Skip to content

Commit

Permalink
fix: FlixHQ emergency fix
Browse files Browse the repository at this point in the history
  • Loading branch information
rhenwinch committed Feb 15, 2024
1 parent 8769e42 commit 8549712
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 80 deletions.
1 change: 0 additions & 1 deletion .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ val versionPatch = 0
val versionBuild = 0
val applicationName: String = libs.versions.applicationName.get()
val _applicationId: String = libs.versions.applicationId.get()
val _versionName = "${versionMajor}.${versionMinor}.${versionPatch}"
val _versionName = "${versionMajor}.${versionMinor}.${versionPatch}-beta" // TODO: Remove beta


android {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,12 @@ object CryptographyUtil {
* @param data The base64-encoded string to decode.
* @return The decoded string.
*/
fun base64Decode(data: String): String = String(Base64.decode(data, Base64.DEFAULT))
fun base64Decode(data: String, flag: Int = Base64.DEFAULT): String = String(Base64.decode(data, flag))

/**
* Encodes the specified data into a base64-encoded string.
* @param data The data to encode.
* @return The base64-encoded string.
*/
fun base64Encode(data: ByteArray): String = Base64.encodeToString(data, Base64.DEFAULT)
fun base64Encode(data: ByteArray, flag: Int = Base64.DEFAULT): String = String(Base64.encode(data, flag))
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ import com.flixclusive.core.util.network.request
import com.flixclusive.extractor.upcloud.dto.DecryptedSource
import com.flixclusive.extractor.upcloud.dto.UpCloudEmbedData
import com.flixclusive.extractor.upcloud.dto.UpCloudEmbedData.Companion.toSubtitle
import com.flixclusive.extractor.upcloud.util.DecryptUtils.extractEmbedDecryptionDetails
import com.flixclusive.extractor.upcloud.util.DecryptUtils.getKeyStops
import com.flixclusive.extractor.upcloud.util.getKey
import com.flixclusive.model.provider.SourceLink
import com.flixclusive.model.provider.Subtitle
import com.flixclusive.provider.base.extractor.Extractor
Expand All @@ -33,7 +32,7 @@ class VidCloud(

override val host: String = "https://rabbitstream.net"
private val alternateHost: String = "https://dokicloud.one"
private val e4ScriptEndpoint = "https://rabbitstream.net/js/player/prod/e4-player.min.js"
private val luckyAnimalImage = "https://rabbitstream.net/images/lucky_animal/icon.png"

private fun getHost(isAlternative: Boolean) =
(if (isAlternative) "DokiCloud" else "Rabbitstream")
Expand Down Expand Up @@ -79,18 +78,15 @@ class VidCloud(
var sources = mutableListOf<DecryptedSource>()

if (upCloudEmbedData.encrypted) {
val e4Script = client.request(
url = e4ScriptEndpoint,
headers = options
).execute().body?.string()
?: throw Exception("Cannot fetch key decoder")

val stops = getKeyStops(e4Script)
val (decryptedKey, newSource) = extractEmbedDecryptionDetails(upCloudEmbedData.sources, stops)

sources = fromJson<MutableList<DecryptedSource>>(
decryptAes(newSource, decryptedKey)
)
client.request(luckyAnimalImage).execute()
.use { keyResponse ->
keyResponse.body?.run {
val key = getKey(byteStream())
sources = fromJson<MutableList<DecryptedSource>>(
decryptAes(upCloudEmbedData.sources, key)
)
}
}
}


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package com.flixclusive.extractor.upcloud.util

import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.util.Base64
import com.flixclusive.core.util.network.CryptographyUtil
import java.io.InputStream

fun getKey(responseBodyStream: InputStream): String {
val bitmap = BitmapFactory.decodeStream(responseBodyStream)

val rgba = bitmapToRgba(bitmap)

val binary = extractBitsFromImage(rgba)
val hexCompiledString = binaryToASCII(binary)
val keys = convertHexToIntegers(hexCompiledString)

return encodeIntegersToBase64(keys)
}

private fun bitmapToRgba(bitmap: Bitmap): ByteArray {
require(bitmap.config == Bitmap.Config.ARGB_8888) { "Bitmap must be in ARGB_8888 format" }
val pixels = IntArray(bitmap.width * bitmap.height)
val bytes = ByteArray(pixels.size * 4)
bitmap.getPixels(pixels, 0, bitmap.width, 0, 0, bitmap.width, bitmap.height)
var i = 0
for (pixel in pixels) {
// Get components assuming is ARGB
val A = pixel shr 24 and 0xff
val R = pixel shr 16 and 0xff
val G = pixel shr 8 and 0xff
val B = pixel and 0xff
bytes[i++] = R.toByte()
bytes[i++] = G.toByte()
bytes[i++] = B.toByte()
bytes[i++] = A.toByte()
}
return bytes
}

private fun extractBitsFromImage(imageData: ByteArray): String {
val i = 8 * imageData[3]
val stringBuilder = StringBuilder()

for (j in 0 until i) {
stringBuilder.append(imageData[4 * (j + 1) + 3] % 2)
}

return stringBuilder.toString()
}

private fun binaryToASCII(string: String): String {
val chunks = string.chunked(8) // Splits the string into chunks of 8 characters
val asciiChars = chunks.map { chunk -> chunk.toInt(2).toChar() } // Converts each chunk from binary to decimal and then to its corresponding ASCII character
return asciiChars.joinToString("") // Joins the ASCII characters into a single string
}

private fun convertHexToIntegers(hexString: String): List<Int> {
val keys = mutableListOf<Int>()
var i = 0
while (i < hexString.length) {
// Convert each pair of hexadecimal characters into an integer
val hexPair = hexString.substring(i, i + 2)
keys.add(hexPair.toInt(16))
i += 2
}
return keys
}

private fun encodeIntegersToBase64(keys: List<Int>): String {
val keyBytes = keys.toByteArray()
return CryptographyUtil.base64Encode(keyBytes, Base64.NO_WRAP) // Encode the bytes to base64
}

private fun List<Int>.toByteArray(): ByteArray {
val result = ByteArray(size)
for (i in indices) {
result[i] = get(i).toByte()
}
return result
}

This file was deleted.

0 comments on commit 8549712

Please sign in to comment.