package me.eternal.purrfect.core.features.impl.spying import me.eternal.purrfect.common.data.MessagingRuleType import me.eternal.purrfect.common.data.RuleState import me.eternal.purrfect.core.event.events.impl.OnSnapInteractionEvent import me.eternal.purrfect.core.features.MessagingRuleFeature import me.eternal.purrfect.core.util.hook.HookStage import me.eternal.purrfect.core.util.hook.hook import me.eternal.purrfect.core.wrapper.impl.SnapUUID import java.util.concurrent.CopyOnWriteArraySet import java.util.concurrent.ConcurrentHashMap class StealthMode : MessagingRuleFeature("StealthMode", MessagingRuleType.STEALTH) { private val displayedMessageQueue = CopyOnWriteArraySet() private val snapInteractionQueue = CopyOnWriteArraySet() private fun getTargetId(conversationId: String): String { return context.database.getDMOtherParticipant(conversationId) ?: conversationId } fun canUseChatStealth(conversationId: String): Boolean { return canUseRule(conversationId) || (context.feature(ChatStealth::class)?.canUseRule(conversationId) ?: false) } fun canUseSnapStealth(conversationId: String): Boolean { return canUseRule(conversationId) || (context.feature(SnapStealth::class)?.canUseRule(conversationId) ?: false) } fun isAnyStealthEnabled(conversationId: String): Boolean { return canUseChatStealth(conversationId) || canUseSnapStealth(conversationId) } fun addDisplayedMessageException(clientMessageId: Long) { displayedMessageQueue.add(clientMessageId) } fun addSnapInteractionException(messageId: Long) { snapInteractionQueue.add(messageId) } override fun init() { arrayOf("mediaMessagesDisplayed", "displayedMessages").forEach { methodName: String -> context.classCache.conversationManager.hook(methodName, HookStage.BEFORE) { param -> if (displayedMessageQueue.removeIf { param.arg(1) == it }) return@hook if (canUseChatStealth(SnapUUID(param.arg(0)).toString())) { param.setResult(null) } } } context.event.subscribe(OnSnapInteractionEvent::class) { event -> if (snapInteractionQueue.removeIf { event.messageId == it }) return@subscribe if (canUseSnapStealth(event.conversationId.toString())) { event.canceled = true } } } } class SnapStealth : MessagingRuleFeature("SnapStealth", MessagingRuleType.SNAP_STEALTH) { override fun init() {} } class ChatStealth : MessagingRuleFeature("ChatStealth", MessagingRuleType.CHAT_STEALTH) { override fun init() {} }