All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.robertograham.fortnite2.xmpp.implementation.DefaultChatResource Maven / Gradle / Ivy

package io.github.robertograham.fortnite2.xmpp.implementation;

import io.github.robertograham.fortnite2.xmpp.domain.enumeration.Status;
import io.github.robertograham.fortnite2.xmpp.listener.OnChatMessageReceivedListener;
import io.github.robertograham.fortnite2.xmpp.resource.ChatResource;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.chat2.ChatManager;
import org.jivesoftware.smack.chat2.IncomingChatMessageListener;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
import org.jxmpp.jid.impl.JidCreate;
import org.jxmpp.jid.parts.Localpart;

import java.io.IOException;
import java.util.Objects;
import java.util.Set;

final class DefaultChatResource implements ChatResource, AutoCloseable {

    private static final Set AVAILABLE_PRESENCE_STATUSES = Set.of(Status.ONLINE, Status.AWAY);
    private final ChatManager chatManager;
    private final OnChatMessageReceivedListener onChatMessageReceivedListener;
    private final XMPPTCPConnection prodServiceXmppTcpConnection;
    private final IncomingChatMessageListener incomingChatMessageListener;

    private DefaultChatResource(final OnChatMessageReceivedListener onChatMessageReceivedListener,
                                final XMPPTCPConnection prodServiceXmppTcpConnection) {
        this.onChatMessageReceivedListener = onChatMessageReceivedListener;
        this.prodServiceXmppTcpConnection = prodServiceXmppTcpConnection;
        chatManager = ChatManager.getInstanceFor(this.prodServiceXmppTcpConnection);
        incomingChatMessageListener = createIncomingChatMessageListener();
        chatManager.addIncomingListener(incomingChatMessageListener);
    }

    static DefaultChatResource newInstance(final OnChatMessageReceivedListener onChatMessageReceivedListener,
                                           final XMPPTCPConnection prodServiceXmppTcpConnection) {
        return new DefaultChatResource(
            onChatMessageReceivedListener,
            prodServiceXmppTcpConnection
        );
    }

    private IncomingChatMessageListener createIncomingChatMessageListener() {
        return (entityBareJid, message, chat) -> {
            if (Message.Type.chat == message.getType())
                onChatMessageReceivedListener.onChatMessageReceived(
                    entityBareJid.getLocalpart().asUnescapedString(),
                    message.getBody()
                );
        };
    }

    @Override
    public void sendMessageToAccountId(final String accountId, final String messageBody) throws IOException {
        Objects.requireNonNull(accountId, "accountId cannot be null");
        Objects.requireNonNull(messageBody, "messageBody cannot be null");
        try {
            chatManager.chatWith(JidCreate.entityBareFrom(
                Localpart.fromOrThrowUnchecked(accountId),
                prodServiceXmppTcpConnection.getXMPPServiceDomain()
            ))
                .send(messageBody);
        } catch (final SmackException.NotConnectedException | InterruptedException exception) {
            throw new IOException("Failed to send message", exception);
        }
    }

    @Override
    public void updateStatus(final Status status) throws IOException {
        Objects.requireNonNull(status, "status cannot be null");
        final var presence = createPresence(status);
        try {
            prodServiceXmppTcpConnection.sendStanza(presence);
        } catch (final SmackException.NotConnectedException | InterruptedException exception) {
            throw new IOException("Failed to update status", exception);
        }
    }

    private Presence createPresence(final Status status) {
        final var presenceType = AVAILABLE_PRESENCE_STATUSES.contains(status) ?
            Presence.Type.available
            : Presence.Type.unavailable;
        final var presence = new Presence(presenceType);
        if (Status.AWAY == status)
            presence.setMode(Presence.Mode.away);
        return presence;
    }

    @Override
    public void close() {
        chatManager.removeIncomingListener(incomingChatMessageListener);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy