From f2a17309dafe7d0bdf00990d156137032d5a21ed Mon Sep 17 00:00:00 2001 From: Rodi Date: Tue, 17 May 2022 22:00:28 +0100 Subject: [PATCH] Add feature to auto-download snaps. Refactor toggle options and story download code. Add option to globally hide chat toggles. --- app/libs/snapmod.jar | Bin 175117 -> 178675 bytes .../java/xyz/rodit/snapmod/CustomResources.kt | 2 + .../rodit/snapmod/features/FeatureContext.kt | 2 + .../rodit/snapmod/features/FeatureManager.kt | 2 + .../features/chatmenu/AutoSaveOption.kt | 20 -------- .../features/chatmenu/ChatMenuModifier.kt | 22 +++++++-- .../chatmenu/ConversationToggleOption.kt | 21 +++++++++ .../snapmod/features/chatmenu/PinOption.kt | 25 ---------- .../features/chatmenu/StealthOption.kt | 20 -------- .../features/saving/AutoDownloadSnaps.kt | 43 ++++++++++++++++++ .../snapmod/features/saving/StoriesSaving.kt | 36 ++------------- .../snapmod/features/saving/StoryHelper.kt | 37 ++++++++++++++- app/src/main/res/values/arrays.xml | 14 ++++++ app/src/main/res/values/strings.xml | 6 +++ app/src/main/res/xml/root_preferences.xml | 14 ++++++ snap.ds | 40 ++++++++++++++++ 16 files changed, 201 insertions(+), 103 deletions(-) delete mode 100644 app/src/main/java/xyz/rodit/snapmod/features/chatmenu/AutoSaveOption.kt create mode 100644 app/src/main/java/xyz/rodit/snapmod/features/chatmenu/ConversationToggleOption.kt delete mode 100644 app/src/main/java/xyz/rodit/snapmod/features/chatmenu/PinOption.kt delete mode 100644 app/src/main/java/xyz/rodit/snapmod/features/chatmenu/StealthOption.kt create mode 100644 app/src/main/java/xyz/rodit/snapmod/features/saving/AutoDownloadSnaps.kt diff --git a/app/libs/snapmod.jar b/app/libs/snapmod.jar index f56527da9aa40230a6ee5f237358e1826177f850..b4eb64c45301b3f58a071e94f397a69cddce15d9 100644 GIT binary patch delta 25842 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 delta 22361 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 q-Z#@Fe@% = HashMap() override fun init() { - registerPlugin(PinOption(context)) - registerPlugin(StealthOption(context)) registerPlugin(PreviewOption(context)) - registerPlugin(AutoSaveOption(context)) + + val pinTextResource = context.appContext.resources.getIdentifier( + PIN_STRING_NAME, + "string", + Shared.SNAPCHAT_PACKAGE + ) + registerConversationToggle("pinning", pinTextResource) { it.pinned } + registerConversationToggle("stealth", menu_option_stealth_mode) { it.stealth } + registerConversationToggle("auto_save", menu_option_auto_save) { it.autoSave } + registerConversationToggle("auto_download", menu_option_auto_download) { it.autoDownload } + } + + private fun registerConversationToggle(name: String, textResource: Int, manager: Manager) { + registerPlugin(ConversationToggleOption(context, name, textResource, manager)) } private fun registerPlugin(plugin: MenuPlugin) { diff --git a/app/src/main/java/xyz/rodit/snapmod/features/chatmenu/ConversationToggleOption.kt b/app/src/main/java/xyz/rodit/snapmod/features/chatmenu/ConversationToggleOption.kt new file mode 100644 index 0000000..ecddcb4 --- /dev/null +++ b/app/src/main/java/xyz/rodit/snapmod/features/chatmenu/ConversationToggleOption.kt @@ -0,0 +1,21 @@ +package xyz.rodit.snapmod.features.chatmenu + +import xyz.rodit.snapmod.features.FeatureContext +import xyz.rodit.snapmod.util.ConversationManager +import xyz.rodit.snapmod.util.getList + +typealias Manager = (FeatureContext) -> ConversationManager + +class ConversationToggleOption( + context: FeatureContext, + name: String, + textResource: Int, + private val manager: Manager +) : ToggleOption(context, name, textResource) { + + override fun shouldCreate() = !context.config.getList("hidden_chat_options").contains(name) + + override fun isToggled(key: String?) = manager(context).isEnabled(key) + + override fun handleEvent(data: String?) = manager(context).toggle(data) +} \ No newline at end of file diff --git a/app/src/main/java/xyz/rodit/snapmod/features/chatmenu/PinOption.kt b/app/src/main/java/xyz/rodit/snapmod/features/chatmenu/PinOption.kt deleted file mode 100644 index dfb38ab..0000000 --- a/app/src/main/java/xyz/rodit/snapmod/features/chatmenu/PinOption.kt +++ /dev/null @@ -1,25 +0,0 @@ -package xyz.rodit.snapmod.features.chatmenu - -import xyz.rodit.snapmod.Shared -import xyz.rodit.snapmod.features.FeatureContext - -const val PIN_STRING_NAME = "action_menu_pin_conversation" - -class PinOption(context: FeatureContext) : ToggleOption( - context, - "pinning", - context.appContext.resources.getIdentifier(PIN_STRING_NAME, "string", Shared.SNAPCHAT_PACKAGE) -) { - - override fun shouldCreate(): Boolean { - return context.config.getBoolean("allow_pin_chats") - } - - override fun handleEvent(key: String?) { - context.pinned.toggle(key) - } - - override fun isToggled(key: String?): Boolean { - return context.pinned.isEnabled(key) - } -} \ No newline at end of file diff --git a/app/src/main/java/xyz/rodit/snapmod/features/chatmenu/StealthOption.kt b/app/src/main/java/xyz/rodit/snapmod/features/chatmenu/StealthOption.kt deleted file mode 100644 index ea469e6..0000000 --- a/app/src/main/java/xyz/rodit/snapmod/features/chatmenu/StealthOption.kt +++ /dev/null @@ -1,20 +0,0 @@ -package xyz.rodit.snapmod.features.chatmenu - -import xyz.rodit.snapmod.CustomResources -import xyz.rodit.snapmod.features.FeatureContext - -class StealthOption(context: FeatureContext) : - ToggleOption(context, "stealth", CustomResources.string.menu_option_stealth_mode) { - - override fun shouldCreate(): Boolean { - return true - } - - override fun handleEvent(key: String?) { - context.stealth.toggle(key) - } - - override fun isToggled(key: String?): Boolean { - return context.stealth.isEnabled(key) - } -} \ No newline at end of file diff --git a/app/src/main/java/xyz/rodit/snapmod/features/saving/AutoDownloadSnaps.kt b/app/src/main/java/xyz/rodit/snapmod/features/saving/AutoDownloadSnaps.kt new file mode 100644 index 0000000..a208288 --- /dev/null +++ b/app/src/main/java/xyz/rodit/snapmod/features/saving/AutoDownloadSnaps.kt @@ -0,0 +1,43 @@ +package xyz.rodit.snapmod.features.saving + +import xyz.rodit.snapmod.features.Feature +import xyz.rodit.snapmod.features.FeatureContext +import xyz.rodit.snapmod.mappings.* +import xyz.rodit.snapmod.util.PathManager +import xyz.rodit.snapmod.util.after +import xyz.rodit.snapmod.util.toUUIDString + +class AutoDownloadSnaps(context: FeatureContext) : Feature(context) { + + private val ignore = hashSetOf() + + override fun performHooks() { + OperaPageViewController.onDisplayStateChanged.after { + val viewController = OperaPageViewController.wrap(it.thisObject) + if (viewController.state.instance != OperaDisplayState.FULLY_DISPLAYED().instance) return@after + + val params = ParamsMap.wrap(viewController.metadata.instance) + val map = params.map + if (!map.containsKey(MessageStoryKeys.getSnapInSavedState().instance)) return@after + + val messageId = map[MessageStoryKeys.getMessageId().instance] as String? + val conversationId = UUID.wrap(map[ConversationStoryKeys.getConversationId().instance]) + if (messageId == null || conversationId.isNull) return@after + + if (!context.config.getBoolean("auto_download_snaps") + && !context.autoDownload.isEnabled(conversationId.toUUIDString()) + ) return@after + + if (ignore.contains(messageId)) return@after + + ignore.add(messageId) + getMediaInfo(context, params) { info -> + downloadOperaMedia( + context, + PathManager.DOWNLOAD_SNAP, + info + ) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/xyz/rodit/snapmod/features/saving/StoriesSaving.kt b/app/src/main/java/xyz/rodit/snapmod/features/saving/StoriesSaving.kt index abc964b..bd1aee0 100644 --- a/app/src/main/java/xyz/rodit/snapmod/features/saving/StoriesSaving.kt +++ b/app/src/main/java/xyz/rodit/snapmod/features/saving/StoriesSaving.kt @@ -2,17 +2,12 @@ package xyz.rodit.snapmod.features.saving import xyz.rodit.snapmod.features.Feature import xyz.rodit.snapmod.features.FeatureContext -import xyz.rodit.snapmod.logging.log import xyz.rodit.snapmod.mappings.* import xyz.rodit.snapmod.util.PathManager import xyz.rodit.snapmod.util.after -import xyz.rodit.snapmod.util.download -import xyz.rodit.xposed.client.http.StreamProvider -import xyz.rodit.xposed.client.http.streams.FileProxyStreamProvider import java.lang.reflect.InvocationHandler import java.lang.reflect.Method import java.lang.reflect.Proxy -import java.net.URL class StoriesSaving(context: FeatureContext) : Feature(context) { @@ -42,36 +37,11 @@ class StoriesSaving(context: FeatureContext) : Feature(context) { if (method.name != ContextClickHandler.invoke.dexName) return null val map = ParamsMap.wrap(args!![0]) - getMediaInfo(context, map, this::downloadStoryMedia) - - return null - } - - private fun downloadStoryMedia(media: StoryMedia?) { - if (media == null || media.info.isNull) return - - val provider: StreamProvider = FileProxyStreamProvider(context.appContext) { - try { - var stream = URL(media.info.uri).openStream() - val enc = media.info.encryption - if (enc.isNotNull) { - stream = enc.decryptStream(stream) - } - - return@FileProxyStreamProvider stream - } catch (e: Exception) { - log.error("Error opening story media stream.", e) - } - return@FileProxyStreamProvider null + getMediaInfo(context, map) { + downloadOperaMedia(context, PathManager.DOWNLOAD_STORY, it) } - context.download( - PathManager.DOWNLOAD_STORY, - mapOf("u" to media.username), - media.extension, - provider, - media.username + "'s Story" - ) + return null } } } \ No newline at end of file diff --git a/app/src/main/java/xyz/rodit/snapmod/features/saving/StoryHelper.kt b/app/src/main/java/xyz/rodit/snapmod/features/saving/StoryHelper.kt index 96cd938..01eeb4b 100644 --- a/app/src/main/java/xyz/rodit/snapmod/features/saving/StoryHelper.kt +++ b/app/src/main/java/xyz/rodit/snapmod/features/saving/StoryHelper.kt @@ -4,8 +4,12 @@ import xyz.rodit.snapmod.createDummyProxy import xyz.rodit.snapmod.features.FeatureContext import xyz.rodit.snapmod.logging.XLog import xyz.rodit.snapmod.mappings.* +import xyz.rodit.snapmod.util.download import xyz.rodit.snapmod.util.toSnapUUID import xyz.rodit.snapmod.util.toUUIDString +import xyz.rodit.xposed.client.http.StreamProvider +import xyz.rodit.xposed.client.http.streams.FileProxyStreamProvider +import java.net.URL private val mLog = XLog("StoryHelper") @@ -14,8 +18,10 @@ typealias UsernameFetcher = (Map<*, *>) -> String? private val usernameFetchers = listOf( { val session = ContextSession.wrap(it[ContextStoryKeys.getContextSession().instance]) - val snapUsername = session.info.username - if (snapUsername.isNotNull) snapUsername.displayString else null + if (session.isNull) null else { + val snapUsername = session.info.username + if (snapUsername.isNotNull) snapUsername.displayString else null + } }, { val storySnap = @@ -24,6 +30,33 @@ private val usernameFetchers = listOf( } ) +fun downloadOperaMedia(context: FeatureContext, type: String, media: StoryMedia?) { + if (media == null || media.info.isNull) return + + val provider: StreamProvider = FileProxyStreamProvider(context.appContext) { + try { + var stream = URL(media.info.uri).openStream() + val enc = media.info.encryption + if (enc.isNotNull) { + stream = enc.decryptStream(stream) + } + + return@FileProxyStreamProvider stream + } catch (e: Exception) { + mLog.error("Error opening story media stream.", e) + } + return@FileProxyStreamProvider null + } + + context.download( + type, + mapOf("u" to media.username), + media.extension, + provider, + media.username + "'s Story" + ) +} + fun getMediaInfo( context: FeatureContext, metadata: ParamsMap, callback: (StoryMedia?) -> Unit ) { diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 8af9032..310adef 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -97,6 +97,20 @@ NOTE + + Pin + Stealth + Auto Save + Auto Download Snaps + + + + pinning + stealth + auto_save + auto_download + + CHAT STICKER diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1786141..7ea8a6c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -146,4 +146,10 @@ Filtered Message Types Notifications will not be shown for filtered message types. + + Hidden Chat Options + Hides extra chat options (if you feel the chat menu is too cluttered, for example). + + Auto-Download Snaps + Automatically downloads snaps when viewed. \ No newline at end of file diff --git a/app/src/main/res/xml/root_preferences.xml b/app/src/main/res/xml/root_preferences.xml index c5643cc..c9e8c63 100644 --- a/app/src/main/res/xml/root_preferences.xml +++ b/app/src/main/res/xml/root_preferences.xml @@ -158,11 +158,25 @@ app:iconSpaceReserved="false" app:defaultValue="@array/auto_save_types_defaults" /> + + + + () { [strict] .string "MESSAGE_ID", bind field messageId next reference; + [strict] + .string "SNAP_IN_SAVED_STATE", bind field snapInSavedState next reference; } } @@ -1770,4 +1773,41 @@ class AesCrypto { InputStream encrypt(InputStream) InputStream decrypt(InputStream) +} + +[certain] +class ConversationStoryKeys { + + [late] !MapKey conversationId; + [late] !MapKey senderId; + + static void $() { + [strict] + .string "CONVERSATION_ID", bind field conversationId next reference; + [strict] + .string "SENDER_ID", bind field senderId next reference; + } +} + +[certain, obfuscated] +enum OperaDisplayState { + + [late] static this .fields { NONE, PREPARING, MINIMALLY_DISPLAYED, FULLY_DISPLAYED, ERROR } +} + +class OperaPageViewController { + + !StoryMetadata metadata; + !OperaDisplayState state; + + void $(...) { + .string "OperaPageViewController"; + } + + void onDisplayStateChanged() { + .field !OperaDisplayState->!FULLY_DISPLAYED; + .field !OperaDisplayState->!MINIMALLY_DISPLAYED; + .string contains "display state"; + .string "Opera:moveNext"; + } } \ No newline at end of file