parent
							
								
									5b5657ff14
								
							
						
					
					
						commit
						14ad5b9027
					
				
							
								
								
									
										14
									
								
								src/th/manhuathai/build.gradle
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/th/manhuathai/build.gradle
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,14 @@
 | 
			
		||||
ext {
 | 
			
		||||
    extName = 'ManhuaThai'
 | 
			
		||||
    extClass = '.ManhuaThai'
 | 
			
		||||
    themePkg = 'madara'
 | 
			
		||||
    baseUrl = 'https://www.manhuathai.com'
 | 
			
		||||
    overrideVersionCode = 0
 | 
			
		||||
    isNsfw = false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
apply from: "$rootDir/common.gradle"
 | 
			
		||||
 | 
			
		||||
dependencies {
 | 
			
		||||
    implementation(project(":lib:unpacker"))
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								src/th/manhuathai/res/mipmap-hdpi/ic_launcher.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/th/manhuathai/res/mipmap-hdpi/ic_launcher.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 6.9 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/th/manhuathai/res/mipmap-mdpi/ic_launcher.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/th/manhuathai/res/mipmap-mdpi/ic_launcher.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 3.4 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/th/manhuathai/res/mipmap-xhdpi/ic_launcher.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/th/manhuathai/res/mipmap-xhdpi/ic_launcher.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 11 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/th/manhuathai/res/mipmap-xxhdpi/ic_launcher.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/th/manhuathai/res/mipmap-xxhdpi/ic_launcher.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 24 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/th/manhuathai/res/mipmap-xxxhdpi/ic_launcher.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/th/manhuathai/res/mipmap-xxxhdpi/ic_launcher.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 40 KiB  | 
@ -0,0 +1,122 @@
 | 
			
		||||
package eu.kanade.tachiyomi.extension.th.manhuathai
 | 
			
		||||
 | 
			
		||||
import android.graphics.Bitmap
 | 
			
		||||
import android.graphics.BitmapFactory
 | 
			
		||||
import android.graphics.Canvas
 | 
			
		||||
import android.graphics.Rect
 | 
			
		||||
import eu.kanade.tachiyomi.lib.unpacker.Unpacker
 | 
			
		||||
import eu.kanade.tachiyomi.multisrc.madara.Madara
 | 
			
		||||
import eu.kanade.tachiyomi.source.model.Page
 | 
			
		||||
import kotlinx.serialization.Serializable
 | 
			
		||||
import kotlinx.serialization.decodeFromString
 | 
			
		||||
import kotlinx.serialization.encodeToString
 | 
			
		||||
import okhttp3.Interceptor
 | 
			
		||||
import okhttp3.MediaType.Companion.toMediaType
 | 
			
		||||
import okhttp3.Response
 | 
			
		||||
import okhttp3.ResponseBody.Companion.toResponseBody
 | 
			
		||||
import org.jsoup.nodes.Document
 | 
			
		||||
import java.io.ByteArrayOutputStream
 | 
			
		||||
import java.text.SimpleDateFormat
 | 
			
		||||
import java.util.Locale
 | 
			
		||||
 | 
			
		||||
class ManhuaThai : Madara(
 | 
			
		||||
    "ManhuaThai",
 | 
			
		||||
    "https://www.manhuathai.com",
 | 
			
		||||
    "th",
 | 
			
		||||
    dateFormat = SimpleDateFormat("d MMMM yyyy", Locale("th")),
 | 
			
		||||
) {
 | 
			
		||||
    override val supportsLatest = false
 | 
			
		||||
 | 
			
		||||
    override val useLoadMoreRequest = LoadMoreStrategy.Never
 | 
			
		||||
    override val useNewChapterEndpoint = true
 | 
			
		||||
 | 
			
		||||
    override val filterNonMangaItems = false
 | 
			
		||||
 | 
			
		||||
    override val fetchGenres = false // While genres exist, they can't be used in standard Madara search
 | 
			
		||||
 | 
			
		||||
    // Descrambling logic from ManhuaKey
 | 
			
		||||
    override val client = super.client.newBuilder()
 | 
			
		||||
        .addNetworkInterceptor(::imageDescrambler)
 | 
			
		||||
        .build()
 | 
			
		||||
 | 
			
		||||
    override val pageListParseSelector = ".reading-content img, .reading-content div.displayImage + script:containsData(p,a,c,k,e,d)"
 | 
			
		||||
 | 
			
		||||
    override fun pageListParse(document: Document): List<Page> {
 | 
			
		||||
        launchIO { countViews(document) }
 | 
			
		||||
        val location = document.location()
 | 
			
		||||
 | 
			
		||||
        return document.select(pageListParseSelector).mapIndexed { idx, element ->
 | 
			
		||||
            if (element.tagName().equals("img")) {
 | 
			
		||||
                Page(idx, location, imageFromElement(element))
 | 
			
		||||
            } else {
 | 
			
		||||
                val unpackedScript = Unpacker.unpack(element.data())
 | 
			
		||||
                val blockWidth = blockWidthRegex.find(unpackedScript)!!.groupValues[1].toInt()
 | 
			
		||||
                val blockHeight = blockHeightRegex.find(unpackedScript)!!.groupValues[1].toInt()
 | 
			
		||||
                val matrix = unpackedScript.substringAfter("[")
 | 
			
		||||
                    .substringBefore("];")
 | 
			
		||||
                    .let { "[$it]" }
 | 
			
		||||
                val scrambledImageUrl = unpackedScript.substringAfter("url(")
 | 
			
		||||
                    .substringBefore(");")
 | 
			
		||||
 | 
			
		||||
                val data = ScramblingData(
 | 
			
		||||
                    blockWidth = blockWidth,
 | 
			
		||||
                    blockHeight = blockHeight,
 | 
			
		||||
                    matrix = json.decodeFromString(matrix),
 | 
			
		||||
                )
 | 
			
		||||
 | 
			
		||||
                Page(idx, location, "$scrambledImageUrl#${json.encodeToString(data)}")
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private val blockWidthRegex = Regex("""width:\s*"?\s*\+?\s*(\d+)\s*\+?\s*"?px;""")
 | 
			
		||||
    private val blockHeightRegex = Regex("""height:\s*"?\s*\+?\s*(\d+)\s*\+?\s*"?px;""")
 | 
			
		||||
 | 
			
		||||
    @Serializable
 | 
			
		||||
    class ScramblingData(
 | 
			
		||||
        val blockWidth: Int,
 | 
			
		||||
        val blockHeight: Int,
 | 
			
		||||
        val matrix: List<List<Double>>,
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    private fun imageDescrambler(chain: Interceptor.Chain): Response {
 | 
			
		||||
        val request = chain.request()
 | 
			
		||||
        val response = chain.proceed(request)
 | 
			
		||||
 | 
			
		||||
        if (request.url.fragment.isNullOrEmpty()) {
 | 
			
		||||
            return response
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        val scramblingData = json.decodeFromString<ScramblingData>(request.url.fragment!!)
 | 
			
		||||
 | 
			
		||||
        val scrambledImg = BitmapFactory.decodeStream(response.body.byteStream())
 | 
			
		||||
        val descrambledImg = Bitmap.createBitmap(scrambledImg.width, scrambledImg.height, Bitmap.Config.ARGB_8888)
 | 
			
		||||
        val canvas = Canvas(descrambledImg)
 | 
			
		||||
 | 
			
		||||
        for (pos in scramblingData.matrix) {
 | 
			
		||||
            val srcRect = Rect(
 | 
			
		||||
                pos[2].toInt(),
 | 
			
		||||
                pos[3].toInt(),
 | 
			
		||||
                pos[2].toInt() + scramblingData.blockWidth,
 | 
			
		||||
                pos[3].toInt() + scramblingData.blockHeight,
 | 
			
		||||
            )
 | 
			
		||||
            val destRect = Rect(
 | 
			
		||||
                pos[0].toInt(),
 | 
			
		||||
                pos[1].toInt(),
 | 
			
		||||
                pos[0].toInt() + scramblingData.blockWidth,
 | 
			
		||||
                pos[1].toInt() + scramblingData.blockHeight,
 | 
			
		||||
            )
 | 
			
		||||
            canvas.drawBitmap(scrambledImg, srcRect, destRect, null)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        val output = ByteArrayOutputStream()
 | 
			
		||||
        descrambledImg.compress(Bitmap.CompressFormat.JPEG, 90, output)
 | 
			
		||||
 | 
			
		||||
        val image = output.toByteArray()
 | 
			
		||||
        val body = image.toResponseBody("image/jpeg".toMediaType())
 | 
			
		||||
 | 
			
		||||
        return response.newBuilder()
 | 
			
		||||
            .body(body)
 | 
			
		||||
            .build()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user