commit cac0ccffc7fddc886e8729705b3547f5e8c50df4 parent 699da4974300df5ea23c846469ec7a6f67be5679 Author: rhunk <101876869+rhunk@users.noreply.github.com> Date: Sat, 23 Dec 2023 01:08:36 +0100 feat: unsaveable messages - fix(auto_save): prevent saving unsaveable messages Diffstat:
8 files changed, 71 insertions(+), 10 deletions(-)
diff --git a/common/src/main/assets/lang/en_US.json b/common/src/main/assets/lang/en_US.json @@ -97,6 +97,14 @@ "whitelist": "Auto save" } }, + "unsaveable_messages": { + "name": "Unsaveable Messages", + "description": "Prevents messages from being saved in chat by other people", + "options": { + "blacklist": "Exclude from Unsaveable Messages", + "whitelist": "Unsaveable Messages" + } + }, "hide_friend_feed": { "name": "Hide from Friend Feed" }, @@ -719,6 +727,7 @@ "friend_feed_menu_buttons": { "auto_download": "\u2B07\uFE0F Auto Download", "auto_save": "\uD83D\uDCAC Auto Save Messages", + "unsaveable_messages": "\u2B07\uFE0F Unsaveable Messages", "stealth": "\uD83D\uDC7B Stealth Mode", "mark_snaps_as_seen": "\uD83D\uDC40 Mark Snaps as seen", "mark_stories_as_seen_locally": "\uD83D\uDC40 Mark Stories as seen locally", diff --git a/common/src/main/kotlin/me/rhunk/snapenhance/common/config/impl/Rules.kt b/common/src/main/kotlin/me/rhunk/snapenhance/common/config/impl/Rules.kt @@ -18,8 +18,9 @@ class Rules : ConfigContainer() { rules[ruleType] = unique(ruleType.key,"whitelist", "blacklist") { customTranslationPath = "rules.properties.${ruleType.key}" customOptionTranslationPath = "rules.modes" + addNotices(*ruleType.configNotices) }.apply { - set("whitelist") + set(ruleType.defaultValue) } } } diff --git a/common/src/main/kotlin/me/rhunk/snapenhance/common/data/MessagingCoreObjects.kt b/common/src/main/kotlin/me/rhunk/snapenhance/common/data/MessagingCoreObjects.kt @@ -1,5 +1,6 @@ package me.rhunk.snapenhance.common.data +import me.rhunk.snapenhance.common.config.FeatureNotice import me.rhunk.snapenhance.common.util.SerializableDataObject @@ -29,11 +30,14 @@ enum class SocialScope( enum class MessagingRuleType( val key: String, val listMode: Boolean, - val showInFriendMenu: Boolean = true + val showInFriendMenu: Boolean = true, + val defaultValue: String? = "whitelist", + val configNotices: Array<FeatureNotice> = emptyArray() ) { STEALTH("stealth", true), AUTO_DOWNLOAD("auto_download", true), - AUTO_SAVE("auto_save", true), + AUTO_SAVE("auto_save", true, defaultValue = "blacklist"), + UNSAVEABLE_MESSAGES("unsaveable_messages", true, configNotices = arrayOf(FeatureNotice.REQUIRE_NATIVE_HOOKS), defaultValue = null), HIDE_FRIEND_FEED("hide_friend_feed", false, showInFriendMenu = false), E2E_ENCRYPTION("e2e_encryption", false), PIN_CONVERSATION("pin_conversation", false, showInFriendMenu = false); diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/messaging/AutoSave.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/messaging/AutoSave.kt @@ -47,7 +47,7 @@ class AutoSave : MessagingRuleFeature("Auto Save", MessagingRuleType.AUTO_SAVE, } fun canSaveMessage(message: Message, headless: Boolean = false): Boolean { - if (message.messageState != MessageState.COMMITTED) return false + if (message.messageState != MessageState.COMMITTED || message.messageMetadata?.isSaveable != true) return false if (!headless && (context.mainActivity == null || context.isMainActivityPaused)) return false if (message.messageMetadata!!.savedBy!!.any { uuid -> uuid.toString() == context.database.myUserId }) return false diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/messaging/SendOverride.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/messaging/SendOverride.kt @@ -3,8 +3,8 @@ package me.rhunk.snapenhance.core.features.impl.messaging import me.rhunk.snapenhance.common.data.ContentType import me.rhunk.snapenhance.common.util.protobuf.ProtoEditor import me.rhunk.snapenhance.common.util.protobuf.ProtoReader -import me.rhunk.snapenhance.core.event.events.impl.SendMessageWithContentEvent import me.rhunk.snapenhance.core.event.events.impl.NativeUnaryCallEvent +import me.rhunk.snapenhance.core.event.events.impl.SendMessageWithContentEvent import me.rhunk.snapenhance.core.features.Feature import me.rhunk.snapenhance.core.features.FeatureLoadParams import me.rhunk.snapenhance.core.messaging.MessageSender @@ -40,11 +40,8 @@ class SendOverride : Feature("Send Override", loadParams = FeatureLoadParams.INI } //make snaps savable in chat protoEditor.edit(4) { - val savableState = firstOrNull(7)?.value ?: return@edit - if (savableState == 2L) { - remove(7) - addVarInt(7, 3) - } + remove(7) + addVarInt(7, 3) } } event.buffer = protoEditor.toByteArray() diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/tweaks/UnsaveableMessages.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/tweaks/UnsaveableMessages.kt @@ -0,0 +1,45 @@ +package me.rhunk.snapenhance.core.features.impl.tweaks + +import me.rhunk.snapenhance.common.data.ContentType +import me.rhunk.snapenhance.common.data.MessagingRuleType +import me.rhunk.snapenhance.common.util.protobuf.ProtoEditor +import me.rhunk.snapenhance.common.util.protobuf.ProtoReader +import me.rhunk.snapenhance.core.event.events.impl.NativeUnaryCallEvent +import me.rhunk.snapenhance.core.features.FeatureLoadParams +import me.rhunk.snapenhance.core.features.MessagingRuleFeature +import me.rhunk.snapenhance.core.wrapper.impl.SnapUUID + +class UnsaveableMessages : MessagingRuleFeature( + "Unsaveable Messages", + MessagingRuleType.UNSAVEABLE_MESSAGES, + loadParams = FeatureLoadParams.INIT_SYNC +) { + override fun init() { + if (context.config.rules.getRuleState(MessagingRuleType.UNSAVEABLE_MESSAGES) == null) return + + context.event.subscribe(NativeUnaryCallEvent::class) { event -> + if (event.uri != "/messagingcoreservice.MessagingCoreService/CreateContentMessage") return@subscribe + + val protoReader = ProtoReader(event.buffer) + val conversationIds = mutableListOf<String>() + + protoReader.eachBuffer(3) { + if (contains(2)) { + return@eachBuffer + } + conversationIds.add(SnapUUID.fromBytes(getByteArray(1, 1, 1) ?: return@eachBuffer).toString()) + } + + if (conversationIds.all { canUseRule(it) }) { + event.buffer = ProtoEditor(event.buffer).apply { + edit(4) { + if ((firstOrNull(7)?.value ?: return@edit) == 2L && firstOrNull(2)?.value != ContentType.SNAP.id.toLong()) { + remove(7) + addVarInt(7, 3) + } + } + }.toByteArray() + } + } + } +}+ \ No newline at end of file diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/manager/impl/FeatureManager.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/manager/impl/FeatureManager.kt @@ -21,6 +21,7 @@ import me.rhunk.snapenhance.core.features.impl.spying.StealthMode import me.rhunk.snapenhance.core.features.impl.tweaks.BypassScreenshotDetection import me.rhunk.snapenhance.core.features.impl.tweaks.CameraTweaks import me.rhunk.snapenhance.core.features.impl.tweaks.PreventMessageListAutoScroll +import me.rhunk.snapenhance.core.features.impl.tweaks.UnsaveableMessages import me.rhunk.snapenhance.core.features.impl.ui.* import me.rhunk.snapenhance.core.logger.CoreLogger import me.rhunk.snapenhance.core.manager.Manager @@ -80,6 +81,7 @@ class FeatureManager( AutoSave::class, UITweaks::class, ConfigurationOverride::class, + UnsaveableMessages::class, SendOverride::class, UnlimitedSnapViewTime::class, BypassVideoLengthRestriction::class, diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/wrapper/impl/MessageMetadata.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/wrapper/impl/MessageMetadata.kt @@ -23,4 +23,6 @@ class MessageMetadata(obj: Any?) : AbstractWrapper(obj){ var reactions by field("mReactions") { (it as ArrayList<*>).map { i -> UserIdToReaction(i) }.toMutableList() } + @get:JSGetter @set:JSSetter + var isSaveable by field<Boolean>("mIsSaveable") } \ No newline at end of file