Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
M
Mirai
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
MyCard
Mirai
Commits
20ea49b0
Commit
20ea49b0
authored
Nov 15, 2019
by
Him188
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix unresolved KDoc reference
parent
ee7d3a7e
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
111 additions
and
136 deletions
+111
-136
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/Message.kt
.../src/commonMain/kotlin/net.mamoe.mirai/message/Message.kt
+1
-1
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/TEA.kt
...i-core/src/commonMain/kotlin/net.mamoe.mirai/utils/TEA.kt
+3
-34
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/internal/HexComparator.kt
...in/kotlin/net.mamoe.mirai/utils/internal/HexComparator.kt
+16
-10
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/io/DebugUtil.kt
...c/commonMain/kotlin/net.mamoe.mirai/utils/io/DebugUtil.kt
+3
-1
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/io/InputUtils.kt
.../commonMain/kotlin/net.mamoe.mirai/utils/io/InputUtils.kt
+33
-1
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/io/OutputUtils.kt
...commonMain/kotlin/net.mamoe.mirai/utils/io/OutputUtils.kt
+24
-24
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/io/TypeConvertion.kt
...monMain/kotlin/net.mamoe.mirai/utils/io/TypeConvertion.kt
+5
-42
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/io/Varint.kt
.../src/commonMain/kotlin/net.mamoe.mirai/utils/io/Varint.kt
+26
-23
No files found.
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/Message.kt
View file @
20ea49b0
...
@@ -174,7 +174,7 @@ inline class Image(inline val id: ImageId) : Message {
...
@@ -174,7 +174,7 @@ inline class Image(inline val id: ImageId) : Message {
* 对于好友, [value] 类似于 `/01ee6426-5ff1-4cf0-8278-e8634d2909ef`, 由服务器返回.
* 对于好友, [value] 类似于 `/01ee6426-5ff1-4cf0-8278-e8634d2909ef`, 由服务器返回.
*
*
* @see ExternalImage.groupImageId 群图片的 [ImageId] 获取
* @see ExternalImage.groupImageId 群图片的 [ImageId] 获取
* @see FriendImageIdRequestPacket.Response.imageId 好友图片的 [ImageId] 获取
* @see FriendImageIdRequestPacket.Response.
RequireUpload.
imageId 好友图片的 [ImageId] 获取
*/
*/
inline
class
ImageId
(
inline
val
value
:
String
)
inline
class
ImageId
(
inline
val
value
:
String
)
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/TEA.kt
View file @
20ea49b0
...
@@ -5,7 +5,9 @@ import kotlinx.io.core.IoBuffer
...
@@ -5,7 +5,9 @@ import kotlinx.io.core.IoBuffer
import
kotlinx.io.pool.useInstance
import
kotlinx.io.pool.useInstance
import
net.mamoe.mirai.network.protocol.tim.packet.Decrypter
import
net.mamoe.mirai.network.protocol.tim.packet.Decrypter
import
net.mamoe.mirai.network.protocol.tim.packet.DecrypterByteArray
import
net.mamoe.mirai.network.protocol.tim.packet.DecrypterByteArray
import
net.mamoe.mirai.utils.io.*
import
net.mamoe.mirai.utils.io.ByteArrayPool
import
net.mamoe.mirai.utils.io.toByteArray
import
net.mamoe.mirai.utils.io.toUHexString
import
kotlin.experimental.and
import
kotlin.experimental.and
import
kotlin.experimental.xor
import
kotlin.experimental.xor
import
kotlin.jvm.JvmStatic
import
kotlin.jvm.JvmStatic
...
@@ -30,15 +32,6 @@ fun ByteArray.encryptBy(key: ByteArray, length: Int = this.size): ByteArray = TE
...
@@ -30,15 +32,6 @@ fun ByteArray.encryptBy(key: ByteArray, length: Int = this.size): ByteArray = TE
fun
ByteArray
.
encryptBy
(
key
:
DecrypterByteArray
,
length
:
Int
=
this
.
size
):
ByteArray
=
TEA
.
encrypt
(
this
,
key
.
value
,
sourceLength
=
length
)
fun
ByteArray
.
encryptBy
(
key
:
DecrypterByteArray
,
length
:
Int
=
this
.
size
):
ByteArray
=
TEA
.
encrypt
(
this
,
key
.
value
,
sourceLength
=
length
)
/**
* 通过 [String.hexToBytes] 将 [keyHex] 转为 [ByteArray] 后用它解密 [this].
* 将会使用 [HexCache]
*
* @param keyHex 长度至少为 16 bytes
* @throws DecryptionFailedException 解密错误时
*/
fun
ByteArray
.
encryptBy
(
keyHex
:
String
,
length
:
Int
=
this
.
size
):
ByteArray
=
encryptBy
(
keyHex
.
hexToBytes
(
withCache
=
true
),
length
=
length
)
/**
/**
* 在 [ByteArrayPool] 缓存 [this], 然后使用 [key] 加密.
* 在 [ByteArrayPool] 缓存 [this], 然后使用 [key] 加密.
*
*
...
@@ -83,15 +76,6 @@ fun ByteArray.decryptBy(key: IoBuffer, length: Int = this.size): ByteArray {
...
@@ -83,15 +76,6 @@ fun ByteArray.decryptBy(key: IoBuffer, length: Int = this.size): ByteArray {
}
}
}
}
/**
* 通过 [String.hexToBytes] 将 [keyHex] 转为 [ByteArray] 后用它解密 [this]
* 将会使用 [HexCache]
*
* @param keyHex 长度至少为 16 bytes
* @throws DecryptionFailedException 解密错误时
*/
fun
ByteArray
.
decryptBy
(
keyHex
:
String
,
length
:
Int
=
this
.
size
):
ByteArray
=
decryptBy
(
keyHex
.
hexToBytes
(
withCache
=
true
),
length
=
length
)
/**
/**
* 在 [ByteArrayPool] 缓存 [this], 然后使用 [key] 解密.
* 在 [ByteArrayPool] 缓存 [this], 然后使用 [key] 解密.
*
*
...
@@ -106,16 +90,6 @@ fun IoBuffer.decryptBy(key: ByteArray, offset: Int = 0, length: Int = readRemain
...
@@ -106,16 +90,6 @@ fun IoBuffer.decryptBy(key: ByteArray, offset: Int = 0, length: Int = readRemain
}
}
}
}
/**
* 在 [ByteArrayPool] 缓存 [this], 然后使用 [keyHex] 解密.
*
* @param keyHex 长度至少为 16
* @throws DecryptionFailedException 解密错误时
*/
fun
IoBuffer
.
decryptBy
(
keyHex
:
String
,
offset
:
Int
=
0
,
length
:
Int
=
readRemaining
-
offset
):
ByteArray
=
decryptBy
(
keyHex
.
hexToBytes
(
withCache
=
true
),
offset
=
offset
,
length
=
length
)
// endregion
// endregion
// region ByteReadPacket extension
// region ByteReadPacket extension
...
@@ -126,8 +100,6 @@ fun ByteReadPacket.decryptBy(key: IoBuffer): ByteReadPacket = decryptAsByteArray
...
@@ -126,8 +100,6 @@ fun ByteReadPacket.decryptBy(key: IoBuffer): ByteReadPacket = decryptAsByteArray
fun
ByteReadPacket
.
decryptBy
(
key
:
Decrypter
):
ByteReadPacket
=
key
.
decrypt
(
this
)
fun
ByteReadPacket
.
decryptBy
(
key
:
Decrypter
):
ByteReadPacket
=
key
.
decrypt
(
this
)
fun
ByteReadPacket
.
decryptBy
(
keyHex
:
String
):
ByteReadPacket
=
decryptBy
(
keyHex
.
hexToBytes
())
inline
fun
<
R
>
ByteReadPacket
.
decryptAsByteArray
(
key
:
ByteArray
,
consumer
:
(
ByteArray
)
->
R
):
R
=
inline
fun
<
R
>
ByteReadPacket
.
decryptAsByteArray
(
key
:
ByteArray
,
consumer
:
(
ByteArray
)
->
R
):
R
=
ByteArrayPool
.
useInstance
{
ByteArrayPool
.
useInstance
{
val
length
=
remaining
.
toInt
()
val
length
=
remaining
.
toInt
()
...
@@ -135,9 +107,6 @@ inline fun <R> ByteReadPacket.decryptAsByteArray(key: ByteArray, consumer: (Byte
...
@@ -135,9 +107,6 @@ inline fun <R> ByteReadPacket.decryptAsByteArray(key: ByteArray, consumer: (Byte
consumer
(
it
.
decryptBy
(
key
,
length
))
consumer
(
it
.
decryptBy
(
key
,
length
))
}.
also
{
close
()
}
}.
also
{
close
()
}
inline
fun
<
R
>
ByteReadPacket
.
decryptAsByteArray
(
keyHex
:
String
,
consumer
:
(
ByteArray
)
->
R
):
R
=
this
.
decryptAsByteArray
(
keyHex
.
hexToBytes
(),
consumer
)
inline
fun
<
R
>
ByteReadPacket
.
decryptAsByteArray
(
key
:
IoBuffer
,
consumer
:
(
ByteArray
)
->
R
):
R
=
inline
fun
<
R
>
ByteReadPacket
.
decryptAsByteArray
(
key
:
IoBuffer
,
consumer
:
(
ByteArray
)
->
R
):
R
=
ByteArrayPool
.
useInstance
{
ByteArrayPool
.
useInstance
{
val
length
=
remaining
.
toInt
()
val
length
=
remaining
.
toInt
()
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/internal/HexComparator.kt
View file @
20ea49b0
@
file
:
Suppress
(
"ObjectPropertyName"
,
"MayBeConstant"
,
"NonAsciiCharacters"
,
"SpellCheckingInspection"
,
"unused"
)
@
file
:
Suppress
(
"ObjectPropertyName"
,
"MayBeConstant"
,
"NonAsciiCharacters"
,
"SpellCheckingInspection"
,
"unused"
)
package
net.mamoe.mirai.utils.i
o
package
net.mamoe.mirai.utils.i
nternal
import
kotlinx.io.core.toByteArray
import
kotlinx.io.core.toByteArray
import
net.mamoe.mirai.network.protocol.tim.TIMProtocol
import
net.mamoe.mirai.network.protocol.tim.TIMProtocol
import
net.mamoe.mirai.utils.io.toUHexString
import
kotlin.math.max
import
kotlin.math.max
import
kotlin.reflect.KProperty
import
kotlin.reflect.KProperty
0
/**
/**
* 匹配已知 hex 常量并格式化后打印到控制台.
* 匹配已知 hex 常量并格式化后打印到控制台.
...
@@ -19,7 +20,7 @@ internal fun String.printColorize(ignoreUntilFirstConst: Boolean): String = with
...
@@ -19,7 +20,7 @@ internal fun String.printColorize(ignoreUntilFirstConst: Boolean): String = with
*
*
* 低效率, 仅调试使用.
* 低效率, 仅调试使用.
*/
*/
internal
fun
printCompareHex
(
hex1s
:
String
,
hex2s
:
String
):
String
=
with
(
HexComparator
)
{
compare
(
hex1s
,
hex2s
)
}
fun
printCompareHex
(
hex1s
:
String
,
hex2s
:
String
):
String
=
with
(
HexComparator
)
{
compare
(
hex1s
.
toUpperCase
(),
hex2s
.
toUpperCase
()
)
}
data class
NamedHexElement
(
data class
NamedHexElement
(
val
name
:
String
,
val
name
:
String
,
...
@@ -35,8 +36,8 @@ private fun LinkedHashSet<NamedHexElement>.initConstFileds() {
...
@@ -35,8 +36,8 @@ private fun LinkedHashSet<NamedHexElement>.initConstFileds() {
TIMProtocol
,
TIMProtocol
,
PacketIds
PacketIds
).
forEach
{
obj
->
).
forEach
{
obj
->
obj
::
class
.
members
.
filterIsInstance
<
KProperty
<
*
>>().
forEach
{
property
->
obj
::
class
.
members
.
filterIsInstance
<
KProperty
0
<
*
>>().
forEach
{
property
->
add
(
NamedHexElement
(
property
.
name
,
property
.
getter
.
call
().
toString
()))
property
.
get
()
?.
let
{
add
(
NamedHexElement
(
property
.
name
,
it
.
toString
()))
}
}
}
}
}
}
}
...
@@ -107,9 +108,14 @@ private object HexComparator {
...
@@ -107,9 +108,14 @@ private object HexComparator {
private
class
Match
internal
constructor
(
val
range
:
IntRange
,
val
constName
:
String
)
private
class
Match
internal
constructor
(
val
range
:
IntRange
,
val
constName
:
String
)
init
{
init
{
TIMProtocol
::
class
.
members
.
filterIsInstance
<
KProperty
<
*
>>().
forEach
{
CONST_FIELDS
.
forEach
{
(
name
,
value
)
->
for
(
match
in
match
(
hex
,
it
.
getter
.
call
().
toString
()))
{
for
(
match
in
match
(
hex
,
value
))
{
matches
.
add
(
Match
(
match
,
it
.
getter
.
call
().
toString
()))
matches
.
add
(
Match
(
match
,
name
))
}
}
TIMProtocol
::
class
.
members
.
filterIsInstance
<
KProperty0
<
*
>>().
mapNotNull
{
it
()
?.
toString
()
}.
forEach
{
for
(
match
in
match
(
hex
,
it
))
{
matches
.
add
(
Match
(
match
,
it
))
}
}
}
}
}
}
...
@@ -118,10 +124,10 @@ private object HexComparator {
...
@@ -118,10 +124,10 @@ private object HexComparator {
val
CONST_FIELDS
:
Set
<
NamedHexElement
>
=
linkedSetOf
<
NamedHexElement
>().
apply
{
initConstFileds
()
}
val
CONST_FIELDS
:
Set
<
NamedHexElement
>
=
linkedSetOf
<
NamedHexElement
>().
apply
{
initConstFileds
()
}
}
}
private
fun
match
(
hex
:
String
,
field
:
String
):
Set
<
IntRange
>
{
private
fun
match
(
hex
:
String
,
value
:
String
):
Set
<
IntRange
>
{
val
constValue
:
String
val
constValue
:
String
try
{
try
{
constValue
=
field
.
trim
{
it
<=
' '
}
constValue
=
value
.
trim
{
it
<=
' '
}
if
(
constValue
.
length
/
3
<=
3
)
{
//Minimum numbers of const hex bytes
if
(
constValue
.
length
/
3
<=
3
)
{
//Minimum numbers of const hex bytes
return
linkedSetOf
()
return
linkedSetOf
()
}
}
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/io/DebugUtil.kt
View file @
20ea49b0
...
@@ -3,6 +3,8 @@ package net.mamoe.mirai.utils.io
...
@@ -3,6 +3,8 @@ package net.mamoe.mirai.utils.io
import
kotlinx.io.core.*
import
kotlinx.io.core.*
import
net.mamoe.mirai.utils.DefaultLogger
import
net.mamoe.mirai.utils.DefaultLogger
import
net.mamoe.mirai.utils.MiraiLogger
import
net.mamoe.mirai.utils.MiraiLogger
import
net.mamoe.mirai.utils.internal.printColorize
import
net.mamoe.mirai.utils.internal.printCompareHex
internal
object
DebugLogger
:
MiraiLogger
by
DefaultLogger
(
"Packet Debug"
)
internal
object
DebugLogger
:
MiraiLogger
by
DefaultLogger
(
"Packet Debug"
)
...
@@ -62,7 +64,7 @@ internal fun BytePacketBuilder.debugPrintThis(name: String = "") {
...
@@ -62,7 +64,7 @@ internal fun BytePacketBuilder.debugPrintThis(name: String = "") {
}
}
internal
fun
String
.
printStringFromHex
()
{
internal
fun
String
.
printStringFromHex
()
{
println
(
this
.
hexToBytes
().
stringOfWitch
())
println
(
this
.
hexToBytes
().
encodeToString
())
}
}
internal
fun
ByteArray
.
printColorizedHex
(
name
:
String
=
""
,
ignoreUntilFirstConst
:
Boolean
=
false
,
compareTo
:
String
?
=
null
)
{
internal
fun
ByteArray
.
printColorizedHex
(
name
:
String
=
""
,
ignoreUntilFirstConst
:
Boolean
=
false
,
compareTo
:
String
?
=
null
)
{
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/io/InputUtils.kt
View file @
20ea49b0
...
@@ -3,6 +3,8 @@
...
@@ -3,6 +3,8 @@
package
net.mamoe.mirai.utils.io
package
net.mamoe.mirai.utils.io
import
kotlinx.io.core.*
import
kotlinx.io.core.*
import
kotlinx.io.pool.useInstance
import
kotlin.jvm.JvmName
fun
ByteReadPacket
.
readRemainingBytes
(
fun
ByteReadPacket
.
readRemainingBytes
(
...
@@ -23,8 +25,12 @@ fun Input.readIP(): String = buildString(4 + 3) {
...
@@ -23,8 +25,12 @@ fun Input.readIP(): String = buildString(4 + 3) {
}
}
}
}
fun
Input
.
readUVarIntLVString
():
String
=
String
(
this
.
readUVarIntByteArray
())
fun
Input
.
readUShortLVString
():
String
=
String
(
this
.
readUShortLVByteArray
())
fun
Input
.
readUShortLVString
():
String
=
String
(
this
.
readUShortLVByteArray
())
fun
Input
.
readUVarIntByteArray
():
ByteArray
=
this
.
readBytes
(
this
.
readUVarInt
().
toInt
())
fun
Input
.
readUShortLVByteArray
():
ByteArray
=
this
.
readBytes
(
this
.
readUShort
().
toInt
())
fun
Input
.
readUShortLVByteArray
():
ByteArray
=
this
.
readBytes
(
this
.
readUShort
().
toInt
())
private
inline
fun
<
R
>
inline
(
block
:
()
->
R
):
R
=
block
()
private
inline
fun
<
R
>
inline
(
block
:
()
->
R
):
R
=
block
()
...
@@ -63,7 +69,33 @@ fun Input.readTLVMap(expectingEOF: Boolean = false, tagSize: Int = 1): MutableMa
...
@@ -63,7 +69,33 @@ fun Input.readTLVMap(expectingEOF: Boolean = false, tagSize: Int = 1): MutableMa
fun
Map
<*,
ByteArray
>.
printTLVMap
(
name
:
String
)
=
fun
Map
<*,
ByteArray
>.
printTLVMap
(
name
:
String
)
=
debugPrintln
(
"TLVMap $name= "
+
this
.
mapValues
{
(
_
,
value
)
->
value
.
toUHexString
()
})
debugPrintln
(
"TLVMap $name= "
+
this
.
mapValues
{
(
_
,
value
)
->
value
.
toUHexString
()
})
fun
Input
.
readString
(
length
:
Number
):
String
=
String
(
this
.
readBytes
(
length
.
toInt
()))
fun
Input
.
readString
(
length
:
Int
):
String
=
String
(
this
.
readBytes
(
length
))
fun
Input
.
readString
(
length
:
Long
):
String
=
String
(
this
.
readBytes
(
length
.
toInt
()))
fun
Input
.
readString
(
length
:
Short
):
String
=
String
(
this
.
readBytes
(
length
.
toInt
()))
fun
Input
.
readString
(
length
:
UShort
):
String
=
String
(
this
.
readBytes
(
length
.
toInt
()))
fun
Input
.
readString
(
length
:
Byte
):
String
=
String
(
this
.
readBytes
(
length
.
toInt
()))
fun
Input
.
readStringUntil
(
stopSignalExclude
:
UByte
,
expectingEOF
:
Boolean
=
false
):
String
=
readStringUntil
(
stopSignalExclude
.
toByte
(),
expectingEOF
)
// TODO 应标记 JvmSynthetic 但 kotlin 有bug
@JvmName
(
"readStringUntil0"
)
fun
Input
.
readStringUntil
(
stopSignalExclude
:
Byte
,
expectingEOF
:
Boolean
=
false
):
String
{
ByteArrayPool
.
useInstance
{
var
count
=
0
val
buffer
=
byteArrayOf
(
1
)
while
(
readAvailable
(
buffer
,
1
)
==
1
)
{
if
(
buffer
[
0
]
==
stopSignalExclude
)
{
return
buffer
.
encodeToString
()
}
it
[
count
++]
=
buffer
[
0
]
}
if
(!
expectingEOF
)
{
throw
EOFException
(
"Early EOF"
)
}
return
buffer
.
encodeToString
()
}
}
private
const
val
TRUE_BYTE_VALUE
:
Byte
=
1
private
const
val
TRUE_BYTE_VALUE
:
Byte
=
1
fun
Input
.
readBoolean
():
Boolean
=
this
.
readByte
()
==
TRUE_BYTE_VALUE
fun
Input
.
readBoolean
():
Boolean
=
this
.
readByte
()
==
TRUE_BYTE_VALUE
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/io/OutputUtils.kt
View file @
20ea49b0
...
@@ -29,38 +29,33 @@ fun BytePacketBuilder.writeShortLVByteArray(byteArray: ByteArray) {
...
@@ -29,38 +29,33 @@ fun BytePacketBuilder.writeShortLVByteArray(byteArray: ByteArray) {
this
.
writeFully
(
byteArray
)
this
.
writeFully
(
byteArray
)
}
}
fun
BytePacketBuilder
.
writeShortLVPacket
(
tag
:
UByte
?
=
null
,
lengthOffset
:
((
Long
)
->
Long
)?
=
null
,
builder
:
BytePacketBuilder
.()
->
Unit
)
=
fun
BytePacketBuilder
.
writeShortLVPacket
(
tag
:
UByte
?
=
null
,
lengthOffset
:
((
Long
)
->
Long
)?
=
null
,
builder
:
BytePacketBuilder
.()
->
Unit
)
=
with
(
BytePacketBuilder
().
apply
(
builder
).
build
())
{
BytePacketBuilder
().
apply
(
builder
).
build
().
use
{
if
(
tag
!=
null
)
{
if
(
tag
!=
null
)
writeUByte
(
tag
)
writeUByte
(
tag
)
writeUShort
((
lengthOffset
?.
invoke
(
it
.
remaining
)
?:
it
.
remaining
).
coerceAtMostOrFail
(
0
xFFFFL
).
toUShort
())
}
writePacket
(
it
)
writeUShort
((
lengthOffset
?.
invoke
(
remaining
)
?:
remaining
).
coerceAtMostOrFail
(
0
xFFFFL
).
toUShort
())
writePacket
(
this
)
this
.
release
()
}
}
fun
BytePacketBuilder
.
writeUVarintLVPacket
(
tag
:
UByte
?
=
null
,
lengthOffset
:
((
Long
)
->
Long
)?
=
null
,
builder
:
BytePacketBuilder
.()
->
Unit
)
=
fun
BytePacketBuilder
.
writeUVarIntLVPacket
(
tag
:
UByte
?
=
null
,
lengthOffset
:
((
Long
)
->
Long
)?
=
null
,
builder
:
BytePacketBuilder
.()
->
Unit
)
=
with
(
BytePacketBuilder
().
apply
(
builder
).
build
())
{
BytePacketBuilder
().
apply
(
builder
).
build
().
use
{
if
(
tag
!=
null
)
{
if
(
tag
!=
null
)
writeUByte
(
tag
)
writeUByte
(
tag
)
writeUVarInt
((
lengthOffset
?.
invoke
(
it
.
remaining
)
?:
it
.
remaining
).
coerceAtMostOrFail
(
0
xFFFFL
))
}
writePacket
(
it
)
writeUVarInt
((
lengthOffset
?.
invoke
(
remaining
)
?:
remaining
).
coerceAtMostOrFail
(
0
xFFFFL
))
writePacket
(
this
)
this
.
release
()
}
}
@Suppress
(
"DEPRECATION"
)
fun
BytePacketBuilder
.
writeShortLVString
(
str
:
String
)
=
writeShortLVByteArray
(
str
.
toByteArray
())
fun
BytePacketBuilder
.
writeShortLVString
(
str
:
String
)
=
this
.
writeShortLVByteArray
(
str
.
toByteArray
())
@Suppress
(
"DEPRECATION"
)
fun
BytePacketBuilder
.
writeLVHex
(
hex
:
String
)
=
this
.
writeShortLVByteArray
(
hex
.
hexToBytes
())
fun
BytePacketBuilder
.
writeIP
(
ip
:
String
)
=
writeFully
(
ip
.
trim
().
split
(
"."
).
map
{
it
.
toUByte
()
}.
toUByteArray
())
fun
BytePacketBuilder
.
writeIP
(
ip
:
String
)
=
writeFully
(
ip
.
trim
().
split
(
"."
).
map
{
it
.
toUByte
()
}.
toUByteArray
())
fun
BytePacketBuilder
.
writeTime
()
=
this
.
writeInt
(
currentTime
.
toInt
())
fun
BytePacketBuilder
.
writeTime
()
=
this
.
writeInt
(
currentTime
.
toInt
())
fun
BytePacketBuilder
.
writeHex
(
uHex
:
String
)
=
this
.
writeFully
(
uHex
.
hexToUBytes
())
fun
BytePacketBuilder
.
writeHex
(
uHex
:
String
)
{
uHex
.
split
(
" "
).
forEach
{
if
(
it
.
isNotBlank
())
{
writeUByte
(
it
.
toUByte
(
16
))
}
}
}
fun
BytePacketBuilder
.
writeTLV
(
tag
:
UByte
,
values
:
UByteArray
)
{
fun
BytePacketBuilder
.
writeTLV
(
tag
:
UByte
,
values
:
UByteArray
)
{
writeUByte
(
tag
)
writeUByte
(
tag
)
...
@@ -81,6 +76,11 @@ fun BytePacketBuilder.writeTHex(tag: UByte, uHex: String) {
...
@@ -81,6 +76,11 @@ fun BytePacketBuilder.writeTHex(tag: UByte, uHex: String) {
fun
BytePacketBuilder
.
writeTV
(
tagValue
:
UShort
)
=
writeUShort
(
tagValue
)
fun
BytePacketBuilder
.
writeTV
(
tagValue
:
UShort
)
=
writeUShort
(
tagValue
)
fun
BytePacketBuilder
.
writeTV
(
tag
:
UByte
,
value
:
UByte
)
{
writeUByte
(
tag
)
writeUByte
(
value
)
}
fun
BytePacketBuilder
.
writeTUbyte
(
tag
:
UByte
,
value
:
UByte
)
{
fun
BytePacketBuilder
.
writeTUbyte
(
tag
:
UByte
,
value
:
UByte
)
{
this
.
writeUByte
(
tag
)
this
.
writeUByte
(
tag
)
this
.
writeUByte
(
value
)
this
.
writeUByte
(
value
)
...
@@ -124,7 +124,7 @@ fun BytePacketBuilder.writeTLV0006(qq: UInt, password: String, loginTime: Int, l
...
@@ -124,7 +124,7 @@ fun BytePacketBuilder.writeTLV0006(qq: UInt, password: String, loginTime: Int, l
writeRandom
(
4
)
writeRandom
(
4
)
writeHex
(
"00 02"
)
writeHex
(
"00 02"
)
writeQQ
(
qq
)
writeQQ
(
qq
)
write
Hex
(
TIMProtocol
.
constantData2
)
write
Fully
(
TIMProtocol
.
constantData2
)
writeHex
(
"00 00 01"
)
writeHex
(
"00 00 01"
)
writeFully
(
firstMD5
)
writeFully
(
firstMD5
)
...
@@ -151,5 +151,5 @@ fun BytePacketBuilder.writeDeviceName(random: Boolean) {
...
@@ -151,5 +151,5 @@ fun BytePacketBuilder.writeDeviceName(random: Boolean) {
}
}
this
.
writeShort
((
deviceName
.
length
+
2
).
toShort
())
this
.
writeShort
((
deviceName
.
length
+
2
).
toShort
())
this
.
writeShort
(
deviceName
.
length
.
toShort
())
this
.
writeShort
(
deviceName
.
length
.
toShort
())
this
.
writeStringUtf8
(
deviceName
)
//TODO TEST?
this
.
writeStringUtf8
(
deviceName
)
}
}
\ No newline at end of file
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/io/TypeConvertion.kt
View file @
20ea49b0
...
@@ -5,7 +5,6 @@ package net.mamoe.mirai.utils.io
...
@@ -5,7 +5,6 @@ package net.mamoe.mirai.utils.io
import
kotlinx.io.core.IoBuffer
import
kotlinx.io.core.IoBuffer
import
kotlinx.io.core.writeFully
import
kotlinx.io.core.writeFully
import
kotlinx.io.pool.ObjectPool
import
kotlinx.io.pool.ObjectPool
import
kotlin.jvm.Synchronized
import
kotlin.random.Random
import
kotlin.random.Random
import
kotlin.random.nextInt
import
kotlin.random.nextInt
...
@@ -75,9 +74,8 @@ fun Byte.toUHexString(): String = this.toUByte().toString(16).toUpperCase().let
...
@@ -75,9 +74,8 @@ fun Byte.toUHexString(): String = this.toUByte().toString(16).toUpperCase().let
/**
/**
* 将无符号 Hex 转为 [ByteArray], 有根据 hex 的 [hashCode] 建立的缓存.
* 将无符号 Hex 转为 [ByteArray], 有根据 hex 的 [hashCode] 建立的缓存.
*/
*/
fun
String
.
hexToBytes
(
withCache
:
Boolean
=
true
):
ByteArray
=
fun
String
.
hexToBytes
():
ByteArray
=
if
(
withCache
)
HexCache
.
getCacheOrConvert
(
this
)
this
.
split
(
" "
)
else
this
.
split
(
" "
)
.
filterNot
{
it
.
isEmpty
()
}
.
filterNot
{
it
.
isEmpty
()
}
.
map
{
s
->
s
.
toUByte
(
16
).
toByte
()
}
.
map
{
s
->
s
.
toUByte
(
16
).
toByte
()
}
.
toByteArray
()
.
toByteArray
()
...
@@ -85,9 +83,8 @@ fun String.hexToBytes(withCache: Boolean = true): ByteArray =
...
@@ -85,9 +83,8 @@ fun String.hexToBytes(withCache: Boolean = true): ByteArray =
/**
/**
* 将无符号 Hex 转为 [UByteArray], 有根据 hex 的 [hashCode] 建立的缓存.
* 将无符号 Hex 转为 [UByteArray], 有根据 hex 的 [hashCode] 建立的缓存.
*/
*/
fun
String
.
hexToUBytes
(
withCache
:
Boolean
=
true
):
UByteArray
=
fun
String
.
hexToUBytes
():
UByteArray
=
if
(
withCache
)
HexCache
.
getUCacheOrConvert
(
this
)
this
.
split
(
" "
)
else
this
.
split
(
" "
)
.
filterNot
{
it
.
isEmpty
()
}
.
filterNot
{
it
.
isEmpty
()
}
.
map
{
s
->
s
.
toUByte
(
16
)
}
.
map
{
s
->
s
.
toUByte
(
16
)
}
.
toUByteArray
()
.
toUByteArray
()
...
@@ -129,38 +126,4 @@ fun ByteArray.toUInt(): UInt =
...
@@ -129,38 +126,4 @@ fun ByteArray.toUInt(): UInt =
* 从 [IoBuffer.Pool] [borrow][ObjectPool.borrow] 一个 [IoBuffer] 然后将 [this] 写入.
* 从 [IoBuffer.Pool] [borrow][ObjectPool.borrow] 一个 [IoBuffer] 然后将 [this] 写入.
* 注意回收 ([ObjectPool.recycle])
* 注意回收 ([ObjectPool.recycle])
*/
*/
fun
ByteArray
.
toIoBuffer
():
IoBuffer
=
IoBuffer
.
Pool
.
borrow
().
let
{
it
.
writeFully
(
this
);
it
}
fun
ByteArray
.
toIoBuffer
():
IoBuffer
=
IoBuffer
.
Pool
.
borrow
().
let
{
it
.
writeFully
(
this
);
it
}
\ No newline at end of file
/**
* Hex 转换 [ByteArray] 和 [UByteArray] 缓存.
* 为 [net.mamoe.mirai.network.protocol.tim.TIMProtocol] 的 hex 常量使用
*/
internal
object
HexCache
{
private
val
hexToByteArrayCacheMap
:
MutableMap
<
Int
,
ByteArray
>
=
mutableMapOf
()
@Synchronized
internal
fun
getCacheOrConvert
(
hex
:
String
):
ByteArray
=
hex
.
hashCode
().
let
{
id
->
if
(
hexToByteArrayCacheMap
.
containsKey
(
id
))
{
return
hexToByteArrayCacheMap
[
id
]
!!
}
else
{
hex
.
hexToBytes
(
withCache
=
false
).
let
{
hexToByteArrayCacheMap
[
id
]
=
it
return
it
}
}
}
private
val
hexToUByteArrayCacheMap
:
MutableMap
<
Int
,
UByteArray
>
=
mutableMapOf
()
@Synchronized
internal
fun
getUCacheOrConvert
(
hex
:
String
):
UByteArray
=
hex
.
hashCode
().
let
{
id
->
if
(
hexToUByteArrayCacheMap
.
containsKey
(
id
))
{
return
hexToUByteArrayCacheMap
[
id
]
!!
}
else
{
hex
.
hexToUBytes
(
withCache
=
false
).
let
{
hexToUByteArrayCacheMap
[
id
]
=
it
return
it
}
}
}
}
\ No newline at end of file
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/io/Varint.kt
View file @
20ea49b0
@
file
:
JvmName
(
"Varint"
)
@
file
:
JvmName
(
"Varint"
)
@
file
:
Suppress
(
"EXPERIMENTAL_API_USAGE"
)
@
file
:
Suppress
(
"EXPERIMENTAL_API_USAGE"
)
package
net.mamoe.mirai.utils
package
net.mamoe.mirai.utils
.io
import
kotlinx.io.core.
BytePacketBuilder
import
kotlinx.io.core.
Input
import
kotlinx.io.core.
ByteReadPacke
t
import
kotlinx.io.core.
Outpu
t
import
kotlin.experimental.or
import
kotlin.experimental.or
import
kotlin.jvm.JvmName
import
kotlin.jvm.JvmName
import
kotlin.jvm.JvmSynthetic
/**
/**
* Tool class for VarInt or VarLong operations.
* Tool class for VarInt or VarLong operations.
...
@@ -17,70 +18,72 @@ import kotlin.jvm.JvmName
...
@@ -17,70 +18,72 @@ import kotlin.jvm.JvmName
* @author lmlstarqaq of Nukkit Project
* @author lmlstarqaq of Nukkit Project
*/
*/
fun
encodeZigZag32
(
signedInt
:
Int
):
Long
{
internal
fun
encodeZigZag32
(
signedInt
:
Int
):
Long
{
return
(
signedInt
shl
1
xor
(
signedInt
shr
31
)).
toLong
()
return
(
signedInt
shl
1
xor
(
signedInt
shr
31
)).
toLong
()
}
}
@JvmSynthetic
//@JvmSynthetic
internal
fun
decodeZigZag32
(
uint
:
UInt
):
Int
{
fun
decodeZigZag32
(
uint
:
UInt
):
Int
{
return
decodeZigZag32
(
uint
.
toLong
())
return
decodeZigZag32
(
uint
.
toLong
())
}
}
fun
decodeZigZag32
(
uint
:
Long
):
Int
{
internal
fun
decodeZigZag32
(
uint
:
Long
):
Int
{
return
(
uint
shr
1
).
toInt
()
xor
-(
uint
and
1
).
toInt
()
return
(
uint
shr
1
).
toInt
()
xor
-(
uint
and
1
).
toInt
()
}
}
fun
encodeZigZag64
(
signedLong
:
Long
):
Long
{
internal
fun
encodeZigZag64
(
signedLong
:
Long
):
Long
{
return
signedLong
shl
1
xor
(
signedLong
shr
63
)
return
signedLong
shl
1
xor
(
signedLong
shr
63
)
}
}
fun
decodeZigZag64
(
signedLong
:
Long
):
Long
{
internal
fun
decodeZigZag64
(
signedLong
:
Long
):
Long
{
return
signedLong
.
ushr
(
1
)
xor
-(
signedLong
and
1
)
return
signedLong
.
ushr
(
1
)
xor
-(
signedLong
and
1
)
}
}
fun
ByteReadPacke
t
.
readVarInt
():
Int
{
fun
Inpu
t
.
readVarInt
():
Int
{
return
decodeZigZag32
(
this
.
readU
nsigned
VarInt
())
return
decodeZigZag32
(
this
.
readUVarInt
())
}
}
fun
ByteReadPacket
.
readUnsignedVarInt
():
UInt
{
@JvmSynthetic
fun
Input
.
readUVarInt
():
UInt
{
return
read
(
this
,
5
).
toUInt
()
return
read
(
this
,
5
).
toUInt
()
}
}
fun
ByteReadPacke
t
.
readVarLong
():
Long
{
fun
Inpu
t
.
readVarLong
():
Long
{
return
decodeZigZag64
(
readU
nsigned
VarLong
().
toLong
())
return
decodeZigZag64
(
readUVarLong
().
toLong
())
}
}
fun
ByteReadPacket
.
readUnsignedVarLong
():
ULong
{
@JvmSynthetic
fun
Input
.
readUVarLong
():
ULong
{
return
read
(
this
,
10
).
toULong
()
return
read
(
this
,
10
).
toULong
()
}
}
fun
BytePacketBuilder
.
writeVarInt
(
signedInt
:
Int
)
{
fun
Output
.
writeVarInt
(
signedInt
:
Int
)
{
this
.
writeUVarInt
(
encodeZigZag32
(
signedInt
))
this
.
writeUVarInt
(
encodeZigZag32
(
signedInt
))
}
}
fun
BytePacketBuilder
.
writeUVarInt
(
uint
:
UInt
)
{
@JvmSynthetic
fun
Output
.
writeUVarInt
(
uint
:
UInt
)
{
return
writeUVarInt
(
uint
.
toLong
())
return
writeUVarInt
(
uint
.
toLong
())
}
}
fun
BytePacketBuilder
.
writeUVarInt
(
uint
:
Long
)
{
fun
Output
.
writeUVarInt
(
uint
:
Long
)
{
this
.
write0
(
uint
)
this
.
write0
(
uint
)
}
}
fun
BytePacketBuilder
.
writeVarLong
(
signedLong
:
Long
)
{
fun
Output
.
writeVarLong
(
signedLong
:
Long
)
{
this
.
writeUVarLong
(
encodeZigZag64
(
signedLong
))
this
.
writeUVarLong
(
encodeZigZag64
(
signedLong
))
}
}
fun
BytePacketBuilder
.
writeUVarLong
(
ulong
:
Long
)
{
fun
Output
.
writeUVarLong
(
ulong
:
Long
)
{
this
.
write0
(
ulong
)
this
.
write0
(
ulong
)
}
}
private
fun
BytePacketBuilder
.
write0
(
long
:
Long
)
{
private
fun
Output
.
write0
(
long
:
Long
)
{
var
value
=
long
var
value
=
long
do
{
do
{
var
temp
=
(
value
and
127
).
toByte
()
var
temp
=
(
value
and
127
).
toByte
()
...
@@ -92,7 +95,7 @@ private fun BytePacketBuilder.write0(long: Long) {
...
@@ -92,7 +95,7 @@ private fun BytePacketBuilder.write0(long: Long) {
}
while
(
value
!=
0L
)
}
while
(
value
!=
0L
)
}
}
private
fun
read
(
stream
:
ByteReadPacke
t
,
maxSize
:
Int
):
Long
{
private
fun
read
(
stream
:
Inpu
t
,
maxSize
:
Int
):
Long
{
var
value
:
Long
=
0
var
value
:
Long
=
0
var
size
=
0
var
size
=
0
var
b
=
stream
.
readByte
().
toInt
()
var
b
=
stream
.
readByte
().
toInt
()
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment