Пример #1
0
  public void connect(ServerInfo info, final Callback<Boolean> callback, final boolean retry) {
    Preconditions.checkNotNull(info, "info");

    ServerConnectEvent event = new ServerConnectEvent(this, info);
    if (bungee.getPluginManager().callEvent(event).isCancelled()) {
      return;
    }

    final BungeeServerInfo target =
        (BungeeServerInfo) event.getTarget(); // Update in case the event changed target

    if (getServer() != null && Objects.equals(getServer().getInfo(), target)) {
      sendMessage(bungee.getTranslation("already_connected"));
      return;
    }
    if (pendingConnects.contains(target)) {
      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
          public void operationComplete(ChannelFuture future) throws Exception {
            if (callback != null) {
              callback.done(future.isSuccess(), future.cause());
            }

            if (!future.isSuccess()) {
              future.channel().close();
              pendingConnects.remove(target);

              ServerInfo def =
                  ProxyServer.getInstance()
                      .getServers()
                      .get(getPendingConnection().getListener().getFallbackServer());
              if (retry && target != def && (getServer() == null || def != getServer().getInfo())) {
                sendMessage(bungee.getTranslation("fallback_lobby"));
                connect(def, null, false);
              } else {
                if (dimensionChange) {
                  disconnect(
                      bungee.getTranslation("fallback_kick") + future.cause().getClass().getName());
                } else {
                  sendMessage(
                      bungee.getTranslation("fallback_kick") + future.cause().getClass().getName());
                }
              }
            }
          }
        };
    Bootstrap b =
        new Bootstrap()
            .channel(NioSocketChannel.class)
            .group(ch.getHandle().eventLoop())
            .handler(initializer)
            .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000) // TODO: Configurable
            .remoteAddress(target.getAddress());
    // Windows is bugged, multi homed users will just have to live with random connecting IPs
    if (getPendingConnection().getListener().isSetLocalAddress()
        && !PlatformDependent.isWindows()) {
      b.localAddress(getPendingConnection().getListener().getHost().getHostString(), 0);
    }
    b.connect().addListener(listener);
  }
Пример #2
0
  @Override
  public Future<PCEPSession> createClient(
      @Nonnull final InetSocketAddress remoteAddress,
      @Nonnull final long reconnectTime,
      @Nonnull final PCEPSessionListenerFactory listenerFactory,
      @Nonnull final PCEPSessionNegotiatorFactory negotiatorFactory,
      @Nonnull final KeyMapping keys,
      @Nullable final InetSocketAddress localAddress,
      @Nonnull final BigInteger dbVersion) {
    final Bootstrap b = new Bootstrap();
    b.group(this.workerGroup);
    b.localAddress(localAddress);
    setChannelFactory(b, keys);
    b.option(ChannelOption.SO_KEEPALIVE, true);
    b.option(ChannelOption.MAX_MESSAGES_PER_READ, 1);
    final ReconnectStrategyFactory reconnectStrategy =
        reconnectTime == -1
            ? getNeverReconnectStrategyFactory()
            : getTimedReconnectStrategyFactory(reconnectTime);
    final PCCReconnectPromise promise =
        new PCCReconnectPromise(remoteAddress, reconnectStrategy, b);
    final ChannelInitializer<SocketChannel> channelInitializer =
        new ChannelInitializer<SocketChannel>() {
          @Override
          protected void initChannel(final SocketChannel ch) throws Exception {
            ch.pipeline().addLast(PCCDispatcherImpl.this.factory.getDecoders());
            ch.pipeline()
                .addLast(
                    "negotiator",
                    negotiatorFactory.getSessionNegotiator(
                        listenerFactory, ch, promise, new PCCPeerProposal(dbVersion)));
            ch.pipeline().addLast(PCCDispatcherImpl.this.factory.getEncoders());
            ch.pipeline()
                .addLast(
                    new ChannelInboundHandlerAdapter() {
                      @Override
                      public void channelInactive(final ChannelHandlerContext ctx)
                          throws Exception {
                        if (promise.isCancelled()) {
                          return;
                        }

                        if (!promise.isInitialConnectFinished()) {
                          LOG.debug(
                              "Connection to {} was dropped during negotiation, reattempting",
                              remoteAddress);
                          return;
                        }
                        LOG.debug("Reconnecting after connection to {} was dropped", remoteAddress);
                        PCCDispatcherImpl.this.createClient(
                            remoteAddress,
                            reconnectTime,
                            listenerFactory,
                            negotiatorFactory,
                            keys,
                            localAddress,
                            dbVersion);
                      }
                    });
          }
        };
    b.handler(channelInitializer);
    promise.connect();
    return promise;
  }