Add addStickerPack command

This commit is contained in:
AsamK 2023-08-20 22:27:50 +02:00
parent 133e2cc222
commit e867c57af8
14 changed files with 159 additions and 25 deletions

View file

@ -211,6 +211,8 @@ public interface Manager extends Closeable {
*/
StickerPackUrl uploadStickerPack(File path) throws IOException, StickerPackInvalidException;
void installStickerPack(StickerPackUrl url) throws IOException;
List<StickerPack> getStickerPacks();
void requestAllSyncData() throws IOException;

View file

@ -22,7 +22,7 @@ public final class StickerPackUrl {
public static StickerPackUrl fromUri(URI uri) throws InvalidStickerPackLinkException {
final var rawQuery = uri.getRawFragment();
if (isEmpty(rawQuery)) {
throw new RuntimeException("Invalid sticker pack uri");
throw new InvalidStickerPackLinkException("Invalid sticker pack uri");
}
var query = Utils.getQueryMap(rawQuery);

View file

@ -585,23 +585,15 @@ public final class IncomingMessageHandler {
continue;
}
final var stickerPackId = StickerPackId.deserialize(m.getPackId().get());
final var stickerPackKey = m.getPackKey().orElse(null);
final var installed = m.getType().isEmpty()
|| m.getType().get() == StickerPackOperationMessage.Type.INSTALL;
var sticker = account.getStickerStore().getStickerPack(stickerPackId);
if (m.getPackKey().isPresent()) {
if (sticker == null) {
sticker = new StickerPack(-1, stickerPackId, m.getPackKey().get(), installed);
account.getStickerStore().addStickerPack(sticker);
}
if (installed) {
context.getJobExecutor()
.enqueueJob(new RetrieveStickerPackJob(stickerPackId, m.getPackKey().get()));
}
}
final var sticker = context.getStickerHelper()
.addOrUpdateStickerPack(stickerPackId, stickerPackKey, installed);
if (sticker != null && sticker.isInstalled() != installed) {
account.getStickerStore().updateStickerPackInstalled(sticker.packId(), installed);
if (sticker != null && installed) {
context.getJobExecutor().enqueueJob(new RetrieveStickerPackJob(stickerPackId, sticker.packKey()));
}
}
}

View file

@ -186,6 +186,10 @@ public class SendHelper {
public SendMessageResult sendSyncMessage(SignalServiceSyncMessage message) {
var messageSender = dependencies.getMessageSender();
if (!account.isMultiDevice()) {
logger.trace("Not sending sync message because there are no linked devices.");
return SendMessageResult.success(account.getSelfAddress(), List.of(), false, false, 0, Optional.empty());
}
try {
return messageSender.sendSyncMessage(message, context.getUnidentifiedAccessHelper().getAccessForSync());
} catch (UnregisteredUserException e) {

View file

@ -5,6 +5,7 @@ import org.asamk.signal.manager.api.StickerPackId;
import org.asamk.signal.manager.internal.SignalDependencies;
import org.asamk.signal.manager.storage.SignalAccount;
import org.asamk.signal.manager.storage.stickerPacks.JsonStickerPack;
import org.asamk.signal.manager.storage.stickers.StickerPack;
import org.asamk.signal.manager.util.IOUtils;
import org.signal.libsignal.protocol.InvalidMessageException;
import org.slf4j.Logger;
@ -28,15 +29,33 @@ public class StickerHelper {
this.context = context;
}
public StickerPack addOrUpdateStickerPack(
final StickerPackId stickerPackId, final byte[] stickerPackKey, final boolean installed
) {
final var sticker = account.getStickerStore().getStickerPack(stickerPackId);
if (sticker != null) {
if (sticker.isInstalled() != installed) {
account.getStickerStore().updateStickerPackInstalled(sticker.packId(), installed);
}
return sticker;
}
if (stickerPackKey == null) {
return null;
}
final var newSticker = new StickerPack(-1, stickerPackId, stickerPackKey, installed);
account.getStickerStore().addStickerPack(newSticker);
return newSticker;
}
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");
}
try {
retrieveStickerPack(packId, packKey);
} catch (InvalidMessageException | IOException e) {
throw new InvalidStickerException("Failed to retrieve sticker pack");
}
final JsonStickerPack manifest;
try {
@ -48,6 +67,10 @@ public class StickerHelper {
}
public void retrieveStickerPack(StickerPackId packId, byte[] packKey) throws InvalidMessageException, IOException {
if (context.getStickerPackStore().existsStickerPack(packId)) {
logger.debug("Sticker pack {} already downloaded.", Hex.toStringCondensed(packId.serialize()));
return;
}
logger.debug("Retrieving sticker pack {}.", Hex.toStringCondensed(packId.serialize()));
final var messageReceiver = dependencies.getMessageReceiver();
final var manifest = messageReceiver.retrieveStickerManifest(packId.serialize(), packKey);

View file

@ -6,9 +6,11 @@ import org.asamk.signal.manager.api.TrustLevel;
import org.asamk.signal.manager.storage.SignalAccount;
import org.asamk.signal.manager.storage.groups.GroupInfoV1;
import org.asamk.signal.manager.storage.recipients.RecipientAddress;
import org.asamk.signal.manager.storage.stickers.StickerPack;
import org.asamk.signal.manager.util.AttachmentUtils;
import org.asamk.signal.manager.util.IOUtils;
import org.asamk.signal.manager.util.MimeUtils;
import org.jetbrains.annotations.NotNull;
import org.signal.libsignal.protocol.IdentityKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -26,6 +28,7 @@ import org.whispersystems.signalservice.api.messages.multidevice.DeviceGroupsOut
import org.whispersystems.signalservice.api.messages.multidevice.KeysMessage;
import org.whispersystems.signalservice.api.messages.multidevice.RequestMessage;
import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage;
import org.whispersystems.signalservice.api.messages.multidevice.StickerPackOperationMessage;
import org.whispersystems.signalservice.api.messages.multidevice.VerifiedMessage;
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
import org.whispersystems.signalservice.internal.push.SignalServiceProtos;
@ -40,6 +43,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class SyncHelper {
@ -222,6 +226,22 @@ public class SyncHelper {
context.getSendHelper().sendSyncMessage(SignalServiceSyncMessage.forKeys(keysMessage));
}
public void sendStickerOperationsMessage(List<StickerPack> installStickers, List<StickerPack> removeStickers) {
var installStickerMessages = installStickers.stream().map(s -> getStickerPackOperationMessage(s, true));
var removeStickerMessages = removeStickers.stream().map(s -> getStickerPackOperationMessage(s, false));
var stickerMessages = Stream.concat(installStickerMessages, removeStickerMessages).toList();
context.getSendHelper().sendSyncMessage(SignalServiceSyncMessage.forStickerPackOperations(stickerMessages));
}
@NotNull
private static StickerPackOperationMessage getStickerPackOperationMessage(
final StickerPack s, final boolean installed
) {
return new StickerPackOperationMessage(s.packId().serialize(),
s.packKey(),
installed ? StickerPackOperationMessage.Type.INSTALL : StickerPackOperationMessage.Type.REMOVE);
}
public void sendConfigurationMessage() {
final var config = account.getConfigurationStore();
var configurationMessage = new ConfigurationMessage(Optional.ofNullable(config.getReadReceipts()),

View file

@ -72,6 +72,7 @@ import org.asamk.signal.manager.util.AttachmentUtils;
import org.asamk.signal.manager.util.KeyUtils;
import org.asamk.signal.manager.util.MimeUtils;
import org.asamk.signal.manager.util.StickerUtils;
import org.signal.libsignal.protocol.InvalidMessageException;
import org.signal.libsignal.usernames.BaseUsernameException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -891,10 +892,25 @@ public class ManagerImpl implements Manager {
var sticker = new StickerPack(packId, packKey);
account.getStickerStore().addStickerPack(sticker);
context.getSyncHelper().sendStickerOperationsMessage(List.of(sticker), List.of());
return new StickerPackUrl(packId, packKey);
}
@Override
public void installStickerPack(StickerPackUrl url) throws IOException {
final var packId = url.getPackId();
final var packKey = url.getPackKey();
try {
context.getStickerHelper().retrieveStickerPack(packId, packKey);
} catch (InvalidMessageException e) {
throw new IOException(e);
}
final var sticker = context.getStickerHelper().addOrUpdateStickerPack(packId, packKey, true);
context.getSyncHelper().sendStickerOperationsMessage(List.of(sticker), List.of());
}
@Override
public List<org.asamk.signal.manager.api.StickerPack> getStickerPacks() {
final var stickerPackStore = context.getStickerPackStore();

View file

@ -23,10 +23,6 @@ public class RetrieveStickerPackJob implements Job {
@Override
public void run(Context context) {
if (context.getStickerPackStore().existsStickerPack(packId)) {
logger.debug("Sticker pack {} already downloaded.", Hex.toStringCondensed(packId.serialize()));
return;
}
try {
context.getStickerHelper().retrieveStickerPack(packId, packKey);
} catch (IOException e) {

View file

@ -10,6 +10,7 @@ import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;
public class StickerStore {
@ -36,7 +37,7 @@ public class StickerStore {
this.database = database;
}
public Collection<StickerPack> getStickerPacks() {
public List<StickerPack> getStickerPacks() {
final var sql = (
"""
SELECT s._id, s.pack_id, s.pack_key, s.installed