feat: unsaveable messages

- fix(auto_save): prevent saving unsaveable messages
This commit is contained in:
rhunk 2023-12-23 01:08:36 +01:00
parent 699da49743
commit cac0ccffc7
8 changed files with 70 additions and 10 deletions

View File

@ -97,6 +97,14 @@
"whitelist": "Auto save" "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": { "hide_friend_feed": {
"name": "Hide from Friend Feed" "name": "Hide from Friend Feed"
}, },
@ -719,6 +727,7 @@
"friend_feed_menu_buttons": { "friend_feed_menu_buttons": {
"auto_download": "\u2B07\uFE0F Auto Download", "auto_download": "\u2B07\uFE0F Auto Download",
"auto_save": "\uD83D\uDCAC Auto Save Messages", "auto_save": "\uD83D\uDCAC Auto Save Messages",
"unsaveable_messages": "\u2B07\uFE0F Unsaveable Messages",
"stealth": "\uD83D\uDC7B Stealth Mode", "stealth": "\uD83D\uDC7B Stealth Mode",
"mark_snaps_as_seen": "\uD83D\uDC40 Mark Snaps as seen", "mark_snaps_as_seen": "\uD83D\uDC40 Mark Snaps as seen",
"mark_stories_as_seen_locally": "\uD83D\uDC40 Mark Stories as seen locally", "mark_stories_as_seen_locally": "\uD83D\uDC40 Mark Stories as seen locally",

View File

@ -18,8 +18,9 @@ class Rules : ConfigContainer() {
rules[ruleType] = unique(ruleType.key,"whitelist", "blacklist") { rules[ruleType] = unique(ruleType.key,"whitelist", "blacklist") {
customTranslationPath = "rules.properties.${ruleType.key}" customTranslationPath = "rules.properties.${ruleType.key}"
customOptionTranslationPath = "rules.modes" customOptionTranslationPath = "rules.modes"
addNotices(*ruleType.configNotices)
}.apply { }.apply {
set("whitelist") set(ruleType.defaultValue)
} }
} }
} }

View File

@ -1,5 +1,6 @@
package me.rhunk.snapenhance.common.data package me.rhunk.snapenhance.common.data
import me.rhunk.snapenhance.common.config.FeatureNotice
import me.rhunk.snapenhance.common.util.SerializableDataObject import me.rhunk.snapenhance.common.util.SerializableDataObject
@ -29,11 +30,14 @@ enum class SocialScope(
enum class MessagingRuleType( enum class MessagingRuleType(
val key: String, val key: String,
val listMode: Boolean, val listMode: Boolean,
val showInFriendMenu: Boolean = true val showInFriendMenu: Boolean = true,
val defaultValue: String? = "whitelist",
val configNotices: Array<FeatureNotice> = emptyArray()
) { ) {
STEALTH("stealth", true), STEALTH("stealth", true),
AUTO_DOWNLOAD("auto_download", 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), HIDE_FRIEND_FEED("hide_friend_feed", false, showInFriendMenu = false),
E2E_ENCRYPTION("e2e_encryption", false), E2E_ENCRYPTION("e2e_encryption", false),
PIN_CONVERSATION("pin_conversation", false, showInFriendMenu = false); PIN_CONVERSATION("pin_conversation", false, showInFriendMenu = false);

View File

@ -47,7 +47,7 @@ class AutoSave : MessagingRuleFeature("Auto Save", MessagingRuleType.AUTO_SAVE,
} }
fun canSaveMessage(message: Message, headless: Boolean = false): Boolean { 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 (!headless && (context.mainActivity == null || context.isMainActivityPaused)) return false
if (message.messageMetadata!!.savedBy!!.any { uuid -> uuid.toString() == context.database.myUserId }) return false if (message.messageMetadata!!.savedBy!!.any { uuid -> uuid.toString() == context.database.myUserId }) return false

View File

@ -3,8 +3,8 @@ package me.rhunk.snapenhance.core.features.impl.messaging
import me.rhunk.snapenhance.common.data.ContentType import me.rhunk.snapenhance.common.data.ContentType
import me.rhunk.snapenhance.common.util.protobuf.ProtoEditor import me.rhunk.snapenhance.common.util.protobuf.ProtoEditor
import me.rhunk.snapenhance.common.util.protobuf.ProtoReader 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.NativeUnaryCallEvent
import me.rhunk.snapenhance.core.event.events.impl.SendMessageWithContentEvent
import me.rhunk.snapenhance.core.features.Feature import me.rhunk.snapenhance.core.features.Feature
import me.rhunk.snapenhance.core.features.FeatureLoadParams import me.rhunk.snapenhance.core.features.FeatureLoadParams
import me.rhunk.snapenhance.core.messaging.MessageSender import me.rhunk.snapenhance.core.messaging.MessageSender
@ -40,11 +40,8 @@ class SendOverride : Feature("Send Override", loadParams = FeatureLoadParams.INI
} }
//make snaps savable in chat //make snaps savable in chat
protoEditor.edit(4) { protoEditor.edit(4) {
val savableState = firstOrNull(7)?.value ?: return@edit remove(7)
if (savableState == 2L) { addVarInt(7, 3)
remove(7)
addVarInt(7, 3)
}
} }
} }
event.buffer = protoEditor.toByteArray() event.buffer = protoEditor.toByteArray()

View File

@ -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()
}
}
}
}

View File

@ -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.BypassScreenshotDetection
import me.rhunk.snapenhance.core.features.impl.tweaks.CameraTweaks 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.PreventMessageListAutoScroll
import me.rhunk.snapenhance.core.features.impl.tweaks.UnsaveableMessages
import me.rhunk.snapenhance.core.features.impl.ui.* import me.rhunk.snapenhance.core.features.impl.ui.*
import me.rhunk.snapenhance.core.logger.CoreLogger import me.rhunk.snapenhance.core.logger.CoreLogger
import me.rhunk.snapenhance.core.manager.Manager import me.rhunk.snapenhance.core.manager.Manager
@ -80,6 +81,7 @@ class FeatureManager(
AutoSave::class, AutoSave::class,
UITweaks::class, UITweaks::class,
ConfigurationOverride::class, ConfigurationOverride::class,
UnsaveableMessages::class,
SendOverride::class, SendOverride::class,
UnlimitedSnapViewTime::class, UnlimitedSnapViewTime::class,
BypassVideoLengthRestriction::class, BypassVideoLengthRestriction::class,

View File

@ -23,4 +23,6 @@ class MessageMetadata(obj: Any?) : AbstractWrapper(obj){
var reactions by field("mReactions") { var reactions by field("mReactions") {
(it as ArrayList<*>).map { i -> UserIdToReaction(i) }.toMutableList() (it as ArrayList<*>).map { i -> UserIdToReaction(i) }.toMutableList()
} }
@get:JSGetter @set:JSSetter
var isSaveable by field<Boolean>("mIsSaveable")
} }