refactor: mapping wrapper

- rename members
This commit is contained in:
rhunk
2023-08-07 00:38:20 +02:00
parent 289afce4a5
commit 3fc6030a23
13 changed files with 138 additions and 98 deletions

View File

@ -28,7 +28,7 @@ class RemoteSideContext(
val config = ModConfig() val config = ModConfig()
val translation = LocaleWrapper() val translation = LocaleWrapper()
val mappings = MappingsWrapper(androidContext) val mappings = MappingsWrapper()
val downloadTaskManager = DownloadTaskManager() val downloadTaskManager = DownloadTaskManager()
init { init {
@ -38,7 +38,7 @@ class RemoteSideContext(
translation.loadFromContext(androidContext) translation.loadFromContext(androidContext)
mappings.apply { mappings.apply {
loadFromContext(androidContext) loadFromContext(androidContext)
init() init(androidContext)
} }
downloadTaskManager.init(androidContext) downloadTaskManager.init(androidContext)
}.onFailure { }.onFailure {

View File

@ -13,6 +13,7 @@ import com.google.gson.GsonBuilder
import kotlinx.coroutines.asCoroutineDispatcher import kotlinx.coroutines.asCoroutineDispatcher
import me.rhunk.snapenhance.bridge.BridgeClient import me.rhunk.snapenhance.bridge.BridgeClient
import me.rhunk.snapenhance.bridge.wrapper.LocaleWrapper import me.rhunk.snapenhance.bridge.wrapper.LocaleWrapper
import me.rhunk.snapenhance.bridge.wrapper.MappingsWrapper
import me.rhunk.snapenhance.core.config.ModConfig import me.rhunk.snapenhance.core.config.ModConfig
import me.rhunk.snapenhance.core.eventbus.EventBus import me.rhunk.snapenhance.core.eventbus.EventBus
import me.rhunk.snapenhance.data.MessageSender import me.rhunk.snapenhance.data.MessageSender
@ -20,7 +21,6 @@ import me.rhunk.snapenhance.database.DatabaseAccess
import me.rhunk.snapenhance.features.Feature import me.rhunk.snapenhance.features.Feature
import me.rhunk.snapenhance.manager.impl.ActionManager import me.rhunk.snapenhance.manager.impl.ActionManager
import me.rhunk.snapenhance.manager.impl.FeatureManager import me.rhunk.snapenhance.manager.impl.FeatureManager
import me.rhunk.snapenhance.manager.impl.MappingManager
import me.rhunk.snapenhance.util.download.DownloadServer import me.rhunk.snapenhance.util.download.DownloadServer
import java.util.concurrent.ExecutorService import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors import java.util.concurrent.Executors
@ -47,7 +47,7 @@ class ModContext {
val translation = LocaleWrapper() val translation = LocaleWrapper()
val features = FeatureManager(this) val features = FeatureManager(this)
val mappings = MappingManager(this) val mappings = MappingsWrapper()
val actionManager = ActionManager(this) val actionManager = ActionManager(this)
val database = DatabaseAccess(this) val database = DatabaseAccess(this)
val downloadServer = DownloadServer() val downloadServer = DownloadServer()

View File

@ -66,7 +66,7 @@ class SnapEnhance {
if (!activity.packageName.equals(Constants.SNAPCHAT_PACKAGE_NAME)) return@hook if (!activity.packageName.equals(Constants.SNAPCHAT_PACKAGE_NAME)) return@hook
val isMainActivityNotNull = appContext.mainActivity != null val isMainActivityNotNull = appContext.mainActivity != null
appContext.mainActivity = activity appContext.mainActivity = activity
if (isMainActivityNotNull || !appContext.mappings.areMappingsLoaded) return@hook if (isMainActivityNotNull || !appContext.mappings.isMappingsLoaded()) return@hook
onActivityCreate() onActivityCreate()
} }
@ -95,13 +95,14 @@ class SnapEnhance {
reloadConfig() reloadConfig()
withContext(appContext.coroutineDispatcher) { withContext(appContext.coroutineDispatcher) {
translation.userLocale = getConfigLocale() translation.userLocale = getConfigLocale()
translation.loadFromBridge(appContext.bridgeClient) translation.loadFromBridge(bridgeClient)
} }
mappings.init() mappings.loadFromBridge(bridgeClient)
mappings.init(androidContext)
eventDispatcher.init() eventDispatcher.init()
//if mappings aren't loaded, we can't initialize features //if mappings aren't loaded, we can't initialize features
if (!mappings.areMappingsLoaded) return if (!mappings.isMappingsLoaded()) return
features.init() features.init()
} }
}.also { time -> }.also { time ->

View File

@ -11,6 +11,7 @@ import me.rhunk.snapenhance.bridge.types.BridgeFileType
import me.rhunk.snapmapper.Mapper import me.rhunk.snapmapper.Mapper
import me.rhunk.snapmapper.impl.BCryptClassMapper import me.rhunk.snapmapper.impl.BCryptClassMapper
import me.rhunk.snapmapper.impl.CallbackMapper import me.rhunk.snapmapper.impl.CallbackMapper
import me.rhunk.snapmapper.impl.CompositeConfigurationProviderMapper
import me.rhunk.snapmapper.impl.DefaultMediaItemMapper import me.rhunk.snapmapper.impl.DefaultMediaItemMapper
import me.rhunk.snapmapper.impl.EnumMapper import me.rhunk.snapmapper.impl.EnumMapper
import me.rhunk.snapmapper.impl.FriendsFeedEventDispatcherMapper import me.rhunk.snapmapper.impl.FriendsFeedEventDispatcherMapper
@ -19,13 +20,12 @@ import me.rhunk.snapmapper.impl.OperaPageViewControllerMapper
import me.rhunk.snapmapper.impl.PlatformAnalyticsCreatorMapper import me.rhunk.snapmapper.impl.PlatformAnalyticsCreatorMapper
import me.rhunk.snapmapper.impl.PlusSubscriptionMapper import me.rhunk.snapmapper.impl.PlusSubscriptionMapper
import me.rhunk.snapmapper.impl.ScCameraSettingsMapper import me.rhunk.snapmapper.impl.ScCameraSettingsMapper
import me.rhunk.snapmapper.impl.ScoreUpdateMapper
import me.rhunk.snapmapper.impl.StoryBoostStateMapper import me.rhunk.snapmapper.impl.StoryBoostStateMapper
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
import kotlin.system.measureTimeMillis import kotlin.system.measureTimeMillis
class MappingsWrapper( class MappingsWrapper : FileLoaderWrapper(BridgeFileType.MAPPINGS, "{}".toByteArray(Charsets.UTF_8)) {
private val context: Context,
) : FileLoaderWrapper(BridgeFileType.MAPPINGS, "{}".toByteArray(Charsets.UTF_8)) {
companion object { companion object {
private val gson = GsonBuilder().setPrettyPrinting().create() private val gson = GsonBuilder().setPrettyPrinting().create()
private val mappers = arrayOf( private val mappers = arrayOf(
@ -39,14 +39,19 @@ class MappingsWrapper(
PlusSubscriptionMapper::class, PlusSubscriptionMapper::class,
ScCameraSettingsMapper::class, ScCameraSettingsMapper::class,
StoryBoostStateMapper::class, StoryBoostStateMapper::class,
FriendsFeedEventDispatcherMapper::class FriendsFeedEventDispatcherMapper::class,
CompositeConfigurationProviderMapper::class,
ScoreUpdateMapper::class
) )
} }
private lateinit var context: Context
private val mappings = ConcurrentHashMap<String, Any>() private val mappings = ConcurrentHashMap<String, Any>()
private var snapBuildNumber: Long = 0 private var snapBuildNumber: Long = 0
fun init() { fun init(context: Context) {
this.context = context
snapBuildNumber = getSnapchatVersionCode() snapBuildNumber = getSnapchatVersionCode()
if (isFileExists()) { if (isFileExists()) {
@ -56,6 +61,8 @@ class MappingsWrapper(
Logger.error("Failed to load cached mappings", it) Logger.error("Failed to load cached mappings", it)
delete() delete()
} }
} else {
Logger.debug("Mappings file does not exist")
} }
} }

View File

@ -4,7 +4,6 @@ class SnapClassCache (
private val classLoader: ClassLoader private val classLoader: ClassLoader
) { ) {
val snapUUID by lazy { findClass("com.snapchat.client.messaging.UUID") } val snapUUID by lazy { findClass("com.snapchat.client.messaging.UUID") }
val composerLocalSubscriptionStore by lazy { findClass("com.snap.plus.lib.common.ComposerLocalSubscriptionStore") }
val snapManager by lazy { findClass("com.snapchat.client.messaging.SnapManager\$CppProxy") } val snapManager by lazy { findClass("com.snapchat.client.messaging.SnapManager\$CppProxy") }
val conversationManager by lazy { findClass("com.snapchat.client.messaging.ConversationManager\$CppProxy") } val conversationManager by lazy { findClass("com.snapchat.client.messaging.ConversationManager\$CppProxy") }
val presenceSession by lazy { findClass("com.snapchat.talkcorev3.PresenceSession\$CppProxy") } val presenceSession by lazy { findClass("com.snapchat.talkcorev3.PresenceSession\$CppProxy") }

View File

@ -5,39 +5,45 @@ import android.database.Cursor
import me.rhunk.snapenhance.Constants import me.rhunk.snapenhance.Constants
import me.rhunk.snapenhance.data.ContentType import me.rhunk.snapenhance.data.ContentType
import me.rhunk.snapenhance.database.DatabaseObject import me.rhunk.snapenhance.database.DatabaseObject
import me.rhunk.snapenhance.util.getBlobOrNull
import me.rhunk.snapenhance.util.getInteger
import me.rhunk.snapenhance.util.getLong
import me.rhunk.snapenhance.util.getStringOrNull
import me.rhunk.snapenhance.util.protobuf.ProtoReader import me.rhunk.snapenhance.util.protobuf.ProtoReader
@Suppress("ArrayInDataClass") @Suppress("ArrayInDataClass")
data class ConversationMessage( data class ConversationMessage(
var client_conversation_id: String? = null, var clientConversationId: String? = null,
var client_message_id: Int = 0, var clientMessageId: Int = 0,
var server_message_id: Int = 0, var serverMessageId: Int = 0,
var message_content: ByteArray? = null, var messageContent: ByteArray? = null,
var is_saved: Int = 0, var isSaved: Int = 0,
var is_viewed_by_user: Int = 0, var isViewedByUser: Int = 0,
var content_type: Int = 0, var contentType: Int = 0,
var creation_timestamp: Long = 0, var creationTimestamp: Long = 0,
var read_timestamp: Long = 0, var readTimestamp: Long = 0,
var sender_id: String? = null var senderId: String? = null
) : DatabaseObject { ) : DatabaseObject {
@SuppressLint("Range") @SuppressLint("Range")
override fun write(cursor: Cursor) { override fun write(cursor: Cursor) {
client_conversation_id = cursor.getString(cursor.getColumnIndex("client_conversation_id")) with(cursor) {
client_message_id = cursor.getInt(cursor.getColumnIndex("client_message_id")) clientConversationId = getStringOrNull("client_conversation_id")
server_message_id = cursor.getInt(cursor.getColumnIndex("server_message_id")) clientMessageId = getInteger("client_message_id")
message_content = cursor.getBlob(cursor.getColumnIndex("message_content")) serverMessageId = getInteger("server_message_id")
is_saved = cursor.getInt(cursor.getColumnIndex("is_saved")) messageContent = getBlobOrNull("message_content")
is_viewed_by_user = cursor.getInt(cursor.getColumnIndex("is_viewed_by_user")) isSaved = getInteger("is_saved")
content_type = cursor.getInt(cursor.getColumnIndex("content_type")) isViewedByUser = getInteger("is_viewed_by_user")
creation_timestamp = cursor.getLong(cursor.getColumnIndex("creation_timestamp")) contentType = getInteger("content_type")
read_timestamp = cursor.getLong(cursor.getColumnIndex("read_timestamp")) creationTimestamp = getLong("creation_timestamp")
sender_id = cursor.getString(cursor.getColumnIndex("sender_id")) readTimestamp = getLong("read_timestamp")
senderId = getStringOrNull("sender_id")
}
} }
fun getMessageAsString(): String? { fun getMessageAsString(): String? {
return when (ContentType.fromId(content_type)) { return when (ContentType.fromId(contentType)) {
ContentType.CHAT -> message_content?.let { ProtoReader(it).getString(*Constants.ARROYO_STRING_CHAT_MESSAGE_PROTO) } ContentType.CHAT -> messageContent?.let { ProtoReader(it).getString(*Constants.ARROYO_STRING_CHAT_MESSAGE_PROTO) }
else -> null else -> null
} }
} }

View File

@ -3,6 +3,9 @@ package me.rhunk.snapenhance.database.objects
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.database.Cursor import android.database.Cursor
import me.rhunk.snapenhance.database.DatabaseObject import me.rhunk.snapenhance.database.DatabaseObject
import me.rhunk.snapenhance.util.getInteger
import me.rhunk.snapenhance.util.getLong
import me.rhunk.snapenhance.util.getStringOrNull
data class FriendFeedInfo( data class FriendFeedInfo(
var id: Int = 0, var id: Int = 0,
@ -19,15 +22,17 @@ data class FriendFeedInfo(
@SuppressLint("Range") @SuppressLint("Range")
override fun write(cursor: Cursor) { override fun write(cursor: Cursor) {
id = cursor.getInt(cursor.getColumnIndex("_id")) with(cursor) {
feedDisplayName = cursor.getString(cursor.getColumnIndex("feedDisplayName")) id = getInteger("_id")
participantsSize = cursor.getInt(cursor.getColumnIndex("participantsSize")) feedDisplayName = getStringOrNull("feedDisplayName")
lastInteractionTimestamp = cursor.getLong(cursor.getColumnIndex("lastInteractionTimestamp")) participantsSize = getInteger("participantsSize")
displayTimestamp = cursor.getLong(cursor.getColumnIndex("displayTimestamp")) lastInteractionTimestamp = getLong("lastInteractionTimestamp")
displayInteractionType = cursor.getString(cursor.getColumnIndex("displayInteractionType")) displayTimestamp = getLong("displayTimestamp")
lastInteractionUserId = cursor.getInt(cursor.getColumnIndex("lastInteractionUserId")) displayInteractionType = getStringOrNull("displayInteractionType")
key = cursor.getString(cursor.getColumnIndex("key")) lastInteractionUserId = getInteger("lastInteractionUserId")
friendUserId = cursor.getString(cursor.getColumnIndex("friendUserId")) key = getStringOrNull("key")
friendDisplayName = cursor.getString(cursor.getColumnIndex("friendDisplayUsername")) friendUserId = getStringOrNull("friendUserId")
friendDisplayName = getStringOrNull("friendDisplayUsername")
}
} }
} }

View File

@ -3,6 +3,9 @@ package me.rhunk.snapenhance.database.objects
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.database.Cursor import android.database.Cursor
import me.rhunk.snapenhance.database.DatabaseObject import me.rhunk.snapenhance.database.DatabaseObject
import me.rhunk.snapenhance.util.getInteger
import me.rhunk.snapenhance.util.getLong
import me.rhunk.snapenhance.util.getStringOrNull
data class FriendInfo( data class FriendInfo(
var id: Int = 0, var id: Int = 0,
@ -30,29 +33,31 @@ data class FriendInfo(
) : DatabaseObject { ) : DatabaseObject {
@SuppressLint("Range") @SuppressLint("Range")
override fun write(cursor: Cursor) { override fun write(cursor: Cursor) {
id = cursor.getInt(cursor.getColumnIndex("_id")) with(cursor) {
lastModifiedTimestamp = cursor.getLong(cursor.getColumnIndex("_lastModifiedTimestamp")) id = getInteger("_id")
username = cursor.getString(cursor.getColumnIndex("username")) lastModifiedTimestamp = getLong("_lastModifiedTimestamp")
userId = cursor.getString(cursor.getColumnIndex("userId")) username = getStringOrNull("username")
displayName = cursor.getString(cursor.getColumnIndex("displayName")) userId = getStringOrNull("userId")
bitmojiAvatarId = cursor.getString(cursor.getColumnIndex("bitmojiAvatarId")) displayName = getStringOrNull("displayName")
bitmojiSelfieId = cursor.getString(cursor.getColumnIndex("bitmojiSelfieId")) bitmojiAvatarId = getStringOrNull("bitmojiAvatarId")
bitmojiSceneId = cursor.getString(cursor.getColumnIndex("bitmojiSceneId")) bitmojiSelfieId = getStringOrNull("bitmojiSelfieId")
bitmojiBackgroundId = cursor.getString(cursor.getColumnIndex("bitmojiBackgroundId")) bitmojiSceneId = getStringOrNull("bitmojiSceneId")
friendmojis = cursor.getString(cursor.getColumnIndex("friendmojis")) bitmojiBackgroundId = getStringOrNull("bitmojiBackgroundId")
friendmojiCategories = cursor.getString(cursor.getColumnIndex("friendmojiCategories")) friendmojis = getStringOrNull("friendmojis")
snapScore = cursor.getInt(cursor.getColumnIndex("score")) friendmojiCategories = getStringOrNull("friendmojiCategories")
birthday = cursor.getLong(cursor.getColumnIndex("birthday")) snapScore = getInteger("score")
addedTimestamp = cursor.getLong(cursor.getColumnIndex("addedTimestamp")) birthday = getLong("birthday")
reverseAddedTimestamp = cursor.getLong(cursor.getColumnIndex("reverseAddedTimestamp")) addedTimestamp = getLong("addedTimestamp")
serverDisplayName = cursor.getString(cursor.getColumnIndex("serverDisplayName")) reverseAddedTimestamp = getLong("reverseAddedTimestamp")
streakLength = cursor.getInt(cursor.getColumnIndex("streakLength")) serverDisplayName = getStringOrNull("serverDisplayName")
streakExpirationTimestamp = cursor.getLong(cursor.getColumnIndex("streakExpiration")) streakLength = getInteger("streakLength")
reverseBestFriendRanking = cursor.getInt(cursor.getColumnIndex("reverseBestFriendRanking")) streakExpirationTimestamp = getLong("streakExpiration")
usernameForSorting = cursor.getString(cursor.getColumnIndex("usernameForSorting")) reverseBestFriendRanking = getInteger("reverseBestFriendRanking")
if (cursor.getColumnIndex("isPinnedBestFriend") != -1) isPinnedBestFriend = usernameForSorting = getStringOrNull("usernameForSorting")
cursor.getInt(cursor.getColumnIndex("isPinnedBestFriend")) if (getColumnIndex("isPinnedBestFriend") != -1) isPinnedBestFriend =
if (cursor.getColumnIndex("plusBadgeVisibility") != -1) plusBadgeVisibility = getInteger("isPinnedBestFriend")
cursor.getInt(cursor.getColumnIndex("plusBadgeVisibility")) if (getColumnIndex("plusBadgeVisibility") != -1) plusBadgeVisibility =
getInteger("plusBadgeVisibility")
}
} }
} }

View File

@ -3,6 +3,8 @@ package me.rhunk.snapenhance.database.objects
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.database.Cursor import android.database.Cursor
import me.rhunk.snapenhance.database.DatabaseObject import me.rhunk.snapenhance.database.DatabaseObject
import me.rhunk.snapenhance.util.getInteger
import me.rhunk.snapenhance.util.getStringOrNull
data class StoryEntry( data class StoryEntry(
var id: Int = 0, var id: Int = 0,
@ -14,10 +16,12 @@ data class StoryEntry(
@SuppressLint("Range") @SuppressLint("Range")
override fun write(cursor: Cursor) { override fun write(cursor: Cursor) {
id = cursor.getInt(cursor.getColumnIndex("_id")) with(cursor) {
storyId = cursor.getString(cursor.getColumnIndex("storyId")) id = getInteger("_id")
displayName = cursor.getString(cursor.getColumnIndex("displayName")) storyId = getStringOrNull("storyId")
isLocal = cursor.getInt(cursor.getColumnIndex("isLocal")) == 1 displayName = getStringOrNull("displayName")
userId = cursor.getString(cursor.getColumnIndex("userId")) isLocal = getInteger("isLocal") == 1
userId = getStringOrNull("userId")
}
} }
} }

View File

@ -3,17 +3,21 @@ package me.rhunk.snapenhance.database.objects
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.database.Cursor import android.database.Cursor
import me.rhunk.snapenhance.database.DatabaseObject import me.rhunk.snapenhance.database.DatabaseObject
import me.rhunk.snapenhance.util.getInteger
import me.rhunk.snapenhance.util.getStringOrNull
class UserConversationLink( class UserConversationLink(
var user_id: String? = null, var userId: String? = null,
var client_conversation_id: String? = null, var clientConversationId: String? = null,
var conversation_type: Int = 0 var conversationType: Int = 0
) : DatabaseObject { ) : DatabaseObject {
@SuppressLint("Range") @SuppressLint("Range")
override fun write(cursor: Cursor) { override fun write(cursor: Cursor) {
user_id = cursor.getString(cursor.getColumnIndex("user_id")) with(cursor) {
client_conversation_id = cursor.getString(cursor.getColumnIndex("client_conversation_id")) userId = getStringOrNull("user_id")
conversation_type = cursor.getInt(cursor.getColumnIndex("conversation_type")) clientConversationId = getStringOrNull("client_conversation_id")
conversationType = getInteger("conversation_type")
}
} }
} }

View File

@ -228,8 +228,8 @@ class MediaDownloader : Feature("MediaDownloader", loadParams = FeatureLoadParam
val messageId = id.substring(id.lastIndexOf(":") + 1).toLong() val messageId = id.substring(id.lastIndexOf(":") + 1).toLong()
val conversationMessage = context.database.getConversationMessageFromId(messageId)!! val conversationMessage = context.database.getConversationMessageFromId(messageId)!!
val senderId = conversationMessage.sender_id!! val senderId = conversationMessage.senderId!!
val conversationId = conversationMessage.client_conversation_id!! val conversationId = conversationMessage.clientConversationId!!
if (!forceDownload && context.feature(AntiAutoDownload::class).isUserIgnored(senderId)) { if (!forceDownload && context.feature(AntiAutoDownload::class).isUserIgnored(senderId)) {
return return
@ -240,7 +240,7 @@ class MediaDownloader : Feature("MediaDownloader", loadParams = FeatureLoadParam
downloadOperaMedia(provideDownloadManagerClient( downloadOperaMedia(provideDownloadManagerClient(
pathSuffix = authorUsername, pathSuffix = authorUsername,
mediaIdentifier = "$conversationId$senderId${conversationMessage.server_message_id}", mediaIdentifier = "$conversationId$senderId${conversationMessage.serverMessageId}",
mediaDisplaySource = authorUsername, mediaDisplaySource = authorUsername,
mediaDisplayType = MediaFilter.CHAT_MEDIA.key, mediaDisplayType = MediaFilter.CHAT_MEDIA.key,
friendInfo = author friendInfo = author
@ -266,9 +266,9 @@ class MediaDownloader : Feature("MediaDownloader", loadParams = FeatureLoadParam
?.split(":")?.getOrNull(2) ?: return@let ?.split(":")?.getOrNull(2) ?: return@let
val conversationMessage = context.database.getConversationMessageFromId(arroyoMessageId.toLong()) ?: return@let val conversationMessage = context.database.getConversationMessageFromId(arroyoMessageId.toLong()) ?: return@let
val conversationParticipants = context.database.getConversationParticipants(conversationMessage.client_conversation_id.toString()) ?: return@let val conversationParticipants = context.database.getConversationParticipants(conversationMessage.clientConversationId.toString()) ?: return@let
conversationParticipants.firstOrNull { it != conversationMessage.sender_id } conversationParticipants.firstOrNull { it != conversationMessage.senderId }
} }
val author = context.database.getFriendInfo( val author = context.database.getFriendInfo(
@ -421,18 +421,18 @@ class MediaDownloader : Feature("MediaDownloader", loadParams = FeatureLoadParam
val message = context.database.getConversationMessageFromId(messageId) ?: throw Exception("Message not found in database") val message = context.database.getConversationMessageFromId(messageId) ?: throw Exception("Message not found in database")
//get the message author //get the message author
val friendInfo: FriendInfo = context.database.getFriendInfo(message.sender_id!!) ?: throw Exception("Friend not found in database") val friendInfo: FriendInfo = context.database.getFriendInfo(message.senderId!!) ?: throw Exception("Friend not found in database")
val authorName = friendInfo.usernameForSorting!! val authorName = friendInfo.usernameForSorting!!
var messageContent = message.message_content!! var messageContent = message.messageContent!!
var isArroyoMessage = true var isArroyoMessage = true
var deletedMediaReference: ByteArray? = null var deletedMediaReference: ByteArray? = null
//check if the messageId //check if the messageId
var contentType: ContentType = ContentType.fromId(message.content_type) var contentType: ContentType = ContentType.fromId(message.contentType)
if (messageLogger.isMessageRemoved(message.client_message_id.toLong())) { if (messageLogger.isMessageRemoved(message.clientMessageId.toLong())) {
val messageObject = messageLogger.getMessageObject(message.client_conversation_id!!, message.client_message_id.toLong()) ?: throw Exception("Message not found in database") val messageObject = messageLogger.getMessageObject(message.clientConversationId!!, message.clientMessageId.toLong()) ?: throw Exception("Message not found in database")
isArroyoMessage = false isArroyoMessage = false
val messageContentObject = messageObject.getAsJsonObject("mMessageContent") val messageContentObject = messageObject.getAsJsonObject("mMessageContent")
@ -474,7 +474,7 @@ class MediaDownloader : Feature("MediaDownloader", loadParams = FeatureLoadParam
val encryptionKeys = EncryptionHelper.getEncryptionKeys(contentType, messageReader, isArroyo = isArroyoMessage) val encryptionKeys = EncryptionHelper.getEncryptionKeys(contentType, messageReader, isArroyo = isArroyoMessage)
provideDownloadManagerClient( provideDownloadManagerClient(
pathSuffix = authorName, pathSuffix = authorName,
mediaIdentifier = "${message.client_conversation_id}${message.sender_id}${message.server_message_id}", mediaIdentifier = "${message.clientConversationId}${message.senderId}${message.serverMessageId}",
mediaDisplaySource = authorName, mediaDisplaySource = authorName,
mediaDisplayType = MediaFilter.CHAT_MEDIA.key, mediaDisplayType = MediaFilter.CHAT_MEDIA.key,
friendInfo = friendInfo friendInfo = friendInfo

View File

@ -117,12 +117,12 @@ class FriendFeedInfoMenu : AbstractMenu() {
val messageBuilder = StringBuilder() val messageBuilder = StringBuilder()
messages.forEach{ message: ConversationMessage -> messages.forEach{ message: ConversationMessage ->
val sender: FriendInfo? = participants[message.sender_id] val sender: FriendInfo? = participants[message.senderId]
var messageString: String = message.getMessageAsString() ?: ContentType.fromId(message.content_type).name var messageString: String = message.getMessageAsString() ?: ContentType.fromId(message.contentType).name
if (message.content_type == ContentType.SNAP.id) { if (message.contentType == ContentType.SNAP.id) {
val readTimeStamp: Long = message.read_timestamp val readTimeStamp: Long = message.readTimestamp
messageString = "\uD83D\uDFE5" //red square messageString = "\uD83D\uDFE5" //red square
if (readTimeStamp > 0) { if (readTimeStamp > 0) {
messageString += " \uD83D\uDC40 " //eyes messageString += " \uD83D\uDC40 " //eyes
@ -160,7 +160,7 @@ class FriendFeedInfoMenu : AbstractMenu() {
messages.lastOrNull()?.let { messages.lastOrNull()?.let {
messageBuilder messageBuilder
.append("\n\n") .append("\n\n")
.append(context.translation.format("conversation_preview.total_messages", "count" to it.server_message_id.toString())) .append(context.translation.format("conversation_preview.total_messages", "count" to it.serverMessageId.toString()))
.append("\n") .append("\n")
} }
@ -214,7 +214,7 @@ class FriendFeedInfoMenu : AbstractMenu() {
//old conversation fetch //old conversation fetch
val conversationId = if (messaging.lastFetchConversationUUID == null && focusedConversationTargetUser != null) { val conversationId = if (messaging.lastFetchConversationUUID == null && focusedConversationTargetUser != null) {
val conversation: UserConversationLink = context.database.getDMConversationIdFromUserId(focusedConversationTargetUser) ?: throw IllegalStateException("No conversation found") val conversation: UserConversationLink = context.database.getDMConversationIdFromUserId(focusedConversationTargetUser) ?: throw IllegalStateException("No conversation found")
conversation.client_conversation_id!!.trim().lowercase() conversation.clientConversationId!!.trim().lowercase()
} else { } else {
messaging.lastFetchConversationUUID.toString() messaging.lastFetchConversationUUID.toString()
} }

View File

@ -12,6 +12,15 @@ fun Cursor.getIntOrNull(columnName: String): Int? {
return if (columnIndex == -1) null else getInt(columnIndex) return if (columnIndex == -1) null else getInt(columnIndex)
} }
fun Cursor.getInteger(columnName: String) = getIntOrNull(columnName) ?: throw NullPointerException("Column $columnName is null")
fun Cursor.getLong(columnName: String) = getLongOrNull(columnName) ?: throw NullPointerException("Column $columnName is null")
fun Cursor.getBlobOrNull(columnName: String): ByteArray? {
val columnIndex = getColumnIndex(columnName)
return if (columnIndex == -1) null else getBlob(columnIndex)
}
fun Cursor.getLongOrNull(columnName: String): Long? { fun Cursor.getLongOrNull(columnName: String): Long? {
val columnIndex = getColumnIndex(columnName) val columnIndex = getColumnIndex(columnName)
return if (columnIndex == -1) null else getLong(columnIndex) return if (columnIndex == -1) null else getLong(columnIndex)