From 99eef05084f1b92ffdd091f8d1fe581dd51453fd Mon Sep 17 00:00:00 2001 From: AsamK Date: Mon, 3 Jan 2022 17:54:53 +0100 Subject: [PATCH] Retrieve sticker pack before sending if necessary --- graalvm-config-dir/reflect-config.json | 3 +- .../org/asamk/signal/manager/ManagerImpl.java | 4 +- .../asamk/signal/manager/helper/Context.java | 5 ++ .../signal/manager/helper/StickerHelper.java | 84 +++++++++++++++++++ .../manager/jobs/RetrieveStickerPackJob.java | 40 +-------- 5 files changed, 94 insertions(+), 42 deletions(-) create mode 100644 lib/src/main/java/org/asamk/signal/manager/helper/StickerHelper.java diff --git a/graalvm-config-dir/reflect-config.json b/graalvm-config-dir/reflect-config.json index 7adb67ea..68af8ab4 100644 --- a/graalvm-config-dir/reflect-config.json +++ b/graalvm-config-dir/reflect-config.json @@ -772,7 +772,8 @@ {"name":"","parameterTypes":["java.lang.String","java.lang.String","java.lang.String"] }, {"name":"contentType","parameterTypes":[] }, {"name":"emoji","parameterTypes":[] }, - {"name":"file","parameterTypes":[] } + {"name":"file","parameterTypes":[] }, + {"name":"id","parameterTypes":[] } ]} , { diff --git a/lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java b/lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java index b584da44..fbcf1b48 100644 --- a/lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java +++ b/lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java @@ -519,10 +519,10 @@ public class ManagerImpl implements Manager { final var stickerId = sticker.stickerId(); final var stickerPack = context.getAccount().getStickerStore().getStickerPack(packId); - if (stickerPack == null || !context.getStickerPackStore().existsStickerPack(packId)) { + if (stickerPack == null) { throw new InvalidStickerException("Sticker pack not found"); } - final var manifest = context.getStickerPackStore().retrieveManifest(packId); + final var manifest = context.getStickerHelper().getOrRetrieveStickerPack(packId, stickerPack.getPackKey()); if (manifest.stickers().size() <= stickerId) { throw new InvalidStickerException("Sticker id not part of this pack"); } diff --git a/lib/src/main/java/org/asamk/signal/manager/helper/Context.java b/lib/src/main/java/org/asamk/signal/manager/helper/Context.java index f1b7c3c1..3ef0bf16 100644 --- a/lib/src/main/java/org/asamk/signal/manager/helper/Context.java +++ b/lib/src/main/java/org/asamk/signal/manager/helper/Context.java @@ -33,6 +33,7 @@ public class Context { private ReceiveHelper receiveHelper; private RecipientHelper recipientHelper; private SendHelper sendHelper; + private StickerHelper stickerHelper; private StorageHelper storageHelper; private SyncHelper syncHelper; private UnidentifiedAccessHelper unidentifiedAccessHelper; @@ -129,6 +130,10 @@ public class Context { return getOrCreate(() -> sendHelper, () -> sendHelper = new SendHelper(this)); } + public StickerHelper getStickerHelper() { + return getOrCreate(() -> stickerHelper, () -> stickerHelper = new StickerHelper(this)); + } + public StorageHelper getStorageHelper() { return getOrCreate(() -> storageHelper, () -> storageHelper = new StorageHelper(this)); } diff --git a/lib/src/main/java/org/asamk/signal/manager/helper/StickerHelper.java b/lib/src/main/java/org/asamk/signal/manager/helper/StickerHelper.java new file mode 100644 index 00000000..2fdb2593 --- /dev/null +++ b/lib/src/main/java/org/asamk/signal/manager/helper/StickerHelper.java @@ -0,0 +1,84 @@ +package org.asamk.signal.manager.helper; + +import org.asamk.signal.manager.JsonStickerPack; +import org.asamk.signal.manager.SignalDependencies; +import org.asamk.signal.manager.api.InvalidStickerException; +import org.asamk.signal.manager.api.StickerPackId; +import org.asamk.signal.manager.storage.SignalAccount; +import org.asamk.signal.manager.util.IOUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.whispersystems.libsignal.InvalidMessageException; +import org.whispersystems.signalservice.internal.util.Hex; + +import java.io.IOException; +import java.util.HashSet; + +public class StickerHelper { + + private final static Logger logger = LoggerFactory.getLogger(StickerHelper.class); + + private final Context context; + private final SignalAccount account; + private final SignalDependencies dependencies; + + public StickerHelper(final Context context) { + this.account = context.getAccount(); + this.dependencies = context.getDependencies(); + this.context = context; + } + + public JsonStickerPack getOrRetrieveStickerPack( + StickerPackId packId, byte[] packKey + ) throws InvalidStickerException { + if (!context.getStickerPackStore().existsStickerPack(packId)) { + try { + retrieveStickerPack(packId, packKey); + } catch (InvalidMessageException | IOException e) { + throw new InvalidStickerException("Failed to retrieve sticker pack"); + } + } + final JsonStickerPack manifest; + try { + manifest = context.getStickerPackStore().retrieveManifest(packId); + } catch (IOException e) { + throw new InvalidStickerException("Failed to load sticker pack manifest"); + } + return manifest; + } + + public void retrieveStickerPack(StickerPackId packId, byte[] packKey) throws InvalidMessageException, IOException { + logger.debug("Retrieving sticker pack {}.", Hex.toStringCondensed(packId.serialize())); + final var manifest = dependencies.getMessageReceiver().retrieveStickerManifest(packId.serialize(), packKey); + + final var stickerIds = new HashSet(); + if (manifest.getCover().isPresent()) { + stickerIds.add(manifest.getCover().get().getId()); + } + for (var sticker : manifest.getStickers()) { + stickerIds.add(sticker.getId()); + } + + for (var id : stickerIds) { + final var inputStream = dependencies.getMessageReceiver().retrieveSticker(packId.serialize(), packKey, id); + context.getStickerPackStore().storeSticker(packId, id, o -> IOUtils.copyStream(inputStream, o)); + } + + final var jsonManifest = new JsonStickerPack(manifest.getTitle().orNull(), + manifest.getAuthor().orNull(), + manifest.getCover() + .transform(c -> new JsonStickerPack.JsonSticker(c.getId(), + c.getEmoji(), + String.valueOf(c.getId()), + c.getContentType())) + .orNull(), + manifest.getStickers() + .stream() + .map(c -> new JsonStickerPack.JsonSticker(c.getId(), + c.getEmoji(), + String.valueOf(c.getId()), + c.getContentType())) + .toList()); + context.getStickerPackStore().storeManifest(packId, jsonManifest); + } +} diff --git a/lib/src/main/java/org/asamk/signal/manager/jobs/RetrieveStickerPackJob.java b/lib/src/main/java/org/asamk/signal/manager/jobs/RetrieveStickerPackJob.java index f9768004..2d7633b8 100644 --- a/lib/src/main/java/org/asamk/signal/manager/jobs/RetrieveStickerPackJob.java +++ b/lib/src/main/java/org/asamk/signal/manager/jobs/RetrieveStickerPackJob.java @@ -1,16 +1,13 @@ package org.asamk.signal.manager.jobs; -import org.asamk.signal.manager.JsonStickerPack; import org.asamk.signal.manager.api.StickerPackId; import org.asamk.signal.manager.helper.Context; -import org.asamk.signal.manager.util.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.whispersystems.libsignal.InvalidMessageException; import org.whispersystems.signalservice.internal.util.Hex; import java.io.IOException; -import java.util.HashSet; public class RetrieveStickerPackJob implements Job { @@ -30,43 +27,8 @@ public class RetrieveStickerPackJob implements Job { logger.debug("Sticker pack {} already downloaded.", Hex.toStringCondensed(packId.serialize())); return; } - logger.debug("Retrieving sticker pack {}.", Hex.toStringCondensed(packId.serialize())); try { - final var manifest = context.getDependencies() - .getMessageReceiver() - .retrieveStickerManifest(packId.serialize(), packKey); - - final var stickerIds = new HashSet(); - if (manifest.getCover().isPresent()) { - stickerIds.add(manifest.getCover().get().getId()); - } - for (var sticker : manifest.getStickers()) { - stickerIds.add(sticker.getId()); - } - - for (var id : stickerIds) { - final var inputStream = context.getDependencies() - .getMessageReceiver() - .retrieveSticker(packId.serialize(), packKey, id); - context.getStickerPackStore().storeSticker(packId, id, o -> IOUtils.copyStream(inputStream, o)); - } - - final var jsonManifest = new JsonStickerPack(manifest.getTitle().orNull(), - manifest.getAuthor().orNull(), - manifest.getCover() - .transform(c -> new JsonStickerPack.JsonSticker(c.getId(), - c.getEmoji(), - String.valueOf(c.getId()), - c.getContentType())) - .orNull(), - manifest.getStickers() - .stream() - .map(c -> new JsonStickerPack.JsonSticker(c.getId(), - c.getEmoji(), - String.valueOf(c.getId()), - c.getContentType())) - .toList()); - context.getStickerPackStore().storeManifest(packId, jsonManifest); + context.getStickerHelper().retrieveStickerPack(packId, packKey); } catch (IOException e) { logger.warn("Failed to retrieve sticker pack {}: {}", Hex.toStringCondensed(packId.serialize()), -- 2.50.1