1
0
mirror of https://github.com/mamoe/mirai.git synced 2025-04-05 07:10:11 +08:00

Implement ByteArrayOp

This commit is contained in:
Him188 2022-05-26 22:36:17 +01:00
parent 17430857a8
commit a1832a4de7
No known key found for this signature in database
GPG Key ID: BA439CDDCF652375
22 changed files with 462 additions and 108 deletions
buildSrc/src/main/kotlin
mirai-core-utils/src
mirai-core/src
commonMain/kotlin
message/protocol/impl
network
components
protocol/data/proto
commonTest/kotlin

View File

@ -18,6 +18,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeCompilation
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType
import java.io.File
private val miraiPlatform = Attribute.of(
@ -133,7 +134,8 @@ private fun Project.configureNativeInterop(
nativeTargets: MutableList<KotlinNativeTarget>
) {
if (nativeInteropDir.exists() && nativeInteropDir.isDirectory && nativeInteropDir.resolve("build.rs").exists()) {
val crateName = project.name.replace("-", "_")
val crateName = project.name.replace("-", "_") + "_i"
val kotlinDylibName = project.name.replace("-", "_")
val headerName = "$crateName.h"
val rustLibDir = nativeInteropDir.resolve("target/debug/")
@ -149,10 +151,16 @@ private fun Project.configureNativeInterop(
sharedLib {
linkerOpts("-v")
linkerOpts("-L${rustLibDir.absolutePath.replace("\\", "/")}")
// linkerOpts("-lmyrust")
linkerOpts("-Wl,-undefined,dynamic_lookup") // resolve symbols in runtime
// linkerOpts("-lmirai_core_utils_i")
linkerOpts("-undefined", "dynamic_lookup")
baseName = project.name
}
getTest(NativeBuildType.DEBUG).apply {
linkerOpts("-v")
linkerOpts("-L${rustLibDir.absolutePath.replace("\\", "/")}")
linkerOpts("-lmirai_core_utils_i")
// linkerOpts("-undefined", "dynamic_lookup")
}
}
}
@ -190,7 +198,7 @@ private fun Project.configureNativeInterop(
val bindgen = tasks.register("bindgen${compilationName.titlecase()}") {
group = "mirai"
val bindingsPath = nativeInteropDir.resolve("src/bindings.rs")
val headerFile = buildDir.resolve("bin/native/debugShared/lib${crateName}_api.h")
val headerFile = buildDir.resolve("bin/native/debugShared/lib${kotlinDylibName}_api.h")
inputs.files(headerFile)
outputs.file(bindingsPath)
mustRunAfter(tasks.findByName("linkDebugSharedNative"))
@ -239,7 +247,7 @@ private fun Project.configureNativeInterop(
"build",
"--color", "always",
"--all",
"--", "--color", "always", "2>&1"
// "--", "--color", "always", "2>&1"
)
}
}

View File

@ -7,28 +7,15 @@
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
@file:JvmMultifileClass
@file:JvmName("MiraiUtils")
@file:JvmName("ByteArrayOpKt_common")
package net.mamoe.mirai.utils
import io.ktor.utils.io.core.*
import io.ktor.utils.io.core.Closeable
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName
public expect val DEFAULT_BUFFER_SIZE: Int
public expect fun ByteArray.unzip(offset: Int = 0, length: Int = size - offset): ByteArray
/**
* Localhost 解析
*/
public expect fun localIpAddress(): String
public fun String.md5(): ByteArray = toByteArray().md5()
public expect fun ByteArray.md5(offset: Int = 0, length: Int = size - offset): ByteArray
@ -37,24 +24,8 @@ public fun String.sha1(): ByteArray = toByteArray().sha1()
public expect fun ByteArray.sha1(offset: Int = 0, length: Int = size - offset): ByteArray
public expect fun ByteArray.gzip(offset: Int = 0, length: Int = size - offset): ByteArray
public expect fun ByteArray.ungzip(offset: Int = 0, length: Int = size - offset): ByteArray
public expect fun ByteArray.gzip(offset: Int = 0, length: Int = size - offset): ByteArray
public expect fun ByteArray.zip(offset: Int = 0, length: Int = size - offset): ByteArray
public expect fun availableProcessors(): Int
public inline fun <C : Closeable, R> C.withUse(block: C.() -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return use(block)
}
public inline fun <I : Closeable, O : Closeable, R> I.withOut(output: O, block: I.(output: O) -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return use { output.use { block(this, output) } }
}
public expect fun ByteArray.inflate(offset: Int = 0, length: Int = size - offset): ByteArray
public expect fun ByteArray.deflate(offset: Int = 0, length: Int = size - offset): ByteArray

View File

@ -18,6 +18,8 @@ import io.ktor.utils.io.*
import io.ktor.utils.io.charsets.*
import io.ktor.utils.io.core.*
import io.ktor.utils.io.core.internal.*
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName
import kotlin.jvm.JvmSynthetic
@ -27,6 +29,20 @@ public val EMPTY_BYTE_ARRAY: ByteArray = ByteArray(0)
public val DECRYPTER_16_ZERO: ByteArray = ByteArray(16)
public val KEY_16_ZEROS: ByteArray = ByteArray(16)
public inline fun <C : Closeable, R> C.withUse(block: C.() -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return use(block)
}
public inline fun <I : Closeable, O : Closeable, R> I.withOut(output: O, block: I.(output: O) -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return use { output.use { block(this, output) } }
}
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
public inline fun <R> ByteReadPacket.useBytes(
n: Int = remaining.toInt(),//not that safe but adequate

View File

@ -166,4 +166,12 @@ public inline fun <reified T> isSameType(thisObject: T, other: Any?): Boolean {
if (other == null) return false
if (other !is T) return false
return isSameClass(thisObject, other)
}
}
public expect fun availableProcessors(): Int
/**
* Localhost 解析
*/
public expect fun localIpAddress(): String

View File

@ -12,11 +12,9 @@
package net.mamoe.mirai.utils
import io.ktor.utils.io.core.*
import java.io.ByteArrayOutputStream
import java.io.InputStream
import java.io.OutputStream
import java.net.Inet4Address
import java.security.MessageDigest
import java.util.zip.Deflater
import java.util.zip.GZIPInputStream
@ -25,7 +23,7 @@ import java.util.zip.Inflater
public actual val DEFAULT_BUFFER_SIZE: Int get() = kotlin.io.DEFAULT_BUFFER_SIZE
public actual fun ByteArray.unzip(offset: Int, length: Int): ByteArray {
public actual fun ByteArray.inflate(offset: Int, length: Int): ByteArray {
checkOffsetAndLength(offset, length)
if (length == 0) return ByteArray(0)
@ -44,10 +42,6 @@ public actual fun ByteArray.unzip(offset: Int, length: Int): ByteArray {
}
}
public actual fun localIpAddress(): String = runCatching {
Inet4Address.getLocalHost().hostAddress
}.getOrElse { "192.168.1.123" }
public fun InputStream.md5(): ByteArray {
return digest("md5")
}
@ -104,7 +98,7 @@ public actual fun ByteArray.gzip(offset: Int, length: Int): ByteArray {
}
@JvmOverloads
public actual fun ByteArray.zip(offset: Int, length: Int): ByteArray {
public actual fun ByteArray.deflate(offset: Int, length: Int): ByteArray {
checkOffsetAndLength(offset, length)
if (length == 0) return ByteArray(0)
@ -117,4 +111,3 @@ public actual fun ByteArray.zip(offset: Int, length: Int): ByteArray {
}
}
public actual fun availableProcessors(): Int = Runtime.getRuntime().availableProcessors()

View File

@ -9,6 +9,14 @@
package net.mamoe.mirai.utils
import java.net.Inet4Address
internal actual fun isSameClassPlatform(object1: Any, object2: Any): Boolean {
return object1.javaClass == object2.javaClass
}
}
public actual fun localIpAddress(): String = runCatching {
Inet4Address.getLocalHost().hostAddress
}.getOrElse { "192.168.1.123" }
public actual fun availableProcessors(): Int = Runtime.getRuntime().availableProcessors()

View File

@ -0,0 +1,54 @@
/*
* Copyright 2019-2022 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
@file:Suppress("RedundantVisibilityModifier")
package net.mamoe.mirai.utils
import interop.*
import kotlinx.cinterop.*
import platform.posix.free
import platform.posix.uint8_tVar
public actual val DEFAULT_BUFFER_SIZE: Int get() = 8192
public actual fun ByteArray.md5(offset: Int, length: Int): ByteArray = callImpl(::mirai_crypto_md5, offset, length)
public actual fun ByteArray.sha1(offset: Int, length: Int): ByteArray = callImpl(::mirai_crypto_sha1, offset, length)
public actual fun ByteArray.gzip(offset: Int, length: Int): ByteArray = callImpl(::mirai_crypto_gzip, offset, length)
public actual fun ByteArray.ungzip(offset: Int, length: Int): ByteArray =
callImpl(::mirai_crypto_ungzip, offset, length)
public actual fun ByteArray.deflate(offset: Int, length: Int): ByteArray =
callImpl(::mirai_crypto_deflate, offset, length)
public actual fun ByteArray.inflate(offset: Int, length: Int): ByteArray =
callImpl(::mirai_crypto_inflate, offset, length)
private fun ByteArray.callImpl(
fn: (CValuesRef<uint8_tVar>, UInt, CValuesRef<SizedByteArray>) -> Boolean,
offset: Int,
length: Int
): ByteArray {
checkOffsetAndLength(offset, length)
memScoped {
val r = alloc<SizedByteArray>()
if (!fn(toCValues().ptr.reinterpret<uint8_tVar>().plus(offset)!!, length.toUInt(), r.ptr)) {
throw IllegalStateException("Failed platform implementation call")
}
try {
return r.arr?.readBytes(r.size.toInt())!!
} finally {
free(r.arr)
}
}
}

View File

@ -1,46 +0,0 @@
/*
* Copyright 2019-2022 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
@file:Suppress("RedundantVisibilityModifier")
package net.mamoe.mirai.utils
public actual fun ByteArray.unzip(offset: Int, length: Int): ByteArray {
TODO("Not yet implemented")
}
public actual fun localIpAddress(): String = "192.168.1.123"
public actual fun ByteArray.md5(offset: Int, length: Int): ByteArray {
TODO("Not yet implemented")
}
public actual val DEFAULT_BUFFER_SIZE: Int get() = 8192
public actual fun ByteArray.sha1(offset: Int, length: Int): ByteArray {
TODO("Not yet implemented")
}
public actual fun ByteArray.ungzip(offset: Int, length: Int): ByteArray {
TODO("Not yet implemented")
}
public actual fun ByteArray.gzip(offset: Int, length: Int): ByteArray {
TODO("Not yet implemented")
}
public actual fun ByteArray.zip(offset: Int, length: Int): ByteArray {
TODO("Not yet implemented")
}
public actual fun availableProcessors(): Int {
TODO("Not yet implemented")
}

View File

@ -9,6 +9,6 @@
package net.mamoe.mirai.utils
internal actual fun isSameClassPlatform(object1: Any, object2: Any): Boolean {
return object1::class == object2::class
public fun symbolNotFound(name: String): Nothing {
throw IllegalStateException("Symbol '$name' not found.")
}

View File

@ -0,0 +1,22 @@
/*
* Copyright 2019-2022 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
package net.mamoe.mirai.utils
import platform.posix._SC_NPROCESSORS_ONLN
import platform.posix.sysconf
public actual fun localIpAddress(): String = "192.168.1.123"
public actual fun availableProcessors(): Int = sysconf(_SC_NPROCESSORS_ONLN).toInt()
internal actual fun isSameClassPlatform(object1: Any, object2: Any): Boolean {
return object1::class == object2::class
}

View File

@ -0,0 +1,8 @@
/target
Cargo.lock
myrust.h
*.iml
src/bindings.rs
/*.h

View File

@ -0,0 +1,18 @@
[package]
name = "mirai_core_utils_i"
version = "0.1.0"
[dependencies]
md5 = "0.7.0"
sha1 = "0.10.1"
flate2 = "1.0.23"
libc = "0.2.126"
[lib]
name = "mirai_core_utils_i"
crate-type = ["cdylib"] # Creates dynamic lib
# crate-type = ["staticlib"] # Creates static lib
[build-dependencies]
bindgen = "0.53.1"
cbindgen = "0.20.0"

View File

@ -0,0 +1,32 @@
/*
* Copyright 2019-2022 Mamoe Technologies and contributors.
*
* 使 GNU AFFERO GENERAL PUBLIC LICENSE version 3 , .
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
extern crate bindgen;
extern crate cbindgen;
use std::env;
use std::path::PathBuf;
use cbindgen::Config;
use cbindgen::Language::C;
fn main() {
// let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
// cbindgen::Builder::new()
// .with_crate(crate_dir)
// .with_language(C)
// .generate()
// .expect("Unable to generate bindings")
// .write_to_file("nativeInterop.h");
println!("cargo:rustc-link-search=../../build/bin/native/debugShared");
println!("cargo:rustc-link-lib=mirai_core_utils");
}

View File

@ -0,0 +1,10 @@
# This is a template cbindgen.toml file with all of the default values.
# Some values are commented out because their absence is the real default.
#
# See https://github.com/eqrion/cbindgen/blob/master/docs.md#cbindgentoml
# for detailed documentation of every option here.
language = "C"

View File

@ -0,0 +1,125 @@
/*
* Copyright 2019-2022 Mamoe Technologies and contributors.
*
* 使 GNU AFFERO GENERAL PUBLIC LICENSE version 3 , .
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
use std::io::{BufReader, Read, Write};
use flate2::Compression;
use flate2::write::{DeflateDecoder, DeflateEncoder, GzDecoder, GzEncoder, ZlibDecoder, ZlibEncoder};
use libc::{malloc, read, size_t};
use sha1::{Digest, Sha1};
use sha1::digest::{Output, OutputSizeUser};
use sha1::digest::generic_array::GenericArray;
#[no_mangle]
#[repr(C)]
pub struct SizedByteArray {
arr: *mut u8,
size: u32,
}
#[no_mangle]
pub unsafe extern "C" fn mirai_crypto_md5(data: *const u8, len: u32, ret: &mut SizedByteArray) -> bool {
let data = unsafe { std::slice::from_raw_parts(data, len as usize) };
let result = md5::compute(data);
let size = 16;
let mut memory = malloc(size).cast();
memory.copy_from(result.as_ptr(), size);
ret.arr = memory;
ret.size = size as u32;
return true;
}
#[no_mangle]
pub unsafe extern "C" fn mirai_crypto_sha1(data: *const u8, len: u32, ret: &mut SizedByteArray) -> bool {
let data = unsafe { std::slice::from_raw_parts(data, len as usize) };
let mut hasher = Sha1::new();
hasher.update(data);
let result = hasher.finalize();
let size = 16;
let mut memory = malloc(size).cast();
memory.copy_from(result.as_ptr(), size);
ret.arr = memory;
ret.size = size as u32;
return true;
}
#[no_mangle]
pub unsafe extern "C" fn mirai_crypto_gzip(data: *const u8, len: u32, ret: &mut SizedByteArray) -> bool {
let data = unsafe { std::slice::from_raw_parts(data, len as usize) };
let mut encoder = GzEncoder::new(Vec::new(), Compression::default());
let result = encoder.write_all(data).and_then(|_| { encoder.finish() });
if result.is_err() { return false; }
let result = result.unwrap();
let size = result.len();
let mut memory = malloc(size).cast();
memory.copy_from(result.as_ptr(), size);
ret.arr = memory;
ret.size = size as u32;
return true;
}
#[no_mangle]
pub unsafe extern "C" fn mirai_crypto_ungzip(data: *const u8, len: u32, ret: &mut SizedByteArray) -> bool {
let data = unsafe { std::slice::from_raw_parts(data, len as usize) };
let mut encoder = GzDecoder::new(Vec::new());
let result = encoder.write_all(data).and_then(|_| { encoder.finish() });
if result.is_err() { return false; }
let result = result.unwrap();
let size = result.len();
let mut memory = malloc(size).cast();
memory.copy_from(result.as_ptr(), size);
ret.arr = memory;
ret.size = size as u32;
return true;
}
#[no_mangle]
pub unsafe extern "C" fn mirai_crypto_deflate(data: *const u8, len: u32, ret: &mut SizedByteArray) -> bool {
let data = unsafe { std::slice::from_raw_parts(data, len as usize) };
let mut encoder = ZlibEncoder::new(Vec::new(), Compression::default());
let result = encoder.write_all(data).and_then(|_| { encoder.finish() });
if result.is_err() { return false; }
let result = result.unwrap();
let size = result.len();
let mut memory = malloc(size).cast();
memory.copy_from(result.as_ptr(), size);
ret.arr = memory;
ret.size = size as u32;
return true;
}
#[no_mangle]
pub unsafe extern "C" fn mirai_crypto_inflate(data: *const u8, len: u32, ret: &mut SizedByteArray) -> bool {
let data = unsafe { std::slice::from_raw_parts(data, len as usize) };
let mut encoder = ZlibDecoder::new(Vec::new());
let result = encoder.write_all(data).and_then(|_| { encoder.finish() });
if result.is_err() { return false; }
let result = result.unwrap();
let size = result.len();
let mut memory = malloc(size).cast();
memory.copy_from(result.as_ptr(), size);
ret.arr = memory;
ret.size = size as u32;
return true;
}

View File

@ -0,0 +1,17 @@
/*
* Copyright 2019-2022 Mamoe Technologies and contributors.
*
* 使 GNU AFFERO GENERAL PUBLIC LICENSE version 3 , .
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
extern crate flate2;
extern crate libc;
extern crate sha1;
/// cbindgen:ignore
mod bindings;
mod crypto;

View File

@ -0,0 +1,110 @@
/*
* Copyright 2019-2022 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
package net.mamoe.mirai.utils
import io.ktor.utils.io.core.*
import kotlin.random.Random
import kotlin.test.Test
import kotlin.test.assertContentEquals
import kotlin.test.assertEquals
import kotlin.test.assertTrue
class CryptoTest {
@Test
fun testAvailableProcessors() {
val processors = availableProcessors()
assertTrue(processors.toString()) { processors > 0 }
}
@Test
fun testMd5() {
val str = getRandomString(10, Random(1))
println(str)
val hash = str.md5()
assertContentEquals(
"30 3B 36 B3 42 00 39 E2 EC 18 22 79 10 32 05 48".hexToBytes(),
hash,
message = hash.toUHexString()
)
}
@Test
fun testMd5WithOffset() {
val str = getRandomString(10, Random(1))
println(str)
val hash = (byteArrayOf(1) + str.toByteArray()).md5(1)
assertContentEquals(
"30 3B 36 B3 42 00 39 E2 EC 18 22 79 10 32 05 48".hexToBytes(),
hash,
message = hash.toUHexString()
)
}
@Test
fun testSha1() {
val str = getRandomString(10, Random(1))
println(str)
val hash = str.sha1()
assertContentEquals(
"54 98 CD 62 6C DE E3 9B 96 D4 34 5E 13 51 48 BB".hexToBytes(),
hash,
message = hash.toUHexString()
)
}
@Test
fun testDeflate() {
val str = "qGnJ1RrFC9"
println(str)
val hash = str.toByteArray().deflate()
assertContentEquals(
"78 9C 2B 74 CF F3 32 0C 2A 72 73 B6 04 00 12 82 03 28".hexToBytes(),
hash,
message = hash.toUHexString()
)
}
@Test
fun testInflate() {
val result =
"78 9C 2B 74 CF F3 32 0C 2A 72 73 B6 04 00 12 82 03 28".hexToBytes()
.inflate().decodeToString()
assertEquals(
"qGnJ1RrFC9",
result,
message = result
)
}
@Test
fun testGzip() {
val str = "qGnJ1RrFC9"
println(str)
val hash = str.toByteArray().gzip()
assertContentEquals(
"1F 8B 08 00 00 00 00 00 00 FF 2B 74 CF F3 32 0C 2A 72 73 B6 04 00 A8 35 6D D9 0A 00 00 00".hexToBytes(),
hash,
message = hash.toUHexString()
)
}
@Test
fun testUnGzip() {
val result =
"1F 8B 08 00 00 00 00 00 00 FF 2B 74 CF F3 32 0C 2A 72 73 B6 04 00 A8 35 6D D9 0A 00 00 00".hexToBytes()
.ungzip().decodeToString()
assertEquals(
"qGnJ1RrFC9",
result,
message = result
)
}
}

View File

@ -23,10 +23,10 @@ import net.mamoe.mirai.internal.message.protocol.encode.MessageEncoderContext.Co
import net.mamoe.mirai.internal.message.runWithBugReport
import net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody
import net.mamoe.mirai.message.data.*
import net.mamoe.mirai.utils.deflate
import net.mamoe.mirai.utils.hexToBytes
import net.mamoe.mirai.utils.inflate
import net.mamoe.mirai.utils.toUHexString
import net.mamoe.mirai.utils.unzip
import net.mamoe.mirai.utils.zip
/**
* Handles:
@ -50,7 +50,7 @@ internal class RichMessageProtocol : MessageProtocol() {
private class Encoder : MessageEncoder<RichMessage> {
override suspend fun MessageEncoderContext.process(data: RichMessage) {
markAsConsumed()
val content = data.content.toByteArray().zip()
val content = data.content.toByteArray().deflate()
var longTextResId: String? = null
when (data) {
is ForwardMessageInternal -> {
@ -127,7 +127,7 @@ internal class RichMessageProtocol : MessageProtocol() {
{ "resId=" + lightApp.msgResid + "data=" + lightApp.data.toUHexString() }) {
when (lightApp.data[0].toInt()) {
0 -> lightApp.data.decodeToString(startIndex = 1)
1 -> lightApp.data.unzip(1).decodeToString()
1 -> lightApp.data.inflate(1).decodeToString()
else -> error("unknown compression flag=${lightApp.data[0]}")
}
}
@ -146,7 +146,7 @@ internal class RichMessageProtocol : MessageProtocol() {
val content = runWithBugReport("解析 richMsg", { richMsg.template1.toUHexString() }) {
when (richMsg.template1[0].toInt()) {
0 -> richMsg.template1.decodeToString(startIndex = 1)
1 -> richMsg.template1.unzip(1).decodeToString()
1 -> richMsg.template1.inflate(1).decodeToString()
else -> error("unknown compression flag=${richMsg.template1[0]}")
}
}

View File

@ -221,7 +221,7 @@ internal class PacketCodecImpl : PacketCodec {
1 -> {
input.discardExact(4)
input.useBytes { data, length ->
data.unzip(0, length).let {
data.inflate(0, length).let {
val size = it.toInt()
if (size == it.size || size == it.size + 4) {
it.toReadPacket(offset = 4)

View File

@ -20,8 +20,8 @@ import net.mamoe.mirai.internal.utils.io.ProtoBuf
import net.mamoe.mirai.internal.utils.io.serialization.loadAs
import net.mamoe.mirai.internal.utils.structureToStringIfAvailable
import net.mamoe.mirai.utils.EMPTY_BYTE_ARRAY
import net.mamoe.mirai.utils.inflate
import net.mamoe.mirai.utils.isSameType
import net.mamoe.mirai.utils.unzip
import kotlin.jvm.JvmField
@Serializable
@ -558,7 +558,7 @@ internal class ImMsgBody : ProtoBuf {
return when (byteArray[0].toInt()) {
0 -> byteArrayOf(0) + byteArray.decodeToString(startIndex = 1).toByteArray()
1 -> byteArrayOf(0) + byteArray.unzip(offset = 1).decodeToString().toByteArray()
1 -> byteArrayOf(0) + byteArray.inflate(offset = 1).decodeToString().toByteArray()
else -> error("unknown compression flag=${byteArray[0]}")
}
}

View File

@ -11,10 +11,10 @@ package net.mamoe.mirai.internal
import io.ktor.utils.io.core.*
import net.mamoe.mirai.internal.test.AbstractTest
import net.mamoe.mirai.utils.deflate
import net.mamoe.mirai.utils.gzip
import net.mamoe.mirai.utils.inflate
import net.mamoe.mirai.utils.ungzip
import net.mamoe.mirai.utils.unzip
import net.mamoe.mirai.utils.zip
import kotlin.test.Test
import kotlin.test.assertEquals
@ -22,7 +22,7 @@ internal class PlatformUtilsTest : AbstractTest() {
@Test
fun testZip() {
assertEquals("test", "test".toByteArray().zip().unzip().decodeToString())
assertEquals("test", "test".toByteArray().deflate().inflate().decodeToString())
}
@Test