Commit 05735776 authored by Him188moe's avatar Him188moe

Updated

parent f19ea393
......@@ -17,6 +17,11 @@
</parent>
<dependencies>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx-coroutines-core</artifactId>
......@@ -56,7 +61,12 @@
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.12.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.ini4j</groupId>
<artifactId>ini4j</artifactId>
<scope>compile</scope>
</dependency>
</dependencies>
......
......@@ -2,7 +2,7 @@ package net.mamoe.mirai.message.defaults
import net.mamoe.mirai.message.Message
import net.mamoe.mirai.message.MessageId
import net.mamoe.mirai.utils.lazyEncode
import net.mamoe.mirai.utils.lazyOutput
import org.intellij.lang.annotations.MagicConstant
import java.util.*
import java.util.stream.Collectors
......@@ -71,7 +71,7 @@ class MessageChain : Message {
return this
}
override fun toByteArray(): ByteArray = lazyEncode {
override fun toByteArray(): ByteArray = lazyOutput {
stream().forEach { message ->
it.write(message.toByteArray())
}
......
......@@ -2,9 +2,7 @@ package net.mamoe.mirai.message.defaults
import net.mamoe.mirai.message.Message
import net.mamoe.mirai.message.MessageId
import net.mamoe.mirai.network.packet.writeVarByteArray
import net.mamoe.mirai.network.packet.writeVarString
import net.mamoe.mirai.utils.lazyEncode
import net.mamoe.mirai.utils.lazyOutput
/**
* @author Him188moe
......@@ -16,10 +14,10 @@ class PlainText(private val text: String) : Message() {
return text
}
override fun toByteArray(): ByteArray = lazyEncode { section ->
override fun toByteArray(): ByteArray = lazyOutput { section ->
section.writeByte(this.type)
section.writeVarByteArray(lazyEncode { child ->
section.writeVarByteArray(lazyOutput { child ->
child.writeByte(0x01)
child.writeVarString(this.text)
})
......
......@@ -301,7 +301,7 @@ class BotNetworkHandler(private val bot: Bot) : Closeable {
private lateinit var loginIP: String
private var tgtgtKey: ByteArray = getRandomByteArray(16)
private var tlv0105: ByteArray = lazyEncode {
private var tlv0105: ByteArray = lazyOutput {
it.writeHex("01 05 00 30")
it.writeHex("00 01 01 02 00 14 01 01 00 10")
it.writeRandom(16)
......
......@@ -4,7 +4,7 @@ import net.mamoe.mirai.network.Protocol
import net.mamoe.mirai.utils.ByteArrayDataOutputStream
import net.mamoe.mirai.utils.TEA
import net.mamoe.mirai.utils.getRandomByteArray
import net.mamoe.mirai.utils.lazyEncode
import net.mamoe.mirai.utils.lazyOutput
import java.io.DataInputStream
import java.net.InetAddress
......@@ -85,7 +85,7 @@ class ServerSessionKeyResponsePacket(inputStream: DataInputStream, private val d
527 -> {
input.goto(63)
sessionKey = input.readNBytes(16)
tlv0105 = lazyEncode {
tlv0105 = lazyOutput {
it.writeHex("01 05 00 88 00 01 01 02 00 40 02 01 03 3C 01 03 00 00")
input.goto(dataLength - 122)
it.write(input.readNBytes(56))
......
......@@ -3,7 +3,7 @@ package net.mamoe.mirai.network.packet.action
import net.mamoe.mirai.message.defaults.MessageChain
import net.mamoe.mirai.network.Protocol
import net.mamoe.mirai.network.packet.*
import net.mamoe.mirai.utils.lazyEncode
import net.mamoe.mirai.utils.lazyOutput
import java.io.DataInputStream
/**
......@@ -29,7 +29,7 @@ class ClientSendFriendMessagePacket(
it.writeHex("37 0F")
it.writeQQ(botQQ)
it.writeQQ(targetQQ)
it.write(md5(lazyEncode { md5Key -> md5Key.writeQQ(targetQQ); md5Key.write(sessionKey) }))
it.write(md5(lazyOutput { md5Key -> md5Key.writeQQ(targetQQ); md5Key.write(sessionKey) }))
it.writeHex("00 0B")
it.writeRandom(2)
it.writeTime()
......
package net.mamoe.mirai.network.packet.image
import net.mamoe.mirai.network.packet.*
import net.mamoe.mirai.utils.writeProtoInt
import net.mamoe.mirai.utils.toByteArray
import net.mamoe.mirai.utils.writeUVarInt
import java.awt.image.BufferedImage
/**
......@@ -13,23 +14,77 @@ import java.awt.image.BufferedImage
@PacketId("03 88")
@ExperimentalUnsignedTypes
class ClientGetGroupImageIDPacket(
val bot: Long,
val sessionKey: ByteArray,
val group: Long,
val image: BufferedImage
private val bot: Long,
private val sessionKey: ByteArray,
private val group: Long,
private val image: BufferedImage
) : ClientPacket() {
override fun encode() {
this.writeRandom(2)
this.writeQQ(bot)
this.writeHex("04 00 00 00 01 01 01 00 00 68 20 00 00 00 00 00 00 00 00")
val byteArray = image.toByteArray()
this.encryptAndWrite(sessionKey) {
it.writeHex("00 00 00 07 00 00 00 5E 08 01 12 03 98 01 01 10 01 1A")
it.writeHex("5A")
it.writeZero(3)
it.writeHex("07 00")
it.writeZero(2)
it.writeHex("5E")
it.writeHex("08")
it.writeProtoInt(group)
it.writeHex("01 12 03 98 01 01 10 01")
it.writeHex("1A")
it.writeHex("5A")
it.writeHex("08")
it.writeProtoInt(image.height)
it.writeUVarInt(group)
it.writeHex("10")
it.writeUVarInt(bot)
it.writeHex("18 00")
it.writeHex("22")
it.writeHex("10")
it.write(md5(byteArray))
it.writeHex("28")
it.writeUVarInt(byteArray.size.toUInt())
it.writeHex("32")
it.writeHex("1A")
it.writeHex("37 00 4D 00 32 00 25 00 4C 00 31 00 56 00 32 00 7B 00 39 00 30 00 29 00 52 00")
it.writeHex("38 01")
it.writeHex("48 01")
it.writeHex("50")
it.writeUVarInt(image.width.toUInt())
it.writeHex("58")
it.writeUVarInt(image.height.toUInt())
it.writeHex("60 04")
it.writeHex("6A 05")
it.writeHex("32 36 36 35 36 05")
it.writeHex("70 00")
it.writeHex("78 03")
it.writeHex("80 01")
it.writeHex("00")
}
}
}
fun main() {
println(0xff)
}
\ No newline at end of file
package net.mamoe.mirai.utils
import java.io.DataOutputStream
/**
* Google ProtocolBuff 的一些算法实现
*
* @author Him188moe
*/
/**
* 128(10000000) -> 0x7F (10000000_10000001)
*
* TODO improve
*/
@ExperimentalUnsignedTypes
fun DataOutputStream.writeProtoFixedInt(int: Long) {
if (int == 0xFFL) {
this.writeShort(0x80_01)//unsigned//1000000010000001
return
}
this.writeByte((int.rem(0xFF) + 0xFF).toInt())
this.writeByte((int / 0xFF).toInt())
}
/**
* 127(1111111(7)) -> 0x7F (11111111(8))
*
* TODO improve
*/
@ExperimentalUnsignedTypes
fun DataOutputStream.writeProtoInt(int: Long) {
if (int < 0xFF) {
this.writeByte((int and 0xFF).toInt())//10000000
return
}
this.writeProtoFixedInt(int)
}
@ExperimentalUnsignedTypes
fun main() {
println()
println(lazyEncode {
it.writeProtoInt(128)
}.toUHexString())
}
\ No newline at end of file
package net.mamoe.mirai.utils
import net.mamoe.mirai.network.Protocol
import java.awt.image.BufferedImage
import java.io.ByteArrayOutputStream
import java.io.DataOutputStream
import java.io.File
import java.lang.reflect.Field
import java.util.*
import java.util.zip.CRC32
import javax.imageio.ImageIO
/**
* @author Him188moe
......@@ -70,7 +72,7 @@ open class ByteArrayDataOutputStream : DataOutputStream(ByteArrayOutputStream())
}
@JvmSynthetic
fun lazyEncode(t: (ByteArrayDataOutputStream) -> Unit): ByteArray = ByteArrayDataOutputStream().let { t(it); return it.toByteArray() }
fun lazyEncode(t: (ByteArrayDataOutputStream) -> Unit): ByteArray = ByteArrayDataOutputStream().also(t).toByteArray()
@ExperimentalUnsignedTypes
fun getRandomByteArray(length: Int): ByteArray {
......@@ -134,4 +136,10 @@ fun ByteArray.removeZeroTail(): ByteArray {
--i
}
return this.copyOfRange(0, i + 1)
}
fun BufferedImage.toByteArray(formatName: String = "PNG"): ByteArray {
return lazyEncode {
ImageIO.write(this, formatName, it)
}
}
\ No newline at end of file
@file:JvmName("Varint")
package net.mamoe.mirai.utils
import java.io.DataInputStream
import java.io.DataOutputStream
import java.io.IOException
import java.io.InputStream
import kotlin.experimental.or
/**
* Tool class for VarInt or VarLong operations.
*
* Some code from http://wiki.vg/Protocol.
*
* @author MagicDroidX of Nukkit Project
* @author lmlstarqaq of Nukkit Project
*/
fun encodeZigZag32(signedInt: Int): Long {
return (signedInt shl 1 xor (signedInt shr 31)).toLong()
}
@ExperimentalUnsignedTypes
@JvmSynthetic
fun decodeZigZag32(uint: UInt): Int {
return decodeZigZag32(uint.toLong())
}
fun decodeZigZag32(uint: Long): Int {
return (uint shr 1).toInt() xor -(uint and 1).toInt()
}
fun encodeZigZag64(signedLong: Long): Long {
return signedLong shl 1 xor (signedLong shr 63)
}
fun decodeZigZag64(signedLong: Long): Long {
return signedLong.ushr(1) xor -(signedLong and 1)
}
@ExperimentalUnsignedTypes
@Throws(IOException::class)
fun DataInputStream.readVarInt(): Int {
return decodeZigZag32(this.readUnsignedVarInt())
}
@ExperimentalUnsignedTypes
@Throws(IOException::class)
fun DataInputStream.readUnsignedVarInt(): UInt {
return read(this, 5).toUInt()
}
@ExperimentalUnsignedTypes
@Throws(IOException::class)
fun DataInputStream.readVarLong(): Long {
return decodeZigZag64(readUnsignedVarLong().toLong())
}
@ExperimentalUnsignedTypes
@Throws(IOException::class)
fun DataInputStream.readUnsignedVarLong(): ULong {
return read(this, 10).toULong()
}
@Throws(IOException::class)
fun DataOutputStream.writeVarInt(signedInt: Int) {
this.writeUVarInt(encodeZigZag32(signedInt))
}
@ExperimentalUnsignedTypes
@Throws(IOException::class)
fun DataOutputStream.writeUVarInt(uint: UInt) {
return writeUVarInt(uint.toLong())
}
@Throws(IOException::class)
fun DataOutputStream.writeUVarInt(uint: Long) {
this.write0(uint)
}
@Throws(IOException::class)
fun DataOutputStream.writeVarLong(signedLong: Long) {
this.writeUVarLong(encodeZigZag64(signedLong))
}
@Throws(IOException::class)
fun DataOutputStream.writeUVarLong(ulong: Long) {
this.write0(ulong)
}
@Throws(IOException::class)
private fun DataOutputStream.write0(long: Long) {
var value = long
do {
var temp = (value and 127).toByte()
value = value ushr 7
if (value != 0L) {
temp = temp or 128.toByte()
}
this.writeByte(temp.toInt())
} while (value != 0L)
}
@Throws(IOException::class)
private fun read(stream: DataInputStream, maxSize: Int): Long {
var value: Long = 0
var size = 0
var b = stream.readByte().toInt()
while (b and 0x80 == 0x80) {
value = value or ((b and 0x7F).toLong() shl size++ * 7)
require(size < maxSize) { "VarLong too big" }
b = stream.readByte().toInt()
}
return value or ((b and 0x7F).toLong() shl size * 7)
}
@Throws(IOException::class)
private fun read(stream: InputStream, maxSize: Int): Long {
var value: Long = 0
var size = 0
var b = stream.read()
while (b and 0x80 == 0x80) {
value = value or ((b and 0x7F).toLong() shl size++ * 7)
require(size < maxSize) { "VarLong too big" }
b = stream.read()
}
return value or ((b and 0x7F).toLong() shl size * 7)
}
\ No newline at end of file
......@@ -17,10 +17,12 @@
</modules>
<repositories>
<!--
<repository>
<id>mamoe-repo</id>
<url>http://mamoe.net:8081/repository/public/</url>
</repository>
-->
<repository>
<id>huawei</id>
<url>https://mirrors.huaweicloud.com/repository/maven/</url>
......@@ -52,17 +54,24 @@
<version>1.18.8</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.ini4j</groupId>
<artifactId>ini4j</artifactId>
<version>0.5.2</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.5.0</version>
</dependency>
<dependency>
<groupId>org.ini4j</groupId>
<artifactId>ini4j</artifactId>
<version>0.5.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/net.java.dev.jna/jna -->
<dependency>
<groupId>net.java.dev.jna</groupId>
......@@ -90,12 +99,6 @@
<version>4.1.38.Final</version>
</dependency>
<dependency>
<groupId>org.ini4j</groupId>
<artifactId>ini4j</artifactId>
<version>0.5.2</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
......@@ -122,6 +125,12 @@
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.12.1</version>
<scope>compile</scope>
</dependency>
</dependencies>
</dependencyManagement>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment