Skip to content

Commit

Permalink
Merge branch 'aniyomiorg:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
Dark25 authored Jan 19, 2024
2 parents a797a13 + 3be927b commit 708e780
Show file tree
Hide file tree
Showing 6 changed files with 186 additions and 143 deletions.
2 changes: 1 addition & 1 deletion src/en/fmovies/build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
ext {
extName = 'FMovies'
extClass = '.FMovies'
extVersionCode = 15
extVersionCode = 16
}

apply from: "$rootDir/common.gradle"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class FMovies : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
}

private val vrfHelper by lazy { FMoviesHelper(client, headers) }
private val utils by lazy { FmoviesUtils() }

// ============================== Popular ===============================

Expand Down Expand Up @@ -126,8 +126,7 @@ class FMovies : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
val id = client.newCall(GET(baseUrl + anime.url)).execute().asJsoup()
.selectFirst("div[data-id]")!!.attr("data-id")

val vrf = vrfHelper.getVrf(id)

val vrf = utils.vrfEncrypt(id)
val vrfHeaders = headers.newBuilder().apply {
add("Accept", "application/json, text/javascript, */*; q=0.01")
add("Host", baseUrl.toHttpUrl().host)
Expand Down Expand Up @@ -189,7 +188,7 @@ class FMovies : ConfigurableAnimeSource, ParsedAnimeHttpSource() {

override fun videoListRequest(episode: SEpisode): Request {
val data = json.decodeFromString<EpisodeInfo>(episode.url)
val vrf = vrfHelper.getVrf(data.id)
val vrf = utils.vrfEncrypt(data.id)

val vrfHeaders = headers.newBuilder()
.add("Accept", "application/json, text/javascript, */*; q=0.01")
Expand Down Expand Up @@ -217,7 +216,7 @@ class FMovies : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
if (!hosterSelection.contains(name)) return@parallelCatchingFlatMap emptyList()

// Get decrypted url
val vrf = vrfHelper.getVrf(server.attr("data-link-id"))
val vrf = utils.vrfEncrypt(server.attr("data-link-id"))

val vrfHeaders = headers.newBuilder()
.add("Accept", "application/json, text/javascript, */*; q=0.01")
Expand All @@ -229,8 +228,7 @@ class FMovies : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
GET("$baseUrl/ajax/server/${server.attr("data-link-id")}?vrf=$vrf", headers = vrfHeaders),
).await().parseAs<AjaxServerResponse>().result.url

val decrypted = vrfHelper.decrypt(encrypted)

val decrypted = utils.vrfDecrypt(encrypted)
when (name) {
"Vidplay", "MyCloud" -> vidsrcExtractor.videosFromUrl(decrypted, name)
"Filemoon" -> filemoonExtractor.videosFromUrl(decrypted, headers = headers)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,6 @@ package eu.kanade.tachiyomi.animeextension.en.fmovies

import kotlinx.serialization.Serializable

@Serializable
data class VrfResponse(
val url: String,
val vrfQuery: String? = null,
)

@Serializable
data class AjaxResponse(
val result: String,
Expand Down Expand Up @@ -36,21 +30,25 @@ data class FMoviesSubs(
)

@Serializable
data class RawResponse(
val rawURL: String,
)

@Serializable
data class VidsrcResponse(
val result: ResultObject,
data class MediaResponseBody(
val status: Int,
val result: Result,
) {
@Serializable
data class ResultObject(
val sources: List<SourceObject>,
data class Result(
val sources: ArrayList<Source>,
val tracks: ArrayList<SubTrack> = ArrayList(),
) {
@Serializable
data class SourceObject(
data class Source(
val file: String,
)

@Serializable
data class SubTrack(
val file: String,
val label: String = "",
val kind: String,
)
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package eu.kanade.tachiyomi.animeextension.en.fmovies

import android.util.Base64
import java.net.URLDecoder
import javax.crypto.Cipher
import javax.crypto.spec.SecretKeySpec

class FmoviesUtils {

fun vrfEncrypt(input: String): String {
val rc4Key = SecretKeySpec("FWsfu0KQd9vxYGNB".toByteArray(), "RC4")
val cipher = Cipher.getInstance("RC4")
cipher.init(Cipher.DECRYPT_MODE, rc4Key, cipher.parameters)

var vrf = cipher.doFinal(input.toByteArray())
vrf = Base64.encode(vrf, Base64.URL_SAFE or Base64.NO_WRAP)
vrf = rot13(vrf)
vrf = Base64.encode(vrf, Base64.URL_SAFE or Base64.NO_WRAP)
vrf = vrfShift(vrf)
val stringVrf = vrf.toString(Charsets.UTF_8)
return java.net.URLEncoder.encode(stringVrf, "utf-8")
}

fun vrfDecrypt(input: String): String {
var vrf = input.toByteArray()
vrf = Base64.decode(vrf, Base64.URL_SAFE)

val rc4Key = SecretKeySpec("8z5Ag5wgagfsOuhz".toByteArray(), "RC4")
val cipher = Cipher.getInstance("RC4")
cipher.init(Cipher.DECRYPT_MODE, rc4Key, cipher.parameters)
vrf = cipher.doFinal(vrf)

return URLDecoder.decode(vrf.toString(Charsets.UTF_8), "utf-8")
}

private fun rot13(vrf: ByteArray): ByteArray {
for (i in vrf.indices) {
val byte = vrf[i]
if (byte in 'A'.code..'Z'.code) {
vrf[i] = ((byte - 'A'.code + 13) % 26 + 'A'.code).toByte()
} else if (byte in 'a'.code..'z'.code) {
vrf[i] = ((byte - 'a'.code + 13) % 26 + 'a'.code).toByte()
}
}
return vrf
}

private fun vrfShift(vrf: ByteArray): ByteArray {
for (i in vrf.indices) {
val shift = arrayOf(-4, -2, -6, 5, -2)[i % 5]
vrf[i] = vrf[i].plus(shift).toByte()
}
return vrf
}
}
Loading

0 comments on commit 708e780

Please sign in to comment.