net.dv8tion.jda.internal.utils.IOUtil Java Examples

The following examples show how to use net.dv8tion.jda.internal.utils.IOUtil. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Response.java    From JDA with Apache License 2.0 6 votes vote down vote up
public Response(@Nullable final okhttp3.Response response, final int code, @Nonnull final String message, final long retryAfter, @Nonnull final Set<String> cfRays)
{
    this.rawResponse = response;
    this.code = code;
    this.message = message;
    this.exception = null;
    this.retryAfter = retryAfter;
    this.cfRays = cfRays;

    if (response == null)
    {
        this.body = null;
    }
    else // weird compatibility issue, thinks some final isn't initialized if we return pre-maturely
    try
    {
        this.body = IOUtil.getBody(response);
    }
    catch (final Exception e)
    {
        throw new IllegalStateException("An error occurred while parsing the response for a RestAction", e);
    }
}
 
Example #2
Source File: ZlibDecompressor.java    From JDA with Apache License 2.0 6 votes vote down vote up
private void buffer(byte[] data)
{
    if (flushBuffer == null)
        flushBuffer = ByteBuffer.allocate(data.length * 2);

    //Ensure the capacity can hold the new data, ByteBuffer doesn't grow automatically
    if (flushBuffer.capacity() < data.length + flushBuffer.position())
    {
        //Flip to make it a read buffer
        flushBuffer.flip();
        //Reallocate for the new capacity
        flushBuffer = IOUtil.reallocate(flushBuffer, (flushBuffer.capacity() + data.length) * 2);
    }

    flushBuffer.put(data);
}
 
Example #3
Source File: AudioPacket.java    From JDA with Apache License 2.0 6 votes vote down vote up
public AudioPacket(byte[] rawPacket)
{
    this.rawPacket = rawPacket;

    ByteBuffer buffer = ByteBuffer.wrap(rawPacket);
    this.seq = buffer.getChar(SEQ_INDEX);
    this.timestamp = buffer.getInt(TIMESTAMP_INDEX);
    this.ssrc = buffer.getInt(SSRC_INDEX);
    this.type = buffer.get(PT_INDEX);

    final byte profile = buffer.get(0);
    final byte[] data = buffer.array();
    final boolean hasExtension = (profile & 0x10) != 0; // extension bit is at 000X
    final byte cc = (byte) (profile & 0x0f);            // CSRC count - we ignore this for now
    final int csrcLength = cc * 4;                      // defines count of 4-byte words
    // it seems as if extensions only exist without a csrc list being present
    final short extension = hasExtension ? IOUtil.getShortBigEndian(data, RTP_HEADER_BYTE_LENGTH + csrcLength) : 0;

    int offset = RTP_HEADER_BYTE_LENGTH + csrcLength;
    if (hasExtension && extension == RTP_DISCORD_EXTENSION)
        offset = getPayloadOffset(data, csrcLength);

    this.encodedAudio = ByteBuffer.allocate(data.length - offset);
    this.encodedAudio.put(data, offset, encodedAudio.capacity());
    ((Buffer) this.encodedAudio).flip();
}
 
Example #4
Source File: MessageActionImpl.java    From JDA with Apache License 2.0 6 votes vote down vote up
protected RequestBody asMultipart()
{
    final MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);
    int index = 0;
    for (Map.Entry<String, InputStream> entry : files.entrySet())
    {
        final RequestBody body = IOUtil.createRequestBody(Requester.MEDIA_TYPE_OCTET, entry.getValue());
        builder.addFormDataPart("file" + index++, entry.getKey(), body);
    }
    if (!isEmpty())
        builder.addFormDataPart("payload_json", getJSON().toString());
    // clear remaining resources, they will be closed after being sent
    files.clear();
    ownedResources.clear();
    return builder.build();
}
 
Example #5
Source File: ZlibDecompressor.java    From JDA with Apache License 2.0 5 votes vote down vote up
private boolean isFlush(byte[] data)
{
    if (data.length < 4)
        return false;
    int suffix = IOUtil.getIntBigEndian(data, data.length - 4);
    return suffix == Z_SYNC_FLUSH;
}
 
Example #6
Source File: ShardingSessionConfig.java    From JDA with Apache License 2.0 5 votes vote down vote up
public ShardingSessionConfig(
    @Nullable SessionController sessionController, @Nullable VoiceDispatchInterceptor interceptor,
    @Nullable OkHttpClient httpClient, @Nullable OkHttpClient.Builder httpClientBuilder,
    @Nullable WebSocketFactory webSocketFactory, @Nullable IAudioSendFactory audioSendFactory,
    EnumSet<ConfigFlag> flags, EnumSet<ShardingConfigFlag> shardingFlags,
    int maxReconnectDelay, int largeThreshold)
{
    super(sessionController, httpClient, webSocketFactory, interceptor, flags, maxReconnectDelay, largeThreshold);
    if (httpClient == null)
        this.builder = httpClientBuilder == null ? IOUtil.newHttpClientBuilder() : httpClientBuilder;
    else
        this.builder = null;
    this.audioSendFactory = audioSendFactory;
    this.shardingFlags = shardingFlags;
}
 
Example #7
Source File: AudioWebSocket.java    From JDA with Apache License 2.0 5 votes vote down vote up
protected void startConnection()
{
    if (!reconnecting && socket != null)
        throw new IllegalStateException("Somehow, someway, this AudioWebSocket has already attempted to start a connection!");

    try
    {
        WebSocketFactory socketFactory = getJDA().getWebSocketFactory();
        //noinspection SynchronizationOnLocalVariableOrMethodParameter
        synchronized (socketFactory)
        {
            String host = IOUtil.getHost(wssEndpoint);
            // null if the host is undefined, unlikely but we should handle it
            if (host != null)
                socketFactory.setServerName(host);
            else // practically should never happen
                socketFactory.setServerNames(null);
            socket = socketFactory.createSocket(wssEndpoint);
        }
        socket.setDirectTextMessage(true);
        socket.addListener(this);
        changeStatus(ConnectionStatus.CONNECTING_AWAITING_WEBSOCKET_CONNECT);
        socket.connectAsynchronously();
    }
    catch (IOException e)
    {
        LOG.warn("Encountered IOException while attempting to connect to {}: {}\nClosing connection and attempting to reconnect.",
                        wssEndpoint, e.getMessage());
        this.close(ConnectionStatus.ERROR_WEBSOCKET_UNABLE_TO_CONNECT);
    }
}
 
Example #8
Source File: AudioPacket.java    From JDA with Apache License 2.0 5 votes vote down vote up
private int getPayloadOffset(byte[] data, int csrcLength)
{
    // headerLength defines number of 4-byte words in the extension
    final short headerLength = IOUtil.getShortBigEndian(data, RTP_HEADER_BYTE_LENGTH + 2 + csrcLength);
    int i = RTP_HEADER_BYTE_LENGTH // RTP header = 12 bytes
            + 4                    // header which defines a profile and length each 2-bytes = 4 bytes
            + csrcLength           // length of CSRC list (this seems to be always 0 when an extension exists)
            + headerLength * 4;    // number of 4-byte words in extension = len * 4 bytes

    // strip excess 0 bytes
    while (data[i] == 0)
        i++;
    return i;
}
 
Example #9
Source File: Message.java    From JDA with Apache License 2.0 4 votes vote down vote up
/**
 * Enqueues a request to retrieve the contents of this Attachment.
 * <br><b>The receiver is expected to close the retrieved {@link java.io.InputStream}.</b>
 *
 * <h2>Example</h2>
 * <pre>{@code
 * public void printContents(Message.Attachment attachment)
 * {
 *     attachment.retrieveInputStream().thenAccept(in -> {
 *         StringBuilder builder = new StringBuilder();
 *         byte[] buf = byte[1024];
 *         int count = 0;
 *         while ((count = in.read(buf)) > 0)
 *         {
 *             builder.append(new String(buf, 0, count));
 *         }
 *         in.close();
 *         System.out.println(builder);
 *     }).exceptionally(t -> { // handle failure
 *         t.printStackTrace();
 *         return null;
 *     });
 * }
 * }</pre>
 *
 * @return {@link java.util.concurrent.CompletableFuture} - Type: {@link java.io.InputStream}
 */
@Nonnull
public CompletableFuture<InputStream> retrieveInputStream() // it is expected that the response is closed by the callback!
{
    CompletableFuture<InputStream> future = new CompletableFuture<>();
    Request req = getRequest();
    OkHttpClient httpClient = getJDA().getHttpClient();
    httpClient.newCall(req).enqueue(FunctionalCallback
        .onFailure((call, e) -> future.completeExceptionally(new UncheckedIOException(e)))
        .onSuccess((call, response) -> {
            if (response.isSuccessful())
            {
                InputStream body = IOUtil.getBody(response);
                if (!future.complete(body))
                    IOUtil.silentClose(response);
            }
            else
            {
                future.completeExceptionally(new HttpException(response.code() + ": " + response.message()));
                IOUtil.silentClose(response);
            }
        }).build());
    return future;
}
 
Example #10
Source File: Message.java    From JDA with Apache License 2.0 4 votes vote down vote up
/**
 * Retrieves the image of this attachment and provides an {@link net.dv8tion.jda.api.entities.Icon} equivalent.
 * <br>Useful with {@link net.dv8tion.jda.api.managers.AccountManager#setAvatar(Icon)}.
 * <br>This will download the file using the {@link net.dv8tion.jda.api.JDA#getCallbackPool() callback pool}.
 * Alternatively you can use {@link #retrieveInputStream()} and use a continuation with a different executor.
 *
 * <h2>Example</h2>
 * <pre>{@code
 * public void changeAvatar(Message.Attachment attachment)
 * {
 *     attachment.retrieveAsIcon().thenCompose(icon -> {
 *         SelfUser self = attachment.getJDA().getSelfUser();
 *         AccountManager manager = self.getManager();
 *         return manager.setAvatar(icon).submit();
 *     }).exceptionally(t -> {
 *         t.printStackTrace();
 *         return null;
 *     });
 * }
 * }</pre>
 *
 * @throws java.lang.IllegalStateException
 *         If this is not an image ({@link #isImage()})
 *
 * @return {@link java.util.concurrent.CompletableFuture} - Type: {@link net.dv8tion.jda.api.entities.Icon}
 */
@Nonnull
public CompletableFuture<Icon> retrieveAsIcon()
{
    if (!isImage())
        throw new IllegalStateException("Cannot create an Icon out of this attachment. This is not an image.");
    return retrieveInputStream().thenApplyAsync((stream) ->
    {
        try
        {
            return Icon.from(stream);
        }
        catch (IOException e)
        {
            throw new UncheckedIOException(e);
        }
        finally
        {
            IOUtil.silentClose(stream);
        }
    }, getJDA().getCallbackPool());
}
 
Example #11
Source File: JDABuilder.java    From JDA with Apache License 2.0 4 votes vote down vote up
/**
 * Builds a new {@link net.dv8tion.jda.api.JDA} instance and uses the provided token to start the login process.
 * <br>The login process runs in a different thread, so while this will return immediately, {@link net.dv8tion.jda.api.JDA} has not
 * finished loading, thus many {@link net.dv8tion.jda.api.JDA} methods have the chance to return incorrect information.
 * For example {@link JDA#getGuilds()} might return an empty list or {@link net.dv8tion.jda.api.JDA#getUserById(long)} might return null
 * for arbitrary user IDs.
 *
 * <p>If you wish to be sure that the {@link net.dv8tion.jda.api.JDA} information is correct, please use
 * {@link net.dv8tion.jda.api.JDA#awaitReady() JDA.awaitReady()} or register an
 * {@link net.dv8tion.jda.api.hooks.EventListener EventListener} to listen for the
 * {@link net.dv8tion.jda.api.events.ReadyEvent ReadyEvent}.
 *
 * @throws LoginException
 *         If the provided token is invalid.
 * @throws IllegalArgumentException
 *         If the provided token is empty or null. Or the provided intents/cache configuration is not possible.
 *
 * @return A {@link net.dv8tion.jda.api.JDA} instance that has started the login process. It is unknown as
 *         to whether or not loading has finished when this returns.
 *
 * @see    net.dv8tion.jda.api.JDA#awaitReady()
 */
@Nonnull
public JDA build() throws LoginException
{
    checkIntents();
    OkHttpClient httpClient = this.httpClient;
    if (httpClient == null)
    {
        if (this.httpClientBuilder == null)
            this.httpClientBuilder = IOUtil.newHttpClientBuilder();
        httpClient = this.httpClientBuilder.build();
    }

    WebSocketFactory wsFactory = this.wsFactory == null ? new WebSocketFactory() : this.wsFactory;

    if (controller == null && shardInfo != null)
        controller = new ConcurrentSessionController();

    AuthorizationConfig authConfig = new AuthorizationConfig(token);
    ThreadingConfig threadingConfig = new ThreadingConfig();
    threadingConfig.setCallbackPool(callbackPool, shutdownCallbackPool);
    threadingConfig.setGatewayPool(mainWsPool, shutdownMainWsPool);
    threadingConfig.setRateLimitPool(rateLimitPool, shutdownRateLimitPool);
    threadingConfig.setEventPool(eventPool, shutdownEventPool);
    SessionConfig sessionConfig = new SessionConfig(controller, httpClient, wsFactory, voiceDispatchInterceptor, flags, maxReconnectDelay, largeThreshold);
    MetaConfig metaConfig = new MetaConfig(maxBufferSize, contextMap, cacheFlags, flags);

    JDAImpl jda = new JDAImpl(authConfig, sessionConfig, threadingConfig, metaConfig);
    jda.setMemberCachePolicy(memberCachePolicy);
    // We can only do member chunking with the GUILD_MEMBERS intent
    if ((intents & GatewayIntent.GUILD_MEMBERS.getRawValue()) == 0)
        jda.setChunkingFilter(ChunkingFilter.NONE);
    else
        jda.setChunkingFilter(chunkingFilter);

    if (eventManager != null)
        jda.setEventManager(eventManager);

    if (audioSendFactory != null)
        jda.setAudioSendFactory(audioSendFactory);

    listeners.forEach(jda::addEventListener);
    jda.setStatus(JDA.Status.INITIALIZED);  //This is already set by JDA internally, but this is to make sure the listeners catch it.

    // Set the presence information before connecting to have the correct information ready when sending IDENTIFY
    ((PresenceImpl) jda.getPresence())
            .setCacheActivity(activity)
            .setCacheIdle(idle)
            .setCacheStatus(status);
    jda.login(shardInfo, compression, true, intents);
    return jda;
}
 
Example #12
Source File: AudioWebSocket.java    From JDA with Apache License 2.0 4 votes vote down vote up
private InetSocketAddress handleUdpDiscovery(InetSocketAddress address, int ssrc)
{
    //We will now send a packet to discord to punch a port hole in the NAT wall.
    //This is called UDP hole punching.
    try
    {
        //First close existing socket from possible previous attempts
        if (audioConnection.udpSocket != null)
            audioConnection.udpSocket.close();
        //Create new UDP socket for communication
        audioConnection.udpSocket = new DatagramSocket();

        //Create a byte array of length 70 containing our ssrc.
        ByteBuffer buffer = ByteBuffer.allocate(70);    //70 taken from documentation
        buffer.putShort((short) 1);                     // 1 = send (receive will be 2)
        buffer.putShort((short) 70);                    // length = 70 bytes (required)
        buffer.putInt(ssrc);                            // Put the ssrc that we were given into the packet to send back to discord.
        // rest of the bytes are used only in the response (address/port)

        //Construct our packet to be sent loaded with the byte buffer we store the ssrc in.
        DatagramPacket discoveryPacket = new DatagramPacket(buffer.array(), buffer.array().length, address);
        audioConnection.udpSocket.send(discoveryPacket);

        //Discord responds to our packet, returning a packet containing our external ip and the port we connected through.
        DatagramPacket receivedPacket = new DatagramPacket(new byte[70], 70);   //Give a buffer the same size as the one we sent.
        audioConnection.udpSocket.setSoTimeout(1000);
        audioConnection.udpSocket.receive(receivedPacket);

        //The byte array returned by discord containing our external ip and the port that we used
        //to connect to discord with.
        byte[] received = receivedPacket.getData();

        //Example string:"   121.83.253.66                                                   ��"
        //You'll notice that there are 4 leading nulls and a large amount of nulls between the the ip and
        // the last 2 bytes. Not sure why these exist.  The last 2 bytes are the port. More info below.

        //Take bytes between SSRC and PORT and put them into a string
        // null bytes at the beginning are skipped and the rest are appended to the end of the string
        String ourIP = new String(received, 4, received.length - 6);
        // Removes the extra nulls attached to the end of the IP string
        ourIP = ourIP.trim();

        //The port exists as the last 2 bytes in the packet data, and is encoded as an UNSIGNED short.
        //Furthermore, it is stored in Little Endian instead of normal Big Endian.
        //We will first need to convert the byte order from Little Endian to Big Endian (reverse the order)
        //Then we will need to deal with the fact that the bytes represent an unsigned short.
        //Java cannot deal with unsigned types, so we will have to promote the short to a higher type.

        //Get our port which is stored as little endian at the end of the packet
        // We AND it with 0xFFFF to ensure that it isn't sign extended
        int ourPort = (int) IOUtil.getShortBigEndian(received, received.length - 2) & 0xFFFF;
        this.address = address;
        return new InetSocketAddress(ourIP, ourPort);
    }
    catch (IOException e)
    {
        // We either timed out or the socket could not be created (firewall?)
        return null;
    }
}
 
Example #13
Source File: AudioConnection.java    From JDA with Apache License 2.0 4 votes vote down vote up
private void loadNextNonce(long nonce)
{
    IOUtil.setIntBigEndian(nonceBuffer, 0, (int) nonce);
}
 
Example #14
Source File: WebSocketClient.java    From JDA with Apache License 2.0 4 votes vote down vote up
protected synchronized void connect()
{
    if (api.getStatus() != JDA.Status.ATTEMPTING_TO_RECONNECT)
        api.setStatus(JDA.Status.CONNECTING_TO_WEBSOCKET);
    if (shutdown)
        throw new RejectedExecutionException("JDA is shutdown!");
    initiating = true;

    String url = api.getGatewayUrl() + "?encoding=json&v=" + JDAInfo.DISCORD_GATEWAY_VERSION;
    if (compression != Compression.NONE)
    {
        url += "&compress=" + compression.getKey();
        switch (compression)
        {
            case ZLIB:
                if (decompressor == null || decompressor.getType() != Compression.ZLIB)
                    decompressor = new ZlibDecompressor(api.getMaxBufferSize());
                break;
            default:
                throw new IllegalStateException("Unknown compression");
        }
    }

    try
    {
        WebSocketFactory socketFactory = api.getWebSocketFactory();
        //noinspection SynchronizationOnLocalVariableOrMethodParameter
        synchronized (socketFactory)
        {
            String host = IOUtil.getHost(url);
            // null if the host is undefined, unlikely but we should handle it
            if (host != null)
                socketFactory.setServerName(host);
            else // practically should never happen
                socketFactory.setServerNames(null);
            socket = socketFactory.createSocket(url);
        }
        socket.setDirectTextMessage(true);
        socket.addHeader("Accept-Encoding", "gzip")
              .addListener(this)
              .connect();
    }
    catch (IOException | WebSocketException e)
    {
        api.resetGatewayUrl();
        //Completely fail here. We couldn't make the connection.
        throw new IllegalStateException(e);
    }
}
 
Example #15
Source File: Icon.java    From JDA with Apache License 2.0 3 votes vote down vote up
/**
 * Creates an {@link Icon Icon} with the specified {@link java.io.File File}.
 * <br>We here read the specified File and forward the retrieved byte data to {@link #from(byte[], IconType)}.
 *
 * @param  file
 *         An existing, not-null file.
 * @param  type
 *         The type of image
 *
 * @throws IllegalArgumentException
 *         if the provided file is either null or does not exist
 * @throws IOException
 *         if there is a problem while reading the file.
 *
 * @return An Icon instance representing the specified File
 */
@Nonnull
public static Icon from(@Nonnull File file, @Nonnull IconType type) throws IOException
{
    Checks.notNull(file, "Provided File");
    Checks.notNull(type, "IconType");
    Checks.check(file.exists(), "Provided file does not exist!");

    return from(IOUtil.readFully(file), type);
}
 
Example #16
Source File: Icon.java    From JDA with Apache License 2.0 3 votes vote down vote up
/**
 * Creates an {@link Icon Icon} with the specified {@link java.io.InputStream InputStream}.
 * <br>We here read the specified InputStream and forward the retrieved byte data to {@link #from(byte[], IconType)}.
 *
 * @param  stream
 *         A not-null InputStream.
 * @param  type
 *         The type of image
 *
 * @throws IllegalArgumentException
 *         if the provided stream is null
 * @throws IOException
 *         If the first byte cannot be read for any reason other than the end of the file,
 *         if the input stream has been closed, or if some other I/O error occurs.
 *
 * @return An Icon instance representing the specified InputStream
 */
@Nonnull
public static Icon from(@Nonnull InputStream stream, @Nonnull IconType type) throws IOException
{
    Checks.notNull(stream, "InputStream");
    Checks.notNull(type, "IconType");

    return from(IOUtil.readFully(stream), type);
}