This repository has been archived by the owner on Jan 25, 2024. It is now read-only.
forked from CrackerCat/unidbg-fetch-qsign
-
Notifications
You must be signed in to change notification settings - Fork 101
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
17 changed files
with
656 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import com.tencent.mobileqq.dt.model.FEBound | ||
import io.ktor.serialization.kotlinx.json.* | ||
import io.ktor.server.application.* | ||
import io.ktor.server.engine.* | ||
import io.ktor.server.netty.* | ||
import io.ktor.server.plugins.contentnegotiation.* | ||
import io.ktor.server.plugins.statuspages.* | ||
import io.ktor.server.request.* | ||
import io.ktor.server.response.* | ||
import io.ktor.server.routing.* | ||
import kotlinx.serialization.json.Json | ||
import moe.fuqiuluo.api.* | ||
import moe.fuqiuluo.comm.CommonConfigExt | ||
import moe.fuqiuluo.comm.QSignConfig | ||
import moe.fuqiuluo.comm.checkIllegal | ||
import moe.fuqiuluo.comm.invoke | ||
import java.io.File | ||
|
||
private val API_LIST = arrayOf( | ||
Routing::index, | ||
Routing::sign, | ||
Routing::energy, | ||
Routing::submit, | ||
Routing::requestToken, | ||
Routing::register, | ||
) | ||
|
||
private val json1 = Json { | ||
encodeDefaults = true | ||
prettyPrint = true | ||
ignoreUnknownKeys = true | ||
} | ||
|
||
fun main(args: Array<String>) { | ||
val file = File("qsign.json") | ||
val s = if (file.exists()) file.readText() else "{}" | ||
val cfg = json1.decodeFromString(CommonConfigExt.serializer(), s) | ||
cfg.apply() | ||
file.writeText(json1.encodeToString(CommonConfigExt.serializer(), cfg)) | ||
|
||
args().also { | ||
val baseDir = File(it["basePath", "Lack of basePath."]).also { | ||
BASE_PATH = it | ||
} | ||
if (!baseDir.exists() || | ||
!baseDir.isDirectory || | ||
!baseDir.resolve("libfekit.so").exists() || | ||
!baseDir.resolve("config.json").exists() | ||
|| !baseDir.resolve("dtconfig.json").exists() | ||
) { | ||
error("The base path is invalid, perhaps it is not a directory or something is missing inside.") | ||
} else { | ||
val json = Json { ignoreUnknownKeys = true } | ||
FEBound.initAssertConfig(baseDir) | ||
println("FEBond sum = ${FEBound.checkCurrent()}") | ||
CONFIG = json.decodeFromString<QSignConfig>(baseDir.resolve("config.json").readText()) | ||
.apply { checkIllegal() } | ||
println("Load Package = ${CONFIG.protocol}") | ||
} | ||
} | ||
CONFIG.server.also { | ||
embeddedServer(Netty, host = it.host, port = it.port, module = Application::init) | ||
.start(wait = true) | ||
} | ||
|
||
} | ||
|
||
fun Application.init() { | ||
install(ContentNegotiation) { | ||
json(Json { | ||
prettyPrint = true | ||
isLenient = true | ||
ignoreUnknownKeys = true | ||
}) | ||
} | ||
install(StatusPages) { | ||
exception<Throwable> { call, cause -> | ||
if (CONFIG.unidbg.debug) { | ||
cause.printStackTrace() | ||
} | ||
call.respond(APIResult(1, cause.message ?: cause.javaClass.name, call.request.uri)) | ||
} | ||
} | ||
routing { | ||
API_LIST.forEach { it(this) } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package moe.fuqiuluo.api | ||
|
||
import io.ktor.server.application.* | ||
import io.ktor.server.response.* | ||
import io.ktor.server.routing.* | ||
import moe.fuqiuluo.ext.fetchGet | ||
import moe.fuqiuluo.ext.hex2ByteArray | ||
import moe.fuqiuluo.ext.toHexString | ||
|
||
fun Routing.energy() { | ||
get("/custom_energy") { | ||
val uin = fetchGet("uin")!!.toLong() | ||
val data = fetchGet("data")!! | ||
val salt = fetchGet("salt")!!.hex2ByteArray() | ||
|
||
val androidId = fetchGet("android_id", def = "") | ||
val guid = fetchGet("guid", def = "") | ||
val sign = kotlin.runCatching { | ||
UnidbgFetchQSign.customEnergy(uin, data, salt, androidId, guid) | ||
}.onFailure { | ||
it.printStackTrace() | ||
}.getOrNull() | ||
|
||
if (sign == null) { | ||
call.respond(APIResult(-1, "failed", null)) | ||
} else { | ||
call.respond(APIResult(0, "success", sign.toHexString())) | ||
} | ||
} | ||
|
||
get("/energy") { | ||
val uin = fetchGet("uin")!!.toLong() | ||
|
||
val data = fetchGet("data")!! | ||
val androidId = fetchGet("android_id", def = "") | ||
val guid = fetchGet("guid", def = null)?.hex2ByteArray() | ||
val version = fetchGet("version", def = null) | ||
val phone = fetchGet("phone", def = null)?.toByteArray() // 86-xxx | ||
val receipt = fetchGet("receipt", def = null)?.toByteArray() | ||
val sign = kotlin.runCatching { | ||
UnidbgFetchQSign.energy(uin, data, null, version, guid, androidId, phone, receipt) | ||
}.onFailure { | ||
it.printStackTrace() | ||
}.getOrNull() | ||
|
||
if (sign == null) { | ||
call.respond(APIResult(-1, "failed", null)) | ||
} else { | ||
call.respond(APIResult(0, "success", sign.toHexString())) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package moe.fuqiuluo.api | ||
|
||
object SessionNotFoundError : RuntimeException("Uin is not registered.") | ||
|
||
object WrongKeyError : RuntimeException("Wrong API key.") | ||
|
||
object MissingKeyError : RuntimeException("First use must be submitted with android_id and guid.") | ||
|
||
object BlackListError : RuntimeException("Blacklist uin.") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package moe.fuqiuluo.api | ||
|
||
import CONFIG | ||
import io.ktor.server.application.* | ||
import io.ktor.server.response.* | ||
import io.ktor.server.routing.* | ||
import kotlinx.serialization.Contextual | ||
import kotlinx.serialization.Serializable | ||
import moe.fuqiuluo.comm.Protocol | ||
import top.mrxiaom.qsign.BuildConstants | ||
import java.lang.management.ManagementFactory | ||
|
||
@Serializable | ||
data class APIResult<T>( | ||
val code: Int, | ||
val msg: String = "", | ||
@Contextual | ||
val data: T? = null | ||
) | ||
|
||
@Serializable | ||
data class APIInfo( | ||
val version: String, | ||
val protocol: Protocol, | ||
val pid: Int | ||
) | ||
|
||
fun Routing.index() { | ||
get("/") { | ||
call.respond( | ||
APIResult( | ||
0, "IAA 云天明 章北海 猫", APIInfo( | ||
version = BuildConstants.VERSION, | ||
protocol = CONFIG.protocol, | ||
pid = runCatching { ManagementFactory.getRuntimeMXBean().name.split("@")[0].toInt() }.getOrNull() | ||
?: -1 | ||
) | ||
) | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
package moe.fuqiuluo.api | ||
|
||
import CONFIG | ||
import com.tencent.mobileqq.channel.SsoPacket | ||
import io.ktor.server.application.* | ||
import io.ktor.server.request.* | ||
import io.ktor.server.response.* | ||
import io.ktor.server.routing.* | ||
import io.ktor.util.pipeline.* | ||
import kotlinx.serialization.Serializable | ||
import moe.fuqiuluo.ext.fetchGet | ||
import moe.fuqiuluo.ext.fetchPost | ||
import moe.fuqiuluo.ext.hex2ByteArray | ||
import moe.fuqiuluo.ext.toHexString | ||
|
||
fun Routing.sign() { | ||
get("/sign") { | ||
val uin = fetchGet("uin")!! | ||
val qua = fetchGet("qua", CONFIG.protocol.qua)!! | ||
val cmd = fetchGet("cmd")!! | ||
val seq = fetchGet("seq")!!.toInt() | ||
val buffer = fetchGet("buffer")!!.hex2ByteArray() | ||
val qimei36 = fetchGet("qimei36", def = "")!! | ||
|
||
val androidId = fetchGet("android_id", def = "")!! | ||
val guid = fetchGet("guid", def = "")!! | ||
|
||
requestSign(cmd, uin, qua, seq, buffer, qimei36, androidId, guid) | ||
} | ||
|
||
post("/sign") { | ||
val param = call.receiveParameters() | ||
val uin = fetchPost(param, "uin")!! | ||
val qua = fetchPost(param, "qua", CONFIG.protocol.qua)!! | ||
val cmd = fetchPost(param, "cmd")!! | ||
val seq = fetchPost(param, "seq")!!.toInt() | ||
val buffer = fetchPost(param, "buffer")!!.hex2ByteArray() | ||
val qimei36 = fetchPost(param, "qimei36", def = "")!! | ||
|
||
val androidId = param["android_id"] ?: "" | ||
val guid = param["guid"] ?: "" | ||
|
||
requestSign(cmd, uin, qua, seq, buffer, qimei36, androidId, guid) | ||
} | ||
} | ||
|
||
@Serializable | ||
private data class Sign( | ||
val token: String, | ||
val extra: String, | ||
val sign: String, | ||
val o3did: String, | ||
val requestCallback: List<SsoPacket> | ||
) | ||
|
||
private suspend fun PipelineContext<Unit, ApplicationCall>.requestSign( | ||
cmd: String, | ||
uin: String, | ||
qua: String, | ||
seq: Int, | ||
buffer: ByteArray, | ||
qimei36: String, | ||
androidId: String, | ||
guid: String | ||
) { | ||
val sign = runCatching { | ||
UnidbgFetchQSign.sign(cmd, uin.toLong(), seq, buffer, qua, qimei36, androidId, guid) | ||
}.onFailure { | ||
it.printStackTrace() | ||
}.getOrNull() | ||
|
||
if (sign == null) { | ||
call.respond(APIResult(-1, "failed", null)) | ||
} else { | ||
call.respond( | ||
APIResult( | ||
0, "success", Sign( | ||
sign.token.toHexString(), | ||
sign.extra.toHexString(), | ||
sign.sign.toHexString(), sign.o3did, sign.requestCallback | ||
) | ||
) | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package moe.fuqiuluo.api | ||
|
||
import CONFIG | ||
import io.ktor.server.application.* | ||
import io.ktor.server.response.* | ||
import io.ktor.server.routing.* | ||
import moe.fuqiuluo.ext.failure | ||
import moe.fuqiuluo.ext.fetchGet | ||
|
||
fun Routing.register() { | ||
get("/register") { | ||
val uin = fetchGet("uin")!!.toLong() | ||
val androidId = fetchGet("android_id")!! | ||
val guid = fetchGet("guid")!!.lowercase() | ||
val qimei36 = fetchGet("qimei36")!!.lowercase() | ||
|
||
val key = fetchGet("key")!! | ||
|
||
val qua = fetchGet("qua", CONFIG.protocol.qua)!! | ||
val version = fetchGet("version", CONFIG.protocol.version)!! | ||
val code = fetchGet("code", CONFIG.protocol.code)!! | ||
|
||
if (key == CONFIG.key) { | ||
if (UnidbgFetchQSign.register(uin, androidId, guid, qimei36, qua, version, code)) { | ||
call.respond( | ||
APIResult( | ||
0, | ||
"The QQ has already loaded an instance, so this time it is deleting the existing instance and creating a new one.", | ||
"" | ||
) | ||
) | ||
} else { | ||
call.respond(APIResult(0, "Instance loaded successfully.", "")) | ||
} | ||
} else { | ||
throw WrongKeyError | ||
} | ||
} | ||
|
||
get("/destroy") { | ||
val uin = fetchGet("uin")!!.toLong() | ||
val key = fetchGet("key")!! | ||
|
||
if (key == CONFIG.key) { | ||
if (UnidbgFetchQSign.destroy(uin)) { | ||
call.respond(APIResult(0, "Instance destroyed successfully.", "")) | ||
} else { | ||
failure(1, "Instance does not exist.") | ||
} | ||
} else { | ||
throw WrongKeyError | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
@file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER") | ||
|
||
package moe.fuqiuluo.api | ||
|
||
import io.ktor.server.application.* | ||
import io.ktor.server.response.* | ||
import io.ktor.server.routing.* | ||
import moe.fuqiuluo.ext.fetchGet | ||
|
||
fun Routing.requestToken() { | ||
get("/request_token") { | ||
val uin = fetchGet("uin")!!.toLong() | ||
val isForced = fetchGet("force", def = "false") | ||
|
||
val pair = runCatching { | ||
UnidbgFetchQSign.requestToken(uin, isForced == "true") | ||
}.onFailure { | ||
call.respond(APIResult(-1, it.message.toString(), "")) | ||
}.getOrNull() ?: return@get | ||
|
||
val isSuccessful = pair.first | ||
val list = pair.second | ||
|
||
call.respond( | ||
APIResult( | ||
if (!isSuccessful) -1 else 0, | ||
if (!isSuccessful) "request_token timeout" else "submit success", | ||
list | ||
) | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package moe.fuqiuluo.api | ||
|
||
import io.ktor.server.application.* | ||
import io.ktor.server.response.* | ||
import io.ktor.server.routing.* | ||
import moe.fuqiuluo.ext.fetchGet | ||
import moe.fuqiuluo.ext.hex2ByteArray | ||
|
||
|
||
fun Routing.submit() { | ||
get("/submit") { | ||
val uin = fetchGet("uin")!!.toLong() | ||
val cmd = fetchGet("cmd")!! | ||
val callbackId = fetchGet("callback_id")!!.toLong() | ||
val buffer = fetchGet("buffer")!!.hex2ByteArray() | ||
val androidId = fetchGet("android_id", def = "")!! | ||
val guid = fetchGet("guid", def = "")!!.lowercase() | ||
val qimei36 = fetchGet("qimei36", def = "")!!.lowercase() | ||
|
||
UnidbgFetchQSign.submit(uin, cmd, callbackId, buffer, androidId, guid, qimei36) | ||
|
||
call.respond(APIResult(0, "submit success", "")) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package moe.fuqiuluo.comm | ||
|
||
import moe.fuqiuluo.ext.StringArray | ||
|
||
class ArgsParser( | ||
args: StringArray | ||
) { | ||
private val map = hashMapOf<String, String>() | ||
|
||
init { | ||
args.forEach { | ||
it.substring( | ||
if (it.startsWith("--")) 2 | ||
else if (it.startsWith("-")) 1 | ||
else error("Not support the expr.") | ||
).split("=").also { | ||
map[it[0]] = it.slice(1 until it.size).joinToString("") | ||
} | ||
} | ||
} | ||
|
||
operator fun get(key: String): String? { | ||
return map[key] | ||
} | ||
|
||
fun getOrDefault(key: String, def: String?): String? { | ||
return get(key) ?: def | ||
} | ||
|
||
operator fun get(key: String, err: String): String { | ||
require(key in this) { err } | ||
return this[key]!! | ||
} | ||
|
||
operator fun contains(key: String): Boolean { | ||
return key in map | ||
} | ||
} | ||
|
||
operator fun StringArray.invoke(): ArgsParser { | ||
return ArgsParser(this) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package moe.fuqiuluo.comm | ||
|
||
import kotlinx.serialization.Serializable | ||
import top.mrxiaom.qsign.CommonConfig | ||
import java.io.File | ||
|
||
@Serializable | ||
data class CommonConfigExt( | ||
var virtualRootPath: String = "virtualRoot", | ||
var appInstallFolder: String = "/data/app/~~nNzv5koU9DgkrbtCpa02wQ==/\${packageName}-fR9VqAFGIZNVZ8MgZYh0Ow==", | ||
var screenSizeWidth: Int = 1080, | ||
var screenSizeHeight: Int = 2400, | ||
var density: String = "2.75", | ||
var serialNumber: String = "0x0000043be8571339", | ||
var androidVersion: String = "13", | ||
var androidSdkVersion: Int = 33, | ||
var targetSdkVersion: Int = 29, | ||
var storageSize: String = "137438953471" | ||
) { | ||
fun apply() = CommonConfig.also { | ||
it.virtualRootPath = File(virtualRootPath) | ||
it.appInstallFolder = appInstallFolder | ||
it.screenSizeWidth = screenSizeWidth | ||
it.screenSizeHeight = screenSizeHeight | ||
it.density = density | ||
it.serialNumber = serialNumber | ||
it.androidVersion = androidVersion | ||
it.androidSdkVersion = androidSdkVersion | ||
it.targetSdkVersion = targetSdkVersion | ||
it.storageSize = storageSize | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
package moe.fuqiuluo.ext | ||
|
||
import com.tencent.crypt.Crypt | ||
import io.ktor.utils.io.core.* | ||
import moe.fuqiuluo.utils.BytesUtil | ||
import kotlin.text.Charsets.UTF_8 | ||
import kotlin.text.toByteArray | ||
|
||
inline fun newBuilder() = BytePacketBuilder() | ||
|
||
fun BytePacketBuilder.writeBytes(bytes: ByteArray) = this.writeFully(bytes) | ||
|
||
fun BytePacketBuilder.toByteArray(): ByteArray = use { it.build().readBytes() } | ||
|
||
fun ByteReadPacket.toByteArray(): ByteArray = use { it.readBytes() } | ||
|
||
/** | ||
* 补充功能代码 | ||
* @receiver BytePacketBuilder | ||
* @param packet BytePacketBuilder | ||
*/ | ||
fun BytePacketBuilder.writePacket(packet: BytePacketBuilder) = this.writePacket(packet.build()) | ||
|
||
/** | ||
* 写布尔型 | ||
* @receiver BytePacketBuilder | ||
* @param z Boolean | ||
*/ | ||
fun BytePacketBuilder.writeBoolean(z: Boolean) = this.writeByte(if (z) 1 else 0) | ||
|
||
/** | ||
* 自动转换类型 | ||
* @receiver BytePacketBuilder | ||
* @param i Int | ||
*/ | ||
fun BytePacketBuilder.writeShort(i: Int) = this.writeShort(i.toShort()) | ||
|
||
fun BytePacketBuilder.writeLongToBuf32(v: Long) { | ||
this.writeBytes(BytesUtil.int64ToBuf32(v)) | ||
} | ||
|
||
fun BytePacketBuilder.writeStringWithIntLen(str: String) { | ||
writeBytesWithIntLen(str.toByteArray()) | ||
} | ||
|
||
fun BytePacketBuilder.writeStringWithShortLen(str: String) { | ||
writeBytesWithShortLen(str.toByteArray()) | ||
} | ||
|
||
fun BytePacketBuilder.writeBytesWithIntLen(bytes: ByteArray) { | ||
writeInt(bytes.size) | ||
writeBytes(bytes) | ||
} | ||
|
||
fun BytePacketBuilder.writeBytesWithShortLen(bytes: ByteArray) { | ||
check(bytes.size <= Short.MAX_VALUE) { "byteArray length is too long" } | ||
writeShort(bytes.size.toShort()) | ||
writeBytes(bytes) | ||
} | ||
|
||
inline fun BytePacketBuilder.writeBlockWithIntLen(len: (Int) -> Int = { it }, block: BytePacketBuilder.() -> Unit) { | ||
val builder = newBuilder() | ||
builder.block() | ||
this.writeInt(len(builder.size)) | ||
this.writePacket(builder) | ||
builder.close() | ||
} | ||
|
||
inline fun BytePacketBuilder.writeBlockWithShortLen(len: (Int) -> Int = { it }, block: BytePacketBuilder.() -> Unit) { | ||
val builder = newBuilder() | ||
builder.block() | ||
this.writeShort(len(builder.size)) | ||
this.writePacket(builder) | ||
builder.close() | ||
} | ||
|
||
|
||
inline fun BytePacketBuilder.writeTeaEncrypt(key: ByteArray, block: BytePacketBuilder.() -> Unit) { | ||
val body = newBuilder() | ||
body.block() | ||
this.writeBytes(Crypt().encrypt(body.toByteArray(), key)) | ||
body.close() | ||
} | ||
|
||
fun BytePacketBuilder.writeString(str: String) { | ||
this.writeBytes(str.toByteArray(UTF_8)) | ||
} | ||
|
||
fun BytePacketBuilder.writeHex(uHex: String) { | ||
writeBytes(uHex.hex2ByteArray()) | ||
} | ||
|
||
fun ByteReadPacket.readString(length: Int) = readBytes(length).decodeToString() | ||
|
||
fun ByteArray.toByteReadPacket() = ByteReadPacket(this) | ||
|
||
inline fun ByteArray.reader(block: ByteReadPacket.() -> Unit) { | ||
this.toByteReadPacket().use(block) | ||
} | ||
|
||
fun ByteReadPacket.readByteReadPacket(length: Int): ByteReadPacket { | ||
return readBytes(length).toByteReadPacket() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package moe.fuqiuluo.ext | ||
|
||
import io.ktor.http.* | ||
import io.ktor.server.application.* | ||
import io.ktor.server.response.* | ||
import io.ktor.util.pipeline.* | ||
import moe.fuqiuluo.api.APIResult | ||
|
||
suspend fun PipelineContext<Unit, ApplicationCall>.fetchGet( | ||
key: String, | ||
def: String? = null, | ||
err: String? = "Parameter '$key' is missing." | ||
): String? { | ||
val data = call.parameters[key] ?: def | ||
if (data == null && err != null) { | ||
failure(1, err) | ||
} | ||
return data | ||
} | ||
|
||
suspend fun PipelineContext<Unit, ApplicationCall>.fetchPost( | ||
params: Parameters, | ||
key: String, | ||
def: String? = null, | ||
err: String? = "Parameter '$key' is missing." | ||
): String? { | ||
val data = params[key] ?: def | ||
if (data == null && err != null) { | ||
failure(1, err) | ||
} | ||
return data | ||
} | ||
|
||
suspend fun PipelineContext<Unit, ApplicationCall>.failure(code: Int, msg: String) { | ||
call.respond(APIResult(code, msg, "failed")) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package moe.fuqiuluo.ext | ||
|
||
fun String.toInt(range: IntRange, lazyMessage: () -> Any = { "Failed requirement." }): Int { | ||
val i = toInt() | ||
require(i in range, lazyMessage) | ||
return i | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
package moe.fuqiuluo.ext | ||
|
||
typealias StringArray = Array<String> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package moe.fuqiuluo.ext | ||
|
||
import com.github.unidbg.linux.android.dvm.BaseVM | ||
import com.github.unidbg.linux.android.dvm.DvmObject | ||
|
||
fun BaseVM.newInstance(className: String, arg: Any? = null): DvmObject<*> { | ||
return resolveClass(className).newObject(arg) | ||
} |