Today I’m going to show you how to break ShonenJump+.
But before writing all that code, we’ll have to take a look at an example.
We can see that we might be able to unpuzzle this by just taking each pieces and putting them in their right place, and that’s what I tried to do, but some pieces where bigger than others.
So basically every panels on the website in unpuzzled by a javascript file but we’re not going to look at it ‘cause it’s too big.
What I did instead was searching on Github if anyone already had an idea on how to unpuzzle those because I’m a lazy man.
And I did found a lot of answers, and for this we’ll need 2 magic numbers.
multiplier = 8
and divider = 4
, We’ll need those to get values like the height of each rows and their width.
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.*
import java.awt.image.BufferedImage
import java.io.File
import java.io.InputStream
import java.net.URI
import javax.imageio.ImageIO
import kotlin.math.floor
fun BufferedImage.getRGB(x: Int, y: Int, width: Int, height: Int): IntArray = getRGB(x, y, width, height, null, 0, width)
fun BufferedImage.setRGB(x: Int, y: Int, width: Int, height: Int, rgbArray: IntArray) = setRGB(x, y, width, height, rgbArray, 0, width)
fun write(output: BufferedImage, name: String) = ImageIO.write(output, "png", File(name))
@Serializable
data class Page(val height: Int, val width: Int, val type: String, val src: String)
fun main(args: Array<String>) {
val url = if(args.isNotEmpty()) args[0] else {println("Enter your url"); readln()}
if(!url.endsWith(".json")) throw IllegalArgumentException("The URL doesn't ends with .json")
URI.create(url).toURL().openStream().use { getImages(it) }
}
private val json = Json { ignoreUnknownKeys = true }
@OptIn(ExperimentalSerializationApi::class)
fun getImages(it: InputStream) {
val pages = json.decodeFromStream<JsonObject>(it)["readableProduct"]!!
.jsonObject["pageStructure"]!!.jsonObject["pages"]!!.jsonArray
.map { it.jsonObject }.filter { it.containsKey("src") }
.map { json.decodeFromJsonElement<Page>(it) }
pages.forEachIndexed { index, page -> write(URI.create(page.src).toURL().openStream().use { getImage(it) }, "IMG-$index.png") }
}
fun getImage(`is`: InputStream): BufferedImage {
val img = ImageIO.read(`is`)
val w = img.width
val h = img.height
val output = BufferedImage(img.width, img.height, img.type)
val div = 4
val mult = 8
val colWidth = floor(w / (div * mult).toDouble()).toInt() * mult
val rowHeight = floor(h / (div * mult).toDouble()).toInt() * mult
output.setRGB(0, 0, w, h, img.getRGB(0,0, w, h))
for(col in 0..<div) {
for(row in 0..col) {
output.setRGB(row * colWidth, col * rowHeight, colWidth, rowHeight, img.getRGB(col * colWidth, row * rowHeight, colWidth, rowHeight))
if(col == row) continue
output.setRGB(col * colWidth, row * rowHeight, colWidth, rowHeight, img.getRGB(row * colWidth, col * rowHeight, colWidth, rowHeight))
}
}
return output
}