Search in sources :

Example 1 with Listener

use of net.md_5.bungee.api.plugin.Listener in project Geyser by GeyserMC.

the class GeyserBungeeInjector method initializeLocalChannel0.

@Override
@SuppressWarnings("unchecked")
protected void initializeLocalChannel0(GeyserBootstrap bootstrap) throws Exception {
    // TODO - allow Geyser to specify its own listener info properties
    if (proxy.getConfig().getListeners().size() != 1) {
        throw new UnsupportedOperationException("Geyser does not currently support multiple listeners with injection! " + "Please reach out to us on our Discord at https://discord.gg/GeyserMC so we can hear feedback on your setup.");
    }
    ListenerInfo listenerInfo = proxy.getConfig().getListeners().stream().findFirst().orElseThrow(IllegalStateException::new);
    Class<? extends ProxyServer> proxyClass = proxy.getClass();
    // Using the specified EventLoop is required, or else an error will be thrown
    EventLoopGroup bossGroup;
    EventLoopGroup workerGroup;
    try {
        EventLoopGroup eventLoops = (EventLoopGroup) proxyClass.getField("eventLoops").get(proxy);
        // Netty redirects ServerBootstrap#group(EventLoopGroup) to #group(EventLoopGroup, EventLoopGroup) and uses the same event loop for both.
        bossGroup = eventLoops;
        workerGroup = eventLoops;
        bootstrap.getGeyserLogger().debug("BungeeCord event loop style detected.");
    } catch (NoSuchFieldException e) {
        // Waterfall uses two separate event loops
        // https://github.com/PaperMC/Waterfall/blob/fea7ec356dba6c6ac28819ff11be604af6eb484e/BungeeCord-Patches/0022-Use-a-worker-and-a-boss-event-loop-group.patch
        bossGroup = (EventLoopGroup) proxyClass.getField("bossEventLoopGroup").get(proxy);
        workerGroup = (EventLoopGroup) proxyClass.getField("workerEventLoopGroup").get(proxy);
        bootstrap.getGeyserLogger().debug("Waterfall event loop style detected.");
    }
    // Is currently just AttributeKey.valueOf("ListerInfo") but we might as well copy the value itself.
    AttributeKey<ListenerInfo> listener = PipelineUtils.LISTENER;
    listenerInfo = new ListenerInfo(listenerInfo.getSocketAddress(), listenerInfo.getMotd(), listenerInfo.getMaxPlayers(), listenerInfo.getTabListSize(), listenerInfo.getServerPriority(), listenerInfo.isForceDefault(), listenerInfo.getForcedHosts(), listenerInfo.getTabListType(), listenerInfo.isSetLocalAddress(), listenerInfo.isPingPassthrough(), listenerInfo.getQueryPort(), listenerInfo.isQueryEnabled(), // If Geyser is expecting HAProxy, so should the Bungee end
    bootstrap.getGeyserConfig().getRemote().isUseProxyProtocol());
    // The field that stores all listeners in BungeeCord
    // As of https://github.com/ViaVersion/ViaVersion/pull/2698 ViaVersion adds a wrapper to this field to
    // add its connections
    Field listenerField = proxyClass.getDeclaredField("listeners");
    listenerField.setAccessible(true);
    bungeeChannels = (Set<Channel>) listenerField.get(proxy);
    // This method is what initializes the connection in Java Edition, after Netty is all set.
    Method initChannel = ChannelInitializer.class.getDeclaredMethod("initChannel", Channel.class);
    initChannel.setAccessible(true);
    ChannelFuture channelFuture = (new ServerBootstrap().channel(LocalServerChannelWrapper.class).childHandler(new ChannelInitializer<>() {

        @Override
        protected void initChannel(Channel ch) throws Exception {
            if (proxy.getConfig().getServers() == null) {
                // Proxy hasn't finished loading all plugins - it loads the config after all plugins
                // Probably doesn't need to be translatable?
                bootstrap.getGeyserLogger().info("Disconnecting player as Bungee has not finished loading");
                ch.close();
                return;
            }
            if (channelInitializer == null) {
                // Proxy has finished initializing; we can safely grab this variable without fear of plugins modifying it
                // (Older versions of ViaVersion replace this to inject)
                channelInitializer = PipelineUtils.SERVER_CHILD;
            }
            initChannel.invoke(channelInitializer, ch);
        }
    }).childAttr(listener, listenerInfo).group(bossGroup, workerGroup).localAddress(LocalAddress.ANY)).bind().syncUninterruptibly();
    this.localChannel = channelFuture;
    this.bungeeChannels.add(this.localChannel.channel());
    this.serverSocketAddress = channelFuture.channel().localAddress();
    if (!this.eventRegistered) {
        // Register reload listener
        this.proxy.getPluginManager().registerListener(this.plugin, this);
        this.eventRegistered = true;
    }
    // Only affects Waterfall, but there is no sure way to differentiate between a proxy with this patch and a proxy without this patch
    // Patch causing the issue: https://github.com/PaperMC/Waterfall/blob/7e6af4cef64d5d377a6ffd00a534379e6efa94cf/BungeeCord-Patches/0045-Don-t-use-a-bytebuf-for-packet-decoding.patch
    // If native compression is enabled, then this line is tripped up if a heap buffer is sent over in such a situation
    // as a new direct buffer is not created with that patch (HeapByteBufs throw an UnsupportedOperationException here):
    // https://github.com/SpigotMC/BungeeCord/blob/a283aaf724d4c9a815540cd32f3aafaa72df9e05/native/src/main/java/net/md_5/bungee/jni/zlib/NativeZlib.java#L43
    // This issue could be mitigated down the line by preventing Bungee from setting compression
    LocalSession.createDirectByteBufAllocator();
}
Also used : ChannelFuture(io.netty.channel.ChannelFuture) Channel(io.netty.channel.Channel) Method(java.lang.reflect.Method) LocalServerChannelWrapper(org.geysermc.geyser.network.netty.LocalServerChannelWrapper) ServerBootstrap(io.netty.bootstrap.ServerBootstrap) Field(java.lang.reflect.Field) ListenerInfo(net.md_5.bungee.api.config.ListenerInfo) EventLoopGroup(io.netty.channel.EventLoopGroup)

Example 2 with Listener

use of net.md_5.bungee.api.plugin.Listener in project BungeeTabListPlus by CodeCrafter47.

the class RedisPlayerManager method updatePlayers.

private void updatePlayers() {
    Set<UUID> playersOnline;
    try {
        playersOnline = RedisBungee.getApi().getPlayersOnline();
    } catch (Throwable th) {
        if (!redisBungeeAPIError) {
            logger.log(Level.WARNING, "Error using RedisBungee API", th);
            redisBungeeAPIError = true;
        }
        return;
    }
    redisBungeeAPIError = false;
    // fetch names for new players
    Map<UUID, String> uuidToNameMap = new Object2ObjectOpenHashMap<>();
    for (UUID uuid : playersOnline) {
        if (!byUUID.containsKey(uuid) && ProxyServer.getInstance().getPlayer(uuid) == null) {
            try {
                uuidToNameMap.put(uuid, RedisBungee.getApi().getNameFromUuid(uuid));
            } catch (Throwable ex) {
                logger.log(Level.WARNING, "Error while using RedisBungee API", ex);
            }
        }
    }
    redisConnectionSuccessful = true;
    try {
        mainThread.submit(() -> {
            // remove players which have gone offline
            for (Iterator<UUID> iterator = byUUID.keySet().iterator(); iterator.hasNext(); ) {
                UUID uuid = iterator.next();
                if (!playersOnline.contains(uuid) || ProxyServer.getInstance().getPlayer(uuid) != null) {
                    RedisPlayer redisPlayer = byUUID.get(uuid);
                    iterator.remove();
                    listeners.forEach(listener -> listener.onPlayerRemoved(redisPlayer));
                }
            }
            // add new players
            for (UUID uuid : uuidToNameMap.keySet()) {
                if (!byUUID.containsKey(uuid) && ProxyServer.getInstance().getPlayer(uuid) == null) {
                    RedisPlayer redisPlayer = new RedisPlayer(uuid, uuidToNameMap.get(uuid));
                    byUUID.put(uuid, redisPlayer);
                    listeners.forEach(listener -> listener.onPlayerAdded(redisPlayer));
                }
            }
        }).sync();
    } catch (InterruptedException ignored) {
    }
}
Also used : DataCache(de.codecrafter47.data.api.DataCache) Player(de.codecrafter47.taboverlay.config.player.Player) EventExecutor(io.netty.util.concurrent.EventExecutor) java.util(java.util) DataStreamUtils(codecrafter47.bungeetablistplus.common.network.DataStreamUtils) PubSubMessageEvent(com.imaginarycode.minecraft.redisbungee.events.PubSubMessageEvent) Level(java.util.logging.Level) BungeePlayer(codecrafter47.bungeetablistplus.player.BungeePlayer) ProxiedPlayer(net.md_5.bungee.api.connection.ProxiedPlayer) Object2ObjectOpenHashMap(it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap) ByteArrayDataInput(com.google.common.io.ByteArrayDataInput) BungeeData(de.codecrafter47.data.bungee.api.BungeeData) BTLPBungeeDataKeys(codecrafter47.bungeetablistplus.data.BTLPBungeeDataKeys) ByteArrayDataOutput(com.google.common.io.ByteArrayDataOutput) Listener(net.md_5.bungee.api.plugin.Listener) BTLPDataTypes(codecrafter47.bungeetablistplus.data.BTLPDataTypes) RedisPlayer(codecrafter47.bungeetablistplus.player.RedisPlayer) DataKey(de.codecrafter47.data.api.DataKey) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) IOException(java.io.IOException) RedisBungee(com.imaginarycode.minecraft.redisbungee.RedisBungee) ProxyServer(net.md_5.bungee.api.ProxyServer) Logger(java.util.logging.Logger) Sets(com.google.common.collect.Sets) PlayerProvider(de.codecrafter47.taboverlay.config.player.PlayerProvider) TypeAdapterRegistry(codecrafter47.bungeetablistplus.common.network.TypeAdapterRegistry) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) BukkitData(de.codecrafter47.data.bukkit.api.BukkitData) DataKeyRegistry(de.codecrafter47.data.api.DataKeyRegistry) SpongeData(de.codecrafter47.data.sponge.api.SpongeData) ReferenceOpenHashSet(it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet) ByteStreams(com.google.common.io.ByteStreams) MinecraftData(de.codecrafter47.data.minecraft.api.MinecraftData) BTLPDataKeys(codecrafter47.bungeetablistplus.common.BTLPDataKeys) BungeeTabListPlus(codecrafter47.bungeetablistplus.BungeeTabListPlus) EventHandler(net.md_5.bungee.event.EventHandler) Object2ObjectOpenHashMap(it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap) RedisPlayer(codecrafter47.bungeetablistplus.player.RedisPlayer)

Example 3 with Listener

use of net.md_5.bungee.api.plugin.Listener in project SubServers-2 by ME1312.

the class PacketDownloadPlatformInfo method send.

@Override
public ObjectMap<Integer> send(SubDataClient client) {
    ObjectMap<Integer> data = new ObjectMap<Integer>();
    if (tracker != null)
        data.set(0x0000, tracker);
    ObjectMap<String> info = new ObjectMap<String>();
    ObjectMap<String> subservers = new ObjectMap<String>();
    subservers.set("version", plugin.api.getWrapperVersion().toString());
    if (plugin.api.getWrapperBuild() != null)
        subservers.set("build", plugin.api.getWrapperBuild().toString());
    subservers.set("last-reload", plugin.resetDate);
    subservers.set("proxies", plugin.api.getProxies().size());
    subservers.set("hosts", plugin.api.getHosts().size());
    subservers.set("subservers", plugin.api.getSubServers().size());
    info.set("subservers", subservers);
    ObjectMap<String> bungee = new ObjectMap<String>();
    bungee.set("version", plugin.api.getProxyVersion().toString());
    bungee.set("disabled-cmds", plugin.getConfig().getDisabledCommands());
    bungee.set("player-limit", plugin.getConfig().getPlayerLimit());
    bungee.set("servers", plugin.api.getServers().size());
    LinkedList<ObjectMap<String>> listeners = new LinkedList<ObjectMap<String>>();
    for (ListenerInfo next : plugin.getConfig().getListeners()) {
        ObjectMap<String> listener = new ObjectMap<String>();
        listener.set("forced-hosts", next.getForcedHosts());
        listener.set("motd", next.getMotd());
        listener.set("priorities", next.getServerPriority());
        listener.set("player-limit", next.getMaxPlayers());
        listeners.add(listener);
    }
    bungee.set("listeners", listeners);
    info.set("bungee", bungee);
    ObjectMap<String> minecraft = new ObjectMap<String>();
    LinkedList<String> mcversions = new LinkedList<String>();
    for (Version version : plugin.api.getGameVersion()) mcversions.add(version.toString());
    minecraft.set("version", mcversions);
    minecraft.set("players", plugin.api.getRemotePlayers().size());
    info.set("minecraft", minecraft);
    ObjectMap<String> system = new ObjectMap<String>();
    ObjectMap<String> os = new ObjectMap<String>();
    os.set("name", System.getProperty("os.name"));
    os.set("version", System.getProperty("os.version"));
    system.set("os", os);
    ObjectMap<String> java = new ObjectMap<String>();
    java.set("version", System.getProperty("java.version"));
    system.set("java", java);
    info.set("system", system);
    data.set(0x0001, info);
    return data;
}
Also used : ListenerInfo(net.md_5.bungee.api.config.ListenerInfo) ObjectMap(net.ME1312.Galaxi.Library.Map.ObjectMap) Version(net.ME1312.Galaxi.Library.Version.Version) LinkedList(java.util.LinkedList)

Example 4 with Listener

use of net.md_5.bungee.api.plugin.Listener in project BungeeCord by SpigotMC.

the class Configuration method load.

public void load() {
    ConfigurationAdapter adapter = ProxyServer.getInstance().getConfigurationAdapter();
    adapter.load();
    File fav = new File("server-icon.png");
    if (fav.exists()) {
        try {
            favicon = Favicon.create(ImageIO.read(fav));
        } catch (IOException | IllegalArgumentException ex) {
            ProxyServer.getInstance().getLogger().log(Level.WARNING, "Could not load server icon", ex);
        }
    }
    listeners = adapter.getListeners();
    timeout = adapter.getInt("timeout", timeout);
    uuid = adapter.getString("stats", uuid);
    onlineMode = adapter.getBoolean("online_mode", onlineMode);
    logCommands = adapter.getBoolean("log_commands", logCommands);
    logPings = adapter.getBoolean("log_pings", logPings);
    remotePingCache = adapter.getInt("remote_ping_cache", remotePingCache);
    playerLimit = adapter.getInt("player_limit", playerLimit);
    serverConnectTimeout = adapter.getInt("server_connect_timeout", serverConnectTimeout);
    remotePingTimeout = adapter.getInt("remote_ping_timeout", remotePingTimeout);
    throttle = adapter.getInt("connection_throttle", throttle);
    throttleLimit = adapter.getInt("connection_throttle_limit", throttleLimit);
    ipForward = adapter.getBoolean("ip_forward", ipForward);
    compressionThreshold = adapter.getInt("network_compression_threshold", compressionThreshold);
    preventProxyConnections = adapter.getBoolean("prevent_proxy_connections", preventProxyConnections);
    forgeSupport = adapter.getBoolean("forge_support", forgeSupport);
    disabledCommands = new CaseInsensitiveSet((Collection<String>) adapter.getList("disabled_commands", Arrays.asList("disabledcommandhere")));
    Preconditions.checkArgument(listeners != null && !listeners.isEmpty(), "No listeners defined.");
    Map<String, ServerInfo> newServers = adapter.getServers();
    Preconditions.checkArgument(newServers != null && !newServers.isEmpty(), "No servers defined");
    if (servers == null) {
        servers = new CaseInsensitiveMap<>(newServers);
    } else {
        for (ServerInfo oldServer : servers.values()) {
            // Don't allow servers to be removed
            Preconditions.checkArgument(newServers.containsKey(oldServer.getName()), "Server %s removed on reload!", oldServer.getName());
        }
        // Add new servers
        for (Map.Entry<String, ServerInfo> newServer : newServers.entrySet()) {
            if (!servers.containsValue(newServer.getValue())) {
                servers.put(newServer.getKey(), newServer.getValue());
            }
        }
    }
    for (ListenerInfo listener : listeners) {
        for (int i = 0; i < listener.getServerPriority().size(); i++) {
            String server = listener.getServerPriority().get(i);
            Preconditions.checkArgument(servers.containsKey(server), "Server %s (priority %s) is not defined", server, i);
        }
        for (String server : listener.getForcedHosts().values()) {
            if (!servers.containsKey(server)) {
                ProxyServer.getInstance().getLogger().log(Level.WARNING, "Forced host server {0} is not defined", server);
            }
        }
    }
}
Also used : ServerInfo(net.md_5.bungee.api.config.ServerInfo) CaseInsensitiveSet(net.md_5.bungee.util.CaseInsensitiveSet) IOException(java.io.IOException) ListenerInfo(net.md_5.bungee.api.config.ListenerInfo) ConfigurationAdapter(net.md_5.bungee.api.config.ConfigurationAdapter) Collection(java.util.Collection) File(java.io.File) TMap(gnu.trove.map.TMap) Map(java.util.Map) CaseInsensitiveMap(net.md_5.bungee.util.CaseInsensitiveMap)

Example 5 with Listener

use of net.md_5.bungee.api.plugin.Listener in project BungeeCord by SpigotMC.

the class UserConnection method connect.

@Override
public void connect(final ServerConnectRequest request) {
    Preconditions.checkNotNull(request, "request");
    final Callback<ServerConnectRequest.Result> callback = request.getCallback();
    ServerConnectEvent event = new ServerConnectEvent(this, request.getTarget(), request.getReason(), request);
    if (bungee.getPluginManager().callEvent(event).isCancelled()) {
        if (callback != null) {
            callback.done(ServerConnectRequest.Result.EVENT_CANCEL, null);
        }
        if (getServer() == null && !ch.isClosing()) {
            throw new IllegalStateException("Cancelled ServerConnectEvent with no server or disconnect.");
        }
        return;
    }
    // Update in case the event changed target
    final BungeeServerInfo target = (BungeeServerInfo) event.getTarget();
    if (getServer() != null && Objects.equals(getServer().getInfo(), target)) {
        if (callback != null) {
            callback.done(ServerConnectRequest.Result.ALREADY_CONNECTED, null);
        }
        sendMessage(bungee.getTranslation("already_connected"));
        return;
    }
    if (pendingConnects.contains(target)) {
        if (callback != null) {
            callback.done(ServerConnectRequest.Result.ALREADY_CONNECTING, null);
        }
        sendMessage(bungee.getTranslation("already_connecting"));
        return;
    }
    pendingConnects.add(target);
    ChannelInitializer initializer = new ChannelInitializer() {

        @Override
        protected void initChannel(Channel ch) throws Exception {
            PipelineUtils.BASE.initChannel(ch);
            ch.pipeline().addAfter(PipelineUtils.FRAME_DECODER, PipelineUtils.PACKET_DECODER, new MinecraftDecoder(Protocol.HANDSHAKE, false, getPendingConnection().getVersion()));
            ch.pipeline().addAfter(PipelineUtils.FRAME_PREPENDER, PipelineUtils.PACKET_ENCODER, new MinecraftEncoder(Protocol.HANDSHAKE, false, getPendingConnection().getVersion()));
            ch.pipeline().get(HandlerBoss.class).setHandler(new ServerConnector(bungee, UserConnection.this, target));
        }
    };
    ChannelFutureListener listener = new ChannelFutureListener() {

        @Override
        @SuppressWarnings("ThrowableResultIgnored")
        public void operationComplete(ChannelFuture future) throws Exception {
            if (callback != null) {
                callback.done((future.isSuccess()) ? ServerConnectRequest.Result.SUCCESS : ServerConnectRequest.Result.FAIL, future.cause());
            }
            if (!future.isSuccess()) {
                future.channel().close();
                pendingConnects.remove(target);
                ServerInfo def = updateAndGetNextServer(target);
                if (request.isRetry() && def != null && (getServer() == null || def != getServer().getInfo())) {
                    sendMessage(bungee.getTranslation("fallback_lobby"));
                    connect(def, null, true, ServerConnectEvent.Reason.LOBBY_FALLBACK);
                } else if (dimensionChange) {
                    disconnect(bungee.getTranslation("fallback_kick", connectionFailMessage(future.cause())));
                } else {
                    sendMessage(bungee.getTranslation("fallback_kick", connectionFailMessage(future.cause())));
                }
            }
        }
    };
    Bootstrap b = new Bootstrap().channel(PipelineUtils.getChannel(target.getAddress())).group(ch.getHandle().eventLoop()).handler(initializer).option(ChannelOption.CONNECT_TIMEOUT_MILLIS, request.getConnectTimeout()).remoteAddress(target.getAddress());
    // Windows is bugged, multi homed users will just have to live with random connecting IPs
    if (getPendingConnection().getListener().isSetLocalAddress() && !PlatformDependent.isWindows() && getPendingConnection().getListener().getSocketAddress() instanceof InetSocketAddress) {
        b.localAddress(getPendingConnection().getListener().getHost().getHostString(), 0);
    }
    b.connect().addListener(listener);
}
Also used : ChannelFuture(io.netty.channel.ChannelFuture) ServerConnectEvent(net.md_5.bungee.api.event.ServerConnectEvent) ServerInfo(net.md_5.bungee.api.config.ServerInfo) InetSocketAddress(java.net.InetSocketAddress) Channel(io.netty.channel.Channel) ChannelFutureListener(io.netty.channel.ChannelFutureListener) HandlerBoss(net.md_5.bungee.netty.HandlerBoss) MinecraftDecoder(net.md_5.bungee.protocol.MinecraftDecoder) Bootstrap(io.netty.bootstrap.Bootstrap) ChannelInitializer(io.netty.channel.ChannelInitializer) MinecraftEncoder(net.md_5.bungee.protocol.MinecraftEncoder)

Aggregations

ListenerInfo (net.md_5.bungee.api.config.ListenerInfo)9 Player (org.bukkit.entity.Player)7 Listener (net.md_5.bungee.api.plugin.Listener)6 TextComponent (net.md_5.bungee.api.chat.TextComponent)5 EventHandler (net.md_5.bungee.event.EventHandler)5 ChannelFuture (io.netty.channel.ChannelFuture)4 BInventory (com.bencodez.advancedcore.api.inventory.BInventory)3 ClickEvent (com.bencodez.advancedcore.api.inventory.BInventory.ClickEvent)3 BInventoryButton (com.bencodez.advancedcore.api.inventory.BInventoryButton)3 AdvancedCoreUser (com.bencodez.advancedcore.api.user.AdvancedCoreUser)3 BookManager (com.bencodez.advancedcore.api.valuerequest.book.BookManager)3 BookSign (com.bencodez.advancedcore.api.valuerequest.book.BookSign)3 ChannelFutureListener (io.netty.channel.ChannelFutureListener)3 ProxiedPlayer (net.md_5.bungee.api.connection.ProxiedPlayer)3 BungeePlayer (codecrafter47.bungeetablistplus.player.BungeePlayer)2 ValueRequest (com.bencodez.advancedcore.api.valuerequest.ValueRequest)2 PromptManager (com.bencodez.advancedcore.api.valuerequest.prompt.PromptManager)2 PromptReturnString (com.bencodez.advancedcore.api.valuerequest.prompt.PromptReturnString)2 TabView (de.codecrafter47.taboverlay.TabView)2 EventListener (de.codecrafter47.taboverlay.config.platform.EventListener)2