Play with CloudStream, fixed #1335

This commit is contained in:
LagradOst 2022-07-26 04:31:58 +02:00
parent 738d56916f
commit bec9a87eed
6 changed files with 284 additions and 210 deletions

View file

@ -4,7 +4,7 @@
package="com.lagradost.cloudstream3">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- I dont remember, probs has to do with downloads -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.INTERNET" /> <!-- unless you only use cs3 as a player for downloaded stuff, you need this -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <!-- Downloads -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- Downloads on low api devices-->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <!-- some dependency needs this -->
@ -53,13 +53,19 @@
<data android:scheme="content" />
<data android:mimeType="video/*" />
</intent-filter>
<!-- I dont think this label can be translated, but idk -->
<intent-filter android:label="@string/play_with_app_name">
<action android:name="android.intent.action.SEND"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="*/*"/>
</intent-filter>
</activity>
<activity
android:exported="true"
android:name=".MainActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout|keyboard|keyboardHidden|navigation"
android:label="@string/app_name"
android:resizeableActivity="true"
android:supportsPictureInPicture="true">
<intent-filter android:exported="true">
@ -68,11 +74,15 @@
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
</intent-filter>
<intent-filter android:exported="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="https" android:host="elifilms.net" android:pathPrefix="/"/>
<data android:scheme="https" android:host="www23.estrenosdoramas.net" android:pathPrefix="/"/>
<data android:scheme="https" android:host="pelisplus.icu" android:pathPrefix="/"/>
<data android:scheme="https" android:host="pelisplushd.net" android:pathPrefix="/"/>
<data android:scheme="https" android:host="pelismart.com" android:pathPrefix="/"/>
@ -84,15 +94,15 @@
<data android:scheme="https" android:host="pelisflix.li" android:pathPrefix="/"/>
<data android:scheme="https" android:host="seriesflix.video" android:pathPrefix="/"/>
<data android:scheme="https" android:host="ihavenotv.com" android:pathPrefix="/"/>
<data android:scheme="https" android:host="lookmovie.io" android:pathPrefix="/"/>
<data android:scheme="https" android:host="www.vmovee.watch" android:pathPrefix="/"/>
<data android:scheme="https" android:host="allmoviesforyou.net" android:pathPrefix="/"/>
<data android:scheme="https" android:host="vidembed.cc" android:pathPrefix="/"/>
<data android:scheme="https" android:host="membed.net" android:pathPrefix="/"/>
<data android:scheme="https" android:host="vf-film.me" android:pathPrefix="/"/>
<data android:scheme="https" android:host="vf-serie.org" android:pathPrefix="/"/>
<data android:scheme="https" android:host="french-stream.re" android:pathPrefix="/"/>
<data android:scheme="https" android:host="asianembed.io" android:pathPrefix="/"/>
<data android:scheme="https" android:host="asiaflix.app" android:pathPrefix="/"/>
<data android:scheme="https" android:host="eja.tv/" android:pathPrefix="/"/>
<data android:scheme="https" android:host="bflix.ru" android:pathPrefix="/"/>
<data android:scheme="https" android:host="fmovies.to" android:pathPrefix="/"/>
<data android:scheme="https" android:host="sflix.pro" android:pathPrefix="/"/>
@ -104,39 +114,71 @@
<data android:scheme="https" android:host="www.pinoy-hd.xyz" android:pathPrefix="/"/>
<data android:scheme="https" android:host="pinoymovies.es" android:pathPrefix="/"/>
<data android:scheme="https" android:host="trailers.to" android:pathPrefix="/"/>
<data android:scheme="https" android:host="www.2embed.ru" android:pathPrefix="/"/>
<data android:scheme="https" android:host="2embed.org" android:pathPrefix="/"/>
<data android:scheme="https" android:host="dramasee.net" android:pathPrefix="/"/>
<data android:scheme="https" android:host="watchasian.sh" android:pathPrefix="/"/>
<data android:scheme="https" android:host="watchasian.cx" android:pathPrefix="/"/>
<data android:scheme="https" android:host="185.224.83.103" android:pathPrefix="/"/>
<data android:scheme="https" android:host="kdramahood.com" android:pathPrefix="/"/>
<data android:scheme="https" android:host="akwam.to" android:pathPrefix="/"/>
<data android:scheme="https" android:host="mycima.tv" android:pathPrefix="/"/>
<data android:scheme="https" android:host="cimanow.cc" android:pathPrefix="/"/>
<data android:scheme="https" android:host="www.egy.best" android:pathPrefix="/"/>
<data android:scheme="https" android:host="faselhd.io" android:pathPrefix="/"/>
<data android:scheme="https" android:host="secretlink.xyz" android:pathPrefix="/"/>
<data android:scheme="https" android:host="hdm.to" android:pathPrefix="/"/>
<data android:scheme="https" android:host="theflix.to" android:pathPrefix="/"/>
<data android:scheme="https" android:host="streamingcommunity.best" android:pathPrefix="/"/>
<data android:scheme="https" android:host="altadefinizione.tienda" android:pathPrefix="/"/>
<data android:scheme="https" android:host="cb01.rip" android:pathPrefix="/"/>
<data android:scheme="https" android:host="filmpertutti.love" android:pathPrefix="/"/>
<data android:scheme="https" android:host="www.tantifilm.nl" android:pathPrefix="/"/>
<data android:scheme="https" android:host="v2.apimdb.net" android:pathPrefix="/"/>
<data android:scheme="https" android:host="cb01.rip" android:pathPrefix="/"/>
<data android:scheme="https" android:host="altadefinizione.tienda" android:pathPrefix="/"/>
<data android:scheme="https" android:host="filmpertutti.love" android:pathPrefix="/"/>
<data android:scheme="https" android:host="hdmovie2.art" android:pathPrefix="/"/>
<data android:scheme="https" android:host="http://167.88.14.149" android:pathPrefix="/"/>
<data android:scheme="https" android:host="149.56.24.226" android:pathPrefix="/"/>
<data android:scheme="https" android:host="hdtoday.cc" android:pathPrefix="/"/>
<data android:scheme="https" android:host="openvids.io" android:pathPrefix="/"/>
<data android:scheme="https" android:host="94.103.82.88" android:pathPrefix="/"/>
<data android:scheme="https" android:host="146.19.24.137" android:pathPrefix="/"/>
<data android:scheme="https" android:host="v2.vidsrc.me" android:pathPrefix="/"/>
<data android:scheme="https" android:host="uakino.club" android:pathPrefix="/"/>
<data android:scheme="https" android:host="phimmoichill.net" android:pathPrefix="/"/>
<data android:scheme="https" android:host="rezka.ag" android:pathPrefix="/"/>
<data android:scheme="https" android:host="yomovies.plus" android:pathPrefix="/"/>
<data android:scheme="https" android:host="www.wcostream.com" android:pathPrefix="/"/>
<data android:scheme="https" android:host="gogoanime.film" android:pathPrefix="/"/>
<data android:scheme="https" android:host="gogoanime.sk" android:pathPrefix="/"/>
<data android:scheme="https" android:host="allanime.site" android:pathPrefix="/"/>
<data android:scheme="https" android:host="animekisa.in" android:pathPrefix="/"/>
<data android:scheme="https" android:host="animeflick.net" android:pathPrefix="/"/>
<data android:scheme="https" android:host="www3.animeflv.net" android:pathPrefix="/"/>
<data android:scheme="https" android:host="animefenix.com" android:pathPrefix="/"/>
<data android:scheme="https" android:host="animeflv.io" android:pathPrefix="/"/>
<data android:scheme="https" android:host="jkanime.net" android:pathPrefix="/"/>
<data android:scheme="https" android:host="tenshi.moe" android:pathPrefix="/"/>
<data android:scheme="https" android:host="wcostream.cc" android:pathPrefix="/"/>
<data android:scheme="https" android:host="animepahe.com" android:pathPrefix="/"/>
<data android:scheme="https" android:host="dreamsub.me" android:pathPrefix="/"/>
<data android:scheme="https" android:host="9anime.id" android:pathPrefix="/"/>
<data android:scheme="https" android:host="www.animeworld.tv" android:pathPrefix="/"/>
<data android:scheme="https" android:host="zoro.to" android:pathPrefix="/"/>
<data android:scheme="https" android:host="bestdubbedanime.com" android:pathPrefix="/"/>
<data android:scheme="https" android:host="monoschinos2.com" android:pathPrefix="/"/>
<data android:scheme="https" android:host="www.mundodonghua.com" android:pathPrefix="/"/>
<data android:scheme="https" android:host="kawaiifu.com" android:pathPrefix="/"/>
<data android:scheme="https" android:host="neonime.watch" android:pathPrefix="/"/>
<data android:scheme="https" android:host="kuramanime.com" android:pathPrefix="/"/>
<data android:scheme="https" android:host="65.108.132.145" android:pathPrefix="/"/>
<data android:scheme="https" android:host="185.231.223.76" android:pathPrefix="/"/>
<data android:scheme="https" android:host="75.119.159.228" android:pathPrefix="/"/>
<data android:scheme="https" android:host="45.12.2.2" android:pathPrefix="/"/>
<data android:scheme="https" android:host="otakudesu.watch" android:pathPrefix="/"/>
<data android:scheme="https" android:host="animeindo.sbs" android:pathPrefix="/"/>
<data android:scheme="https" android:host="111.90.143.42" android:pathPrefix="/"/>
<data android:scheme="https" android:host="tocanime.co" android:pathPrefix="/"/>
<data android:scheme="https" android:host="olgply.com" android:pathPrefix="/"/>
<data android:scheme="https" android:host="aniflix.pro" android:pathPrefix="/"/>
<data android:scheme="https" android:host="kimcartoon.li" android:pathPrefix="/"/>
<data android:scheme="https" android:host="xcine.me" android:pathPrefix="/"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />

View file

@ -1,5 +1,7 @@
package com.lagradost.cloudstream3.ui.player
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.util.Log
import android.view.KeyEvent
@ -35,6 +37,34 @@ class DownloadedPlayerActivity : AppCompatActivity() {
finish()
}
private fun playLink(url: String) {
this.navigate(
R.id.global_to_navigation_player, GeneratorPlayer.newInstance(
LinkGenerator(
listOf(
url
)
)
)
)
}
private fun playUri(uri: Uri) {
val name = UniFile.fromUri(this, uri).name
this.navigate(
R.id.global_to_navigation_player, GeneratorPlayer.newInstance(
DownloadFileGenerator(
listOf(
ExtractorUri(
uri = uri,
name = name ?: getString(R.string.downloaded_file)
)
)
)
)
)
}
override fun onCreate(savedInstanceState: Bundle?) {
Log.i(DTAG, "onCreate")
@ -45,69 +75,35 @@ class DownloadedPlayerActivity : AppCompatActivity() {
setContentView(R.layout.empty_layout)
val data = intent.data
if (data == null) {
if (intent?.action == Intent.ACTION_SEND) {
val extraText = try { // I dont trust android
intent.getStringExtra(Intent.EXTRA_TEXT)
} catch (e: Exception) {
null
}
val cd = intent.clipData
val item = if (cd != null && cd.itemCount > 0) cd.getItemAt(0) else null
val url = item?.text?.toString()
// idk what I am doing, just hope any of these work
if (item?.uri != null)
playUri(item.uri)
else if (url != null)
playLink(url)
else if (data != null)
playUri(data)
else if (extraText != null)
playLink(extraText)
else {
finish()
return
}
if (data.scheme == "content") {
val name = UniFile.fromUri(this, data).name
this.navigate(
R.id.global_to_navigation_player, GeneratorPlayer.newInstance(
DownloadFileGenerator(
listOf(
ExtractorUri(
uri = data,
name = name ?: getString(R.string.downloaded_file)
)
)
)
)
)
} else if (data?.scheme == "content") {
playUri(data)
} else {
finish()
return
}
// Legacy code, seems to work perfectly fine without it
// } else {
// val uri = getUri(intent.data)
// if (uri == null) {
// finish()
// return
// }
// val path = uri.path
// // Because it doesn't get the path when it's downloaded, I have no idea
// val realPath = if (File(
// intent.data?.path?.removePrefix("/file") ?: "NONE"
// ).exists()
// ) intent.data?.path?.removePrefix("/file") else path
//
// if (realPath == null) {
// finish()
// return
// }
//
// val name = try {
// File(realPath).name
// } catch (e: Exception) {
// "NULL"
// }
//
// val tryUri = try {
// AppUtils.getVideoContentUri(this, realPath) ?: uri
// } catch (e: Exception) {
// logError(e)
// uri
// }
//
// setContentView(R.layout.empty_layout)
// Log.i(DTAG, "navigating")
//
// //TODO add relative path for subs
// this.navigate(
// R.id.global_to_navigation_player, GeneratorPlayer.newInstance(
// DownloadFileGenerator(listOf(ExtractorUri(uri = tryUri, name = name)))
// )
// )
// }
}
}

View file

@ -1,10 +1,7 @@
package com.lagradost.cloudstream3.ui.player
import com.lagradost.cloudstream3.apmap
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.ExtractorUri
import com.lagradost.cloudstream3.utils.Qualities
import com.lagradost.cloudstream3.utils.loadExtractor
import com.lagradost.cloudstream3.utils.*
class LinkGenerator(
private val links: List<String>,
@ -50,12 +47,13 @@ class LinkGenerator(
if (!extract || !loadExtractor(link, referer) {
callback(it to null)
}) {
// if don't extract or if no extractor found simply return the link
callback(
ExtractorLink(
"",
link,
link,
unshortenLinkSafe(link), // unshorten because it might be a raw link
referer ?: "",
Qualities.Unknown.value, link.contains(".m3u") // TODO USE REAL PARSER
) to null

View file

@ -5,6 +5,7 @@ import com.lagradost.cloudstream3.TvType
import com.lagradost.cloudstream3.USER_AGENT
import com.lagradost.cloudstream3.app
import com.lagradost.cloudstream3.extractors.*
import com.lagradost.cloudstream3.mvvm.logError
import com.lagradost.cloudstream3.mvvm.suspendSafeApiCall
import kotlinx.coroutines.delay
import org.jsoup.Jsoup
@ -143,6 +144,17 @@ fun getAndUnpack(string: String): String {
return JsUnpacker(packedText).unpack() ?: string
}
suspend fun unshortenLinkSafe(url : String) : String {
return try {
if (ShortLink.isShortLink(url))
ShortLink.unshorten(url)
else url
} catch (e: Exception) {
logError(e)
url
}
}
/**
* Tries to load the appropriate extractor based on link, returns true if any extractor is loaded.
* */
@ -151,14 +163,17 @@ suspend fun loadExtractor(
referer: String? = null,
callback: (ExtractorLink) -> Unit
): Boolean {
val currentUrl = unshortenLinkSafe(url)
for (extractor in extractorApis) {
if (url.replace(schemaStripRegex, "")
if (currentUrl.replace(schemaStripRegex, "")
.startsWith(extractor.mainUrl.replace(schemaStripRegex, ""))
) {
extractor.getSafeUrl(url, referer)?.forEach(callback)
extractor.getSafeUrl(currentUrl, referer)?.forEach(callback)
return true
}
}
return false
}
@ -166,9 +181,11 @@ suspend fun loadExtractor(
url: String,
referer: String? = null,
): List<ExtractorLink> {
val currentUrl = unshortenLinkSafe(url)
for (extractor in extractorApis) {
if (url.startsWith(extractor.mainUrl)) {
return extractor.getSafeUrl(url, referer) ?: emptyList()
if (currentUrl.startsWith(extractor.mainUrl)) {
return extractor.getSafeUrl(currentUrl, referer) ?: emptyList()
}
}
return emptyList()

View file

@ -1,4 +1,5 @@
package com.lagradost.cloudstream3.utils
import android.util.Base64
import com.lagradost.cloudstream3.app
import com.lagradost.cloudstream3.base64Decode
@ -8,163 +9,182 @@ import java.net.URLDecoder
//Code heavily based on unshortenit.py form kodiondemand /addon
private data class ShortUrl(
object ShortLink {
data class ShortUrl(
val regex: Regex,
val type: String,
val function: suspend (String) -> String,
) {
) {
constructor(regex: String, type: String, function: suspend (String) -> String) : this(
Regex(regex),
type,
function
)
companion object {
val adflyRegex = """adf\.ly|j\.gs|q\.gs|u\.bb|ay\.gy|atominik\.com|tinyium\.com|microify\.com|threadsphere\.bid|clearload\.bid|activetect\.net|swiftviz\.net|briskgram\.net|activetect\.net|stoodsef\.com|baymaleti\.net|thouth\.net|uclaut\.net|gloyah\.net|larati\.net|scuseami\.net"""
val linkupRegex = """linkup\.pro|buckler.link"""
val linksafeRegex = """linksafe\.cc"""
val nuovoIndirizzoRegex = """mixdrop\.nuovoindirizzo\.com"""
val nuovoLinkRegex = """nuovolink\.com"""
val uprotRegex = """uprot\.net"""
val davisonbarkerRegex = """davisonbarker\.pro|lowrihouston\.pro"""
}
val shortList = listOf(
ShortUrl(adflyRegex,"adfly",::unshortenAdfly),
ShortUrl(linkupRegex,"linkup",::unshortenLinkup),
ShortUrl(linksafeRegex,"linksafe",::unshortenLinksafe),
ShortUrl(nuovoIndirizzoRegex,"nuovoindirizzo",::unshortenNuovoIndirizzo),
ShortUrl(nuovoLinkRegex,"nuovolink",::unshortenNuovoLink),
ShortUrl(uprotRegex,"uprot",::unshortenUprot),
ShortUrl(davisonbarkerRegex,"uprot",::unshortenDavisonbarker),
private val adflyRegex =
"""adf\.ly|j\.gs|q\.gs|u\.bb|ay\.gy|atominik\.com|tinyium\.com|microify\.com|threadsphere\.bid|clearload\.bid|activetect\.net|swiftviz\.net|briskgram\.net|activetect\.net|stoodsef\.com|baymaleti\.net|thouth\.net|uclaut\.net|gloyah\.net|larati\.net|scuseami\.net"""
private val linkupRegex = """linkup\.pro|buckler.link"""
private val linksafeRegex = """linksafe\.cc"""
private val nuovoIndirizzoRegex = """mixdrop\.nuovoindirizzo\.com"""
private val nuovoLinkRegex = """nuovolink\.com"""
private val uprotRegex = """uprot\.net"""
private val davisonbarkerRegex = """davisonbarker\.pro|lowrihouston\.pro"""
private val shortList = listOf(
ShortUrl(adflyRegex, "adfly", ::unshortenAdfly),
ShortUrl(linkupRegex, "linkup", ::unshortenLinkup),
ShortUrl(linksafeRegex, "linksafe", ::unshortenLinksafe),
ShortUrl(nuovoIndirizzoRegex, "nuovoindirizzo", ::unshortenNuovoIndirizzo),
ShortUrl(nuovoLinkRegex, "nuovolink", ::unshortenNuovoLink),
ShortUrl(uprotRegex, "uprot", ::unshortenUprot),
ShortUrl(davisonbarkerRegex, "uprot", ::unshortenDavisonbarker),
)
}
}
class ShortLink{
fun isShortLink(url : String) : Boolean{
return ShortUrl.shortList.firstOrNull {
it.regex.find(url) != null}!=null
fun isShortLink(url: String): Boolean {
return shortList.any {
it.regex.find(url) != null
}
}
suspend fun unshorten(uri: String, type: String? = null): String {
var currentUrl = uri
while (true) {
val oldurl = currentUrl
val domain = URI(currentUrl).host ?: throw IllegalArgumentException("No domain found in URI!")
currentUrl = ShortUrl.shortList.firstOrNull {
val domain =
URI(currentUrl).host ?: throw IllegalArgumentException("No domain found in URI!")
currentUrl = shortList.firstOrNull {
it.regex.find(domain) != null || type == it.type
}?.function?.let { it(currentUrl) } ?: break
if (oldurl == currentUrl){
if (oldurl == currentUrl) {
break
}
}
return currentUrl
}
}
suspend fun unshortenAdfly(uri: String): String{
val html = app.get(uri).text
val ysmm = Regex("""var ysmm =.*\;?""").find(html)!!.value
if (ysmm.isNotEmpty()){
suspend fun unshortenAdfly(uri: String): String {
val html = app.get(uri).text
val ysmm = Regex("""var ysmm =.*;?""").find(html)!!.value
if (ysmm.isNotEmpty()) {
var left = ""
var right = ""
for (c in ysmm.replace(Regex("""var ysmm \= \'|\'\;"""),"").chunked(2).dropLastWhile {it.length==1}) {
for (c in ysmm.replace(Regex("""var ysmm = '|';"""), "").chunked(2)
.dropLastWhile { it.length == 1 }) {
left += c[0]
right = c[1] + right
}
val encodedUri = (left + right).toMutableList()
val numbers = encodedUri.mapIndexed{ i, n-> Pair(i,n)}.filter{it.second.isDigit()}
for (el in numbers.chunked(2).dropLastWhile {it.size==1}){
val numbers =
encodedUri.mapIndexed { i, n -> Pair(i, n) }.filter { it.second.isDigit() }
for (el in numbers.chunked(2).dropLastWhile { it.size == 1 }) {
val xor = (el[0].second).code.xor(el[1].second.code)
if (xor < 10){
if (xor < 10) {
encodedUri[el[0].first] = xor.digitToChar()
}
}
val encodedbytearray = encodedUri.map { it.code.toByte() }.toByteArray()
var decodedUri = Base64.decode(encodedbytearray,Base64.DEFAULT).decodeToString().dropLast(16).drop(16)
var decodedUri =
Base64.decode(encodedbytearray, Base64.DEFAULT).decodeToString().dropLast(16)
.drop(16)
if (Regex("""go\.php\?u\=""").find(decodedUri) != null){
decodedUri = Base64.decode(decodedUri.replace(Regex("""(.*?)u="""),""),Base64.DEFAULT).decodeToString()
if (Regex("""go\.php\?u=""").find(decodedUri) != null) {
decodedUri =
Base64.decode(decodedUri.replace(Regex("""(.*?)u="""), ""), Base64.DEFAULT)
.decodeToString()
}
return decodedUri
}
else {
} else {
return uri
}
return uri
}
suspend fun unshortenLinkup(uri: String): String {
}
suspend fun unshortenLinkup(uri: String): String {
var r: NiceResponse? = null
var uri = uri
when{
when {
uri.contains("/tv/") -> uri = uri.replace("/tv/", "/tva/")
uri.contains("delta") -> uri = uri.replace("/delta/", "/adelta/")
(uri.contains("/ga/") || uri.contains("/ga2/")) -> uri = base64Decode(uri.split('/').last()).trim()
uri.contains("/speedx/") -> uri = uri.replace("http://linkup.pro/speedx", "http://speedvideo.net")
(uri.contains("/ga/") || uri.contains("/ga2/")) -> uri =
base64Decode(uri.split('/').last()).trim()
uri.contains("/speedx/") -> uri =
uri.replace("http://linkup.pro/speedx", "http://speedvideo.net")
else -> {
r = app.get(uri, allowRedirects = true)
uri = r.url
val link =
Regex("<iframe[^<>]*src=\\'([^'>]*)\\'[^<>]*>").find(r.text)?.value ?:
Regex("""action="(?:[^/]+.*?/[^/]+/([a-zA-Z0-9_]+))">""").find(r.text)?.value ?:
Regex("""href","((.|\\n)*?)"""").findAll(r.text).elementAtOrNull(1)?.groupValues?.get(1)
Regex("<iframe[^<>]*src=\\'([^'>]*)\\'[^<>]*>").find(r.text)?.value
?: Regex("""action="(?:[^/]+.*?/[^/]+/([a-zA-Z0-9_]+))">""").find(r.text)?.value
?: Regex("""href","((.|\\n)*?)"""").findAll(r.text)
.elementAtOrNull(1)?.groupValues?.get(1)
if (link!=null) {
if (link != null) {
uri = link
}
}
}
val short = Regex("""^https?://.*?(https?://.*)""").find(uri)?.value
if (short!=null){
if (short != null) {
uri = short
}
if (r==null){
if (r == null) {
r = app.get(
uri,
allowRedirects = false)
if (r.headers["location"]!= null){
allowRedirects = false
)
if (r.headers["location"] != null) {
uri = r.headers["location"].toString()
}
}
if (uri.contains("snip.")) {
if (uri.contains("out_generator")) {
uri = Regex("url=(.*)\$").find(uri)!!.value
}
else if (uri.contains("/decode/")) {
} else if (uri.contains("/decode/")) {
uri = app.get(uri, allowRedirects = true).url
}
}
return uri
}
fun unshortenLinksafe(uri:String) : String {
}
fun unshortenLinksafe(uri: String): String {
return base64Decode(uri.split("?url=").last())
}
suspend fun unshortenNuovoIndirizzo(uri:String) : String {
}
suspend fun unshortenNuovoIndirizzo(uri: String): String {
val soup = app.get(uri, allowRedirects = true)
val header = soup.headers["refresh"]
val link : String= if (header != null) {
soup.headers["refresh"]!!.substringAfter("=") }
else{
val link: String = if (header != null) {
soup.headers["refresh"]!!.substringAfter("=")
} else {
"non trovato"
}
return link
}
suspend fun unshortenNuovoLink(uri:String) : String {
}
suspend fun unshortenNuovoLink(uri: String): String {
return app.get(uri, allowRedirects = true).document.selectFirst("a")!!.attr("href")
}
suspend fun unshortenUprot(uri: String): String {
}
suspend fun unshortenUprot(uri: String): String {
val page = app.get(uri).text
Regex("""<a[^>]+href="([^"]+)""").findAll(page).map { it.value.replace("""<a href="""","") }.toList().forEach { link ->
if (link.contains("https://maxstream.video") || link.contains("https://uprot.net") && link != uri){
Regex("""<a[^>]+href="([^"]+)""").findAll(page)
.map { it.value.replace("""<a href="""", "") }
.toList().forEach { link ->
if (link.contains("https://maxstream.video") || link.contains("https://uprot.net") && link != uri) {
return link
}
}
return uri
}
fun unshortenDavisonbarker(uri: String): String {
}
fun unshortenDavisonbarker(uri: String): String {
return URLDecoder.decode(uri.substringAfter("dest="))
}
}

View file

@ -92,6 +92,7 @@
<string name="duration_format" formatted="true">%d min</string>
<string name="app_name">CloudStream</string>
<string name="play_with_app_name">Play with CloudStream</string>
<string name="title_home">Home</string>
<string name="title_search">Search</string>
<string name="title_downloads">Downloads</string>