Skip to content

Commit

Permalink
Minor optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
Auties00 committed Jan 16, 2024
1 parent 85e39a8 commit 6f7f719
Show file tree
Hide file tree
Showing 13 changed files with 56 additions and 143 deletions.
4 changes: 2 additions & 2 deletions src/main/java/it/auties/whatsapp/api/Whatsapp.java
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,11 @@ public class Whatsapp {
// This is to make sure that the instances remain in memory only as long as it's needed
private static final Map<UUID, Whatsapp> instances = new ConcurrentHashMap<>();

protected static Optional<Whatsapp> getInstanceByUuid(UUID uuid) {
static Optional<Whatsapp> getInstanceByUuid(UUID uuid) {
return Optional.ofNullable(instances.get(uuid));
}

protected static void removeInstanceByUuid(UUID uuid) {
static void removeInstanceByUuid(UUID uuid) {
instances.remove(uuid);
}

Expand Down
24 changes: 0 additions & 24 deletions src/main/java/it/auties/whatsapp/crypto/Sha1.java

This file was deleted.

4 changes: 2 additions & 2 deletions src/main/java/it/auties/whatsapp/listener/Listener.java
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ default void onNewMessage(MessageInfo info) {
* @param everyone whether this message was deleted by you only for yourself or whether the
* message was permanently removed
*/
default void onMessageDeleted(Whatsapp whatsapp, ChatMessageInfo info, boolean everyone) {
default void onMessageDeleted(Whatsapp whatsapp, MessageInfo info, boolean everyone) {
}

/**
Expand All @@ -343,7 +343,7 @@ default void onMessageDeleted(Whatsapp whatsapp, ChatMessageInfo info, boolean e
* @param everyone whether this message was deleted by you only for yourself or whether the
* message was permanently removed
*/
default void onMessageDeleted(ChatMessageInfo info, boolean everyone) {
default void onMessageDeleted(MessageInfo info, boolean everyone) {
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package it.auties.whatsapp.listener;

import it.auties.whatsapp.model.info.ChatMessageInfo;
import it.auties.whatsapp.model.info.MessageInfo;

public interface OnMessageDeleted extends Listener {
/**
Expand All @@ -11,5 +11,5 @@ public interface OnMessageDeleted extends Listener {
* message was permanently removed
*/
@Override
void onMessageDeleted(ChatMessageInfo info, boolean everyone);
void onMessageDeleted(MessageInfo info, boolean everyone);
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package it.auties.whatsapp.listener;

import it.auties.whatsapp.api.Whatsapp;
import it.auties.whatsapp.model.info.ChatMessageInfo;
import it.auties.whatsapp.model.info.MessageInfo;

public interface OnWhatsappMessageDeleted extends Listener {
/**
Expand All @@ -13,5 +13,5 @@ public interface OnWhatsappMessageDeleted extends Listener {
* message was permanently removed
*/
@Override
void onMessageDeleted(Whatsapp whatsapp, ChatMessageInfo info, boolean everyone);
void onMessageDeleted(Whatsapp whatsapp, MessageInfo info, boolean everyone);
}
12 changes: 9 additions & 3 deletions src/main/java/it/auties/whatsapp/socket/AppStateHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -442,9 +442,15 @@ private void onAction(ActionDataSync mutation, Action action) {
var chat = targetChat.orElseGet(() -> createChat(messageIndex));
updateName(contact, chat, contactAction);
}
case DeleteMessageForMeAction deleteMessageForMeAction -> {
targetChatMessage.ifPresent(message -> targetChat.ifPresent(chat -> chat.removeMessage(message)));
targetNewsletterMessage.ifPresent(message -> targetNewsletter.ifPresent(newsletter -> newsletter.removeMessage(message)));
case DeleteMessageForMeAction ignored -> {
targetChatMessage.ifPresent(message -> {
targetChat.ifPresent(chat -> chat.removeMessage(message));
socketHandler.onMessageDeleted(message, false);
});
targetNewsletterMessage.ifPresent(message -> {
targetNewsletter.ifPresent(newsletter -> newsletter.removeMessage(message));
socketHandler.onMessageDeleted(message, false);
});
}
case MarkChatAsReadAction markAction -> targetChat.ifPresent(chat -> {
var read = markAction.read() ? 0 : -1;
Expand Down
50 changes: 23 additions & 27 deletions src/main/java/it/auties/whatsapp/socket/MessageHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -239,13 +239,12 @@ private AttachmentType getAttachmentType(Jid chatJid, ExtendedMediaMessage<?> me
};
}


private MutableAttachmentProvider<?> attributeMediaMessage(MutableAttachmentProvider<?> mediaMessage, MediaFile upload) {
private void attributeMediaMessage(MutableAttachmentProvider<?> mediaMessage, MediaFile upload) {
if (mediaMessage instanceof ExtendedMediaMessage<?> extendedMediaMessage) {
extendedMediaMessage.setHandle(upload.handle());
}

return mediaMessage.setMediaSha256(upload.fileSha256())
mediaMessage.setMediaSha256(upload.fileSha256())
.setMediaEncryptedSha256(upload.fileEncSha256())
.setMediaKey(upload.mediaKey())
.setMediaUrl(upload.url())
Expand Down Expand Up @@ -686,13 +685,13 @@ public void decode(Node node, JidProvider chatOverride, boolean notify) {

var plainText = node.findNode("plaintext");
if (plainText.isPresent()) {
decodeNewsletterMessage(node, plainText.get(), businessName, chatOverride, notify);
decodeNewsletterMessage(node, plainText.get(), chatOverride, notify);
return;
}

var reaction = node.findNode("reaction");
if (reaction.isPresent()) {
decodeNewsletterReaction(node, reaction.get(), businessName, chatOverride, notify);
decodeNewsletterReaction(node, reaction.get(), chatOverride, notify);
return;
}

Expand Down Expand Up @@ -728,27 +727,27 @@ private Node createMessageNode(MessageSendRequest.Chat request, CipheredMessageR
private String getMediaType(MessageContainer container) {
var content = container.content();
return switch (content) {
case ImageMessage imageMessage -> "image";
case ImageMessage ignored -> "image";
case VideoOrGifMessage videoMessage -> videoMessage.gifPlayback() ? "gif" : "video";
case AudioMessage audioMessage -> audioMessage.voiceMessage() ? "ptt" : "audio";
case ContactMessage contactMessage -> "vcard";
case DocumentMessage documentMessage -> "document";
case ContactsMessage contactsMessage -> "contact_array";
case LiveLocationMessage liveLocationMessage -> "livelocation";
case StickerMessage stickerMessage -> "sticker";
case ListMessage listMessage -> "list";
case ListResponseMessage listResponseMessage -> "list_response";
case ButtonsResponseMessage buttonsResponseMessage -> "buttons_response";
case PaymentOrderMessage paymentOrderMessage -> "order";
case ProductMessage productMessage -> "product";
case NativeFlowResponseMessage nativeFlowResponseMessage -> "native_flow_response";
case ContactMessage ignored -> "vcard";
case DocumentMessage ignored -> "document";
case ContactsMessage ignored -> "contact_array";
case LiveLocationMessage ignored -> "livelocation";
case StickerMessage ignored -> "sticker";
case ListMessage ignored -> "list";
case ListResponseMessage ignored -> "list_response";
case ButtonsResponseMessage ignored -> "buttons_response";
case PaymentOrderMessage ignored -> "order";
case ProductMessage ignored -> "product";
case NativeFlowResponseMessage ignored -> "native_flow_response";
case ButtonsMessage buttonsMessage ->
buttonsMessage.headerType().hasMedia() ? buttonsMessage.headerType().name().toLowerCase() : null;
case null, default -> null;
};
}

private void decodeNewsletterMessage(Node messageNode, Node plainTextNode, String businessName, JidProvider chatOverride, boolean notify) {
private void decodeNewsletterMessage(Node messageNode, Node plainTextNode, JidProvider chatOverride, boolean notify) {
try {
var newsletterJid = messageNode.attributes()
.getOptionalJid("from")
Expand Down Expand Up @@ -816,7 +815,7 @@ private void decodeNewsletterMessage(Node messageNode, Node plainTextNode, Strin
}
}

private void decodeNewsletterReaction(Node messageNode, Node reactionNode, String businessName, JidProvider chatOverride, boolean notify) {
private void decodeNewsletterReaction(Node messageNode, Node reactionNode, JidProvider chatOverride, boolean notify) {
try {
var messageId = messageNode.attributes()
.getRequiredString("id");
Expand Down Expand Up @@ -945,11 +944,11 @@ private void decodeChatMessage(Node infoNode, Node messageNode, String businessN
}
}

private CompletableFuture<Void> sendEncMessageReceipt(Node infoNode, String id, Jid chatJid, Jid senderJid, boolean fromMe) {
private void sendEncMessageReceipt(Node infoNode, String id, Jid chatJid, Jid senderJid, boolean fromMe) {
var participant = fromMe && senderJid == null ? chatJid : senderJid;
var category = infoNode.attributes().getString("category");
var receiptType = getReceiptType(category, fromMe);
return socketHandler.sendMessageAck(chatJid, infoNode)
socketHandler.sendMessageAck(chatJid, infoNode)
.thenComposeAsync(ignored -> socketHandler.sendReceipt(chatJid, participant, List.of(id), receiptType));
}

Expand Down Expand Up @@ -1106,7 +1105,7 @@ private void onHistorySyncNotification(ChatMessageInfo info, ProtocolMessage pro
}

downloadHistorySync(protocolMessage)
.thenAcceptAsync(history -> onHistoryNotification(info, history))
.thenAcceptAsync(this::onHistoryNotification)
.exceptionallyAsync(throwable -> socketHandler.handleFailure(HISTORY_SYNC, throwable))
.thenRunAsync(() -> socketHandler.sendReceipt(info.chatJid(), null, List.of(info.id()), "hist_sync"));
}
Expand Down Expand Up @@ -1139,7 +1138,7 @@ private CompletableFuture<HistorySync> downloadHistorySyncNotification(HistorySy
.thenApplyAsync(result -> HistorySyncSpec.decode(BytesHelper.decompress(result))));
}

private void onHistoryNotification(ChatMessageInfo info, HistorySync history) {
private void onHistoryNotification(HistorySync history) {
handleHistorySync(history);
if (history.progress() == null) {
return;
Expand Down Expand Up @@ -1169,7 +1168,6 @@ private void handleHistorySync(HistorySync history) {
}

private void handleInitialStatus(HistorySync history) {
var store = socketHandler.store();
for (var messageInfo : history.statusV3Messages()) {
socketHandler.store().addStatus(messageInfo);
}
Expand Down Expand Up @@ -1271,7 +1269,6 @@ private void onForcedHistorySyncCompletion() {


private void handleConversations(HistorySync history) {
var store = socketHandler.store();
for (var chat : history.conversations()) {
for (var message : chat.messages()) {
attributeChatMessage(message.messageInfo());
Expand Down Expand Up @@ -1338,7 +1335,7 @@ private void attributeContextSender(ContextInfo contextInfo, Jid senderJid) {
contextInfo.setQuotedMessageSender(contact);
}

protected ChatMessageInfo attributeChatMessage(ChatMessageInfo info) {
protected void attributeChatMessage(ChatMessageInfo info) {
var chat = socketHandler.store().findChatByJid(info.chatJid())
.orElseGet(() -> socketHandler.store().addNewChat(info.chatJid()));
info.setChat(chat);
Expand All @@ -1353,7 +1350,6 @@ protected ChatMessageInfo attributeChatMessage(ChatMessageInfo info) {
.flatMap(ContextualMessage::contextInfo)
.ifPresent(this::attributeContext);
processMessageWithSecret(info);
return info;
}

private void processMessageWithSecret(ChatMessageInfo info) {
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/it/auties/whatsapp/socket/SocketHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -710,7 +710,7 @@ protected void onSetting(Setting setting) {
});
}

protected void onMessageDeleted(ChatMessageInfo message, boolean everyone) {
protected void onMessageDeleted(MessageInfo message, boolean everyone) {
callListenersAsync(listener -> {
listener.onMessageDeleted(whatsapp, message, everyone);
listener.onMessageDeleted(message, everyone);
Expand Down
71 changes: 10 additions & 61 deletions src/main/java/it/auties/whatsapp/socket/SocketRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,9 @@
import static java.util.concurrent.CompletableFuture.delayedExecutor;
import static java.util.concurrent.TimeUnit.SECONDS;

/**
* An abstract model class that represents a request made from the client to the server.
*/
@SuppressWarnings("UnusedReturnValue")
public record SocketRequest(String id, Object body, CompletableFuture<Node> future,
Function<Node, Boolean> filter, Throwable caller) {
/**
* The timeout in seconds before a Request wrapping a Node fails
*/
private static final int TIMEOUT = 60;

/**
* The delayed executor used to cancel futures
*/
private static final Executor EXECUTOR = delayedExecutor(TIMEOUT, SECONDS);

private SocketRequest(String id, Function<Node, Boolean> filter, Object body) {
Expand All @@ -58,39 +47,22 @@ private void cancelTimedFuture() {
future.completeExceptionally(caller);
}

/**
* Constructs a new request with the provided body expecting a newsletters
*/
public static SocketRequest of(Node body, Function<Node, Boolean> filter) {
return new SocketRequest(body.id(), filter, body);
}

/**
* Constructs a new request with the provided body expecting a newsletters
*/
public static SocketRequest of(byte[] body) {
return new SocketRequest(null, null, body);
}

/**
* Sends a request to the WebSocket linked to {@code session}.
*
* @param session the WhatsappWeb's WebSocket session
* @param store the store
*/
public CompletableFuture<Node> sendWithPrologue(SocketSession session, Keys keys, Store store) {
return send(session, keys, store, true, false);
}

/**
* Sends a request to the WebSocket linked to {@code session}.
*
* @param store the store
* @param session the WhatsappWeb's WebSocket session
* @param prologue whether the prologue should be prepended to the request
* @param response whether the request expects a newsletters
* @return this request
*/
public CompletableFuture<Node> send(SocketSession session, Keys keys, Store store) {
return send(session, keys, store, false, true);
}

public CompletableFuture<Node> send(SocketSession session, Keys keys, Store store, boolean prologue, boolean response) {
var ciphered = encryptMessage(keys);
var byteArrayOutputStream = new ByteArrayOutputStream();
Expand All @@ -110,6 +82,12 @@ public CompletableFuture<Node> send(SocketSession session, Keys keys, Store stor
}
}

public CompletableFuture<Void> sendWithNoResponse(SocketSession session, Keys keys, Store store) {
return send(session, keys, store, false, false)
.thenRun(() -> {});
}


private byte[] getPrologueData(Store store) {
return switch (store.clientType()) {
case WEB -> Specification.Whatsapp.WEB_PROLOGUE;
Expand Down Expand Up @@ -155,35 +133,6 @@ private Void onSendError(Throwable throwable) {
return null;
}

/**
* Sends a request to the WebSocket linked to {@code session}.
*
* @param store the store
* @param session the WhatsappWeb's WebSocket session
* @return this request
*/
public CompletableFuture<Node> send(SocketSession session, Keys keys, Store store) {
return send(session, keys, store, false, true);
}

/**
* Sends a request to the WebSocket linked to {@code session}.
*
* @param store the store
* @param session the WhatsappWeb's WebSocket session
* @return this request
*/
public CompletableFuture<Void> sendWithNoResponse(SocketSession session, Keys keys, Store store) {
return send(session, keys, store, false, false)
.thenRunAsync(() -> {
});
}

/**
* Completes this request using {@code newsletters}
*
* @param response the newsletters used to complete {@link SocketRequest#future}
*/
public boolean complete(Node response, boolean exceptionally) {
if (response == null) {
future.complete(null);
Expand Down
Loading

0 comments on commit 6f7f719

Please sign in to comment.