X-Git-Url: https://git.nmode.ca/signal-cli/blobdiff_plain/82cecfff85ef29e627d4238e3237222b492d5248..ae3e5be1241b3ae9d27fff950c3bb54bdcdc32e7:/src/main/java/org/asamk/signal/Manager.java diff --git a/src/main/java/org/asamk/signal/Manager.java b/src/main/java/org/asamk/signal/Manager.java index 1aefc252..77647d27 100644 --- a/src/main/java/org/asamk/signal/Manager.java +++ b/src/main/java/org/asamk/signal/Manager.java @@ -663,34 +663,75 @@ class Manager implements Signal { } } + if (avatarFile != null) { + createPrivateDirectories(avatarsPath); + File aFile = getGroupAvatarFile(g.groupId); + Files.copy(Paths.get(avatarFile), aFile.toPath(), StandardCopyOption.REPLACE_EXISTING); + } + + groupStore.updateGroup(g); + + SignalServiceDataMessage.Builder messageBuilder = getGroupUpdateMessageBuilder(g); + + // Don't send group message to ourself + final List membersSend = new ArrayList<>(g.members); + membersSend.remove(this.username); + sendMessage(messageBuilder, membersSend); + return g.groupId; + } + + private void sendUpdateGroupMessage(byte[] groupId, String recipient) throws IOException, EncapsulatedExceptions { + if (groupId == null) { + return; + } + GroupInfo g = getGroupForSending(groupId); + + if (!g.members.contains(recipient)) { + return; + } + + SignalServiceDataMessage.Builder messageBuilder = getGroupUpdateMessageBuilder(g); + + // Send group message only to the recipient who requested it + final List membersSend = new ArrayList<>(); + membersSend.add(recipient); + sendMessage(messageBuilder, membersSend); + } + + private SignalServiceDataMessage.Builder getGroupUpdateMessageBuilder(GroupInfo g) { SignalServiceGroup.Builder group = SignalServiceGroup.newBuilder(SignalServiceGroup.Type.UPDATE) .withId(g.groupId) .withName(g.name) .withMembers(new ArrayList<>(g.members)); File aFile = getGroupAvatarFile(g.groupId); - if (avatarFile != null) { - createPrivateDirectories(avatarsPath); - Files.copy(Paths.get(avatarFile), aFile.toPath(), StandardCopyOption.REPLACE_EXISTING); - } if (aFile.exists()) { try { group.withAvatar(createAttachment(aFile)); } catch (IOException e) { - throw new AttachmentInvalidException(avatarFile, e); + throw new AttachmentInvalidException(aFile.toString(), e); } } - groupStore.updateGroup(g); + return SignalServiceDataMessage.newBuilder() + .asGroupMessage(group.build()); + } + + private void sendGroupInfoRequest(byte[] groupId, String recipient) throws IOException, EncapsulatedExceptions { + if (groupId == null) { + return; + } + + SignalServiceGroup.Builder group = SignalServiceGroup.newBuilder(SignalServiceGroup.Type.REQUEST_INFO) + .withId(groupId); SignalServiceDataMessage.Builder messageBuilder = SignalServiceDataMessage.newBuilder() .asGroupMessage(group.build()); - // Don't send group message to ourself - final List membersSend = new ArrayList<>(g.members); - membersSend.remove(this.username); + // Send group info request message to the recipient who sent us a message with this groupId + final List membersSend = new ArrayList<>(); + membersSend.add(recipient); sendMessage(messageBuilder, membersSend); - return g.groupId; } @Override @@ -847,10 +888,9 @@ class Manager implements Signal { if (message.getGroupInfo().isPresent()) { SignalServiceGroup groupInfo = message.getGroupInfo().get(); threadId = Base64.encodeBytes(groupInfo.getGroupId()); + GroupInfo group = groupStore.getGroup(groupInfo.getGroupId()); switch (groupInfo.getType()) { case UPDATE: - GroupInfo group; - group = groupStore.getGroup(groupInfo.getGroupId()); if (group == null) { group = new GroupInfo(groupInfo.getGroupId()); } @@ -877,14 +917,37 @@ class Manager implements Signal { groupStore.updateGroup(group); break; case DELIVER: + if (group == null) { + try { + sendGroupInfoRequest(groupInfo.getGroupId(), source); + } catch (IOException | EncapsulatedExceptions e) { + e.printStackTrace(); + } + } break; case QUIT: - group = groupStore.getGroup(groupInfo.getGroupId()); - if (group != null) { + if (group == null) { + try { + sendGroupInfoRequest(groupInfo.getGroupId(), source); + } catch (IOException | EncapsulatedExceptions e) { + e.printStackTrace(); + } + } else { group.members.remove(source); groupStore.updateGroup(group); } break; + case REQUEST_INFO: + if (group != null) { + try { + sendUpdateGroupMessage(groupInfo.getGroupId(), source); + } catch (IOException | EncapsulatedExceptions e) { + e.printStackTrace(); + } catch (NotAGroupMemberException e) { + // We have left this group, so don't send a group update message + } + } + break; } } else { if (isSync) { @@ -1261,6 +1324,7 @@ class Manager implements Signal { if (output != null) { output.close(); } + input.close(); if (!tmpFile.delete()) { System.err.println("Failed to delete temp file: " + tmpFile); } @@ -1308,13 +1372,17 @@ class Manager implements Signal { if (groupsFile.exists() && groupsFile.length() > 0) { FileInputStream contactsFileStream = new FileInputStream(groupsFile); - SignalServiceAttachmentStream attachmentStream = SignalServiceAttachment.newStreamBuilder() - .withStream(contactsFileStream) - .withContentType("application/octet-stream") - .withLength(groupsFile.length()) - .build(); - - sendSyncMessage(SignalServiceSyncMessage.forGroups(attachmentStream)); + try { + SignalServiceAttachmentStream attachmentStream = SignalServiceAttachment.newStreamBuilder() + .withStream(contactsFileStream) + .withContentType("application/octet-stream") + .withLength(groupsFile.length()) + .build(); + + sendSyncMessage(SignalServiceSyncMessage.forGroups(attachmentStream)); + } finally { + contactsFileStream.close(); + } } } finally { groupsFile.delete();