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
e60a6bcf
Commit
e60a6bcf
authored
Mar 07, 2020
by
Him188
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Revert "Use `ktor.io` than `kotlinx.io`"
parent
6b54abe7
Changes
26
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
856 additions
and
125 deletions
+856
-125
mirai-core-qqandroid/src/androidMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.kt
...roidMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.kt
+174
-1
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.kt
...mmonMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.kt
+7
-3
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt
...moe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt
+7
-7
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidClient.kt
...tlin/net/mamoe/mirai/qqandroid/network/QQAndroidClient.kt
+2
-2
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/highway/HighwayHelper.kt
...et/mamoe/mirai/qqandroid/network/highway/HighwayHelper.kt
+4
-3
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/highway/highway.kt
...tlin/net/mamoe/mirai/qqandroid/network/highway/highway.kt
+1
-1
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/Cmd0x857.kt
...e/mirai/qqandroid/network/protocol/data/proto/Cmd0x857.kt
+408
-0
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.kt
...ndroid/network/protocol/packet/chat/receive/MessageSvc.kt
+0
-57
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/OnlinePush.kt
...ndroid/network/protocol/packet/chat/receive/OnlinePush.kt
+2
-2
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/WtLogin.kt
.../mirai/qqandroid/network/protocol/packet/login/WtLogin.kt
+3
-6
mirai-core-qqandroid/src/jvmMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.kt
.../jvmMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.kt
+172
-2
mirai-core/build.gradle.kts
mirai-core/build.gradle.kts
+1
-2
mirai-core/src/androidMain/kotlin/net/mamoe/mirai/Bot.kt
mirai-core/src/androidMain/kotlin/net/mamoe/mirai/Bot.kt
+1
-1
mirai-core/src/androidMain/kotlin/net/mamoe/mirai/contact/ContactJavaHappyAPI.kt
...ain/kotlin/net/mamoe/mirai/contact/ContactJavaHappyAPI.kt
+1
-1
mirai-core/src/androidMain/kotlin/net/mamoe/mirai/message/SendImageUtilsAndroid.kt
...n/kotlin/net/mamoe/mirai/message/SendImageUtilsAndroid.kt
+16
-12
mirai-core/src/androidMain/kotlin/net/mamoe/mirai/utils/ExternalImageAndroid.kt
...Main/kotlin/net/mamoe/mirai/utils/ExternalImageAndroid.kt
+3
-2
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt
+2
-2
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/MessagePacket.kt
...ommonMain/kotlin/net.mamoe.mirai/message/MessagePacket.kt
+1
-1
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/ExternalImage.kt
.../commonMain/kotlin/net.mamoe.mirai/utils/ExternalImage.kt
+1
-1
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/channels.kt
...e/src/commonMain/kotlin/net.mamoe.mirai/utils/channels.kt
+24
-3
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/io/chunked.kt
...src/commonMain/kotlin/net.mamoe.mirai/utils/io/chunked.kt
+1
-1
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/Bot.kt
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/Bot.kt
+1
-1
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/contact/ContactJavaHappyAPI.kt
...ain/kotlin/net/mamoe/mirai/contact/ContactJavaHappyAPI.kt
+1
-1
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/message/MessagePacket.kt
...c/jvmMain/kotlin/net/mamoe/mirai/message/MessagePacket.kt
+2
-2
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/message/SendImageUtilsJvm.kt
...mMain/kotlin/net/mamoe/mirai/message/SendImageUtilsJvm.kt
+20
-10
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/utils/ExternalImageJvm.kt
.../jvmMain/kotlin/net/mamoe/mirai/utils/ExternalImageJvm.kt
+1
-1
No files found.
mirai-core-qqandroid/src/androidMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.kt
View file @
e60a6bcf
...
@@ -9,10 +9,20 @@
...
@@ -9,10 +9,20 @@
package
net.mamoe.mirai.qqandroid
package
net.mamoe.mirai.qqandroid
import
io.ktor.utils.io.ByteReadChannel
import
io.ktor.utils.io.consumeEachBufferRange
import
io.ktor.utils.io.core.Input
import
io.ktor.utils.io.core.readBytes
import
kotlinx.coroutines.io.*
import
kotlinx.io.core.*
import
kotlinx.io.pool.useInstance
import
net.mamoe.mirai.BotAccount
import
net.mamoe.mirai.BotAccount
import
net.mamoe.mirai.utils.BotConfiguration
import
net.mamoe.mirai.utils.BotConfiguration
import
net.mamoe.mirai.utils.Context
import
net.mamoe.mirai.utils.Context
import
net.mamoe.mirai.utils.MiraiInternalAPI
import
net.mamoe.mirai.utils.MiraiInternalAPI
import
net.mamoe.mirai.utils.io.ByteArrayPool
import
net.mamoe.mirai.utils.io.toReadPacket
import
java.nio.ByteBuffer
@UseExperimental
(
MiraiInternalAPI
::
class
)
@UseExperimental
(
MiraiInternalAPI
::
class
)
internal
actual
class
QQAndroidBot
internal
actual
class
QQAndroidBot
...
@@ -20,4 +30,167 @@ actual constructor(
...
@@ -20,4 +30,167 @@ actual constructor(
context
:
Context
,
context
:
Context
,
account
:
BotAccount
,
account
:
BotAccount
,
configuration
:
BotConfiguration
configuration
:
BotConfiguration
)
:
QQAndroidBotBase
(
context
,
account
,
configuration
)
)
:
QQAndroidBotBase
(
context
,
account
,
configuration
)
\ No newline at end of file
@UseExperimental
(
MiraiInternalAPI
::
class
)
@Suppress
(
"DEPRECATION"
)
internal
actual
fun
ByteReadChannel
.
toKotlinByteReadChannel
():
kotlinx
.
coroutines
.
io
.
ByteReadChannel
{
return
object
: kotlinx.coroutines.io.
ByteReadChannel
{
override
val
availableForRead
:
Int
get
()
=
this
@
toKotlinByteReadChannel
.
availableForRead
override
val
isClosedForRead
:
Boolean
get
()
=
this
@
toKotlinByteReadChannel
.
isClosedForRead
override
val
isClosedForWrite
:
Boolean
get
()
=
this
@
toKotlinByteReadChannel
.
isClosedForWrite
@Suppress
(
"DEPRECATION_ERROR"
,
"OverridingDeprecatedMember"
)
override
var
readByteOrder
:
ByteOrder
get
()
=
when
(
this
@
toKotlinByteReadChannel
.
readByteOrder
)
{
io
.
ktor
.
utils
.
io
.
core
.
ByteOrder
.
BIG_ENDIAN
->
ByteOrder
.
BIG_ENDIAN
io
.
ktor
.
utils
.
io
.
core
.
ByteOrder
.
LITTLE_ENDIAN
->
ByteOrder
.
LITTLE_ENDIAN
}
set
(
value
)
{
this
@
toKotlinByteReadChannel
.
readByteOrder
=
when
(
value
)
{
ByteOrder
.
BIG_ENDIAN
->
io
.
ktor
.
utils
.
io
.
core
.
ByteOrder
.
BIG_ENDIAN
ByteOrder
.
LITTLE_ENDIAN
->
io
.
ktor
.
utils
.
io
.
core
.
ByteOrder
.
LITTLE_ENDIAN
}
}
@Suppress
(
"DEPRECATION_ERROR"
,
"DEPRECATION"
,
"OverridingDeprecatedMember"
)
override
val
totalBytesRead
:
Long
get
()
=
this
@
toKotlinByteReadChannel
.
totalBytesRead
override
fun
cancel
(
cause
:
Throwable
?):
Boolean
=
this
@
toKotlinByteReadChannel
.
cancel
(
cause
)
override
suspend
fun
consumeEachBufferRange
(
visitor
:
ConsumeEachBufferVisitor
)
=
this
@
toKotlinByteReadChannel
.
consumeEachBufferRange
(
visitor
)
override
suspend
fun
discard
(
max
:
Long
):
Long
=
this
@
toKotlinByteReadChannel
.
discard
(
max
)
@Suppress
(
"EXPERIMENTAL_API_USAGE"
,
"EXPERIMENTAL_OVERRIDE"
)
@ExperimentalIoApi
override
fun
<
R
>
lookAhead
(
visitor
:
LookAheadSession
.()
->
R
):
R
{
return
this
@
toKotlinByteReadChannel
.
lookAhead
l
@
{
visitor
(
object
:
LookAheadSession
{
override
fun
consumed
(
n
:
Int
)
{
return
this
@
l
.
consumed
(
n
)
}
override
fun
request
(
skip
:
Int
,
atLeast
:
Int
):
ByteBuffer
?
{
return
this
@
l
.
request
(
skip
,
atLeast
)
}
})
}
}
@Suppress
(
"EXPERIMENTAL_API_USAGE"
,
"EXPERIMENTAL_OVERRIDE"
)
@ExperimentalIoApi
override
suspend
fun
<
R
>
lookAheadSuspend
(
visitor
:
suspend
LookAheadSuspendSession
.()
->
R
):
R
=
this
@
toKotlinByteReadChannel
.
lookAheadSuspend
l
@
{
visitor
(
object
:
LookAheadSuspendSession
{
override
suspend
fun
awaitAtLeast
(
n
:
Int
):
Boolean
{
return
this
@
l
.
awaitAtLeast
(
n
)
}
override
fun
consumed
(
n
:
Int
)
{
return
this
@
l
.
consumed
(
n
)
}
override
fun
request
(
skip
:
Int
,
atLeast
:
Int
):
ByteBuffer
?
{
return
this
@
l
.
request
(
skip
,
atLeast
)
}
})
}
override
suspend
fun
read
(
min
:
Int
,
consumer
:
(
ByteBuffer
)
->
Unit
)
=
this
@
toKotlinByteReadChannel
.
read
(
min
,
consumer
)
override
suspend
fun
readAvailable
(
dst
:
ByteBuffer
):
Int
=
this
@
toKotlinByteReadChannel
.
readAvailable
(
dst
)
override
suspend
fun
readAvailable
(
dst
:
ByteArray
,
offset
:
Int
,
length
:
Int
):
Int
=
this
@
toKotlinByteReadChannel
.
readAvailable
(
dst
,
offset
,
length
)
override
suspend
fun
readAvailable
(
dst
:
IoBuffer
):
Int
{
ByteArrayPool
.
useInstance
{
val
read
=
this
@
toKotlinByteReadChannel
.
readAvailable
(
it
,
0
,
it
.
size
)
dst
.
writeFully
(
it
,
0
,
read
)
return
read
}
}
override
suspend
fun
readBoolean
():
Boolean
=
this
@
toKotlinByteReadChannel
.
readBoolean
()
override
suspend
fun
readByte
():
Byte
=
this
@
toKotlinByteReadChannel
.
readByte
()
override
suspend
fun
readDouble
():
Double
=
this
@
toKotlinByteReadChannel
.
readDouble
()
override
suspend
fun
readFloat
():
Float
=
this
@
toKotlinByteReadChannel
.
readFloat
()
override
suspend
fun
readFully
(
dst
:
ByteBuffer
):
Int
{
TODO
(
"not implemented"
)
}
override
suspend
fun
readFully
(
dst
:
ByteArray
,
offset
:
Int
,
length
:
Int
)
=
this
@
toKotlinByteReadChannel
.
readFully
(
dst
,
offset
,
length
)
override
suspend
fun
readFully
(
dst
:
IoBuffer
,
n
:
Int
)
{
ByteArrayPool
.
useInstance
{
dst
.
writeFully
(
it
,
0
,
this
.
readAvailable
(
it
,
0
,
it
.
size
))
}
}
override
suspend
fun
readInt
():
Int
=
this
@
toKotlinByteReadChannel
.
readInt
()
override
suspend
fun
readLong
():
Long
=
this
@
toKotlinByteReadChannel
.
readLong
()
override
suspend
fun
readPacket
(
size
:
Int
,
headerSizeHint
:
Int
):
ByteReadPacket
{
return
this
@
toKotlinByteReadChannel
.
readPacket
(
size
,
headerSizeHint
).
readBytes
().
toReadPacket
()
}
override
suspend
fun
readRemaining
(
limit
:
Long
,
headerSizeHint
:
Int
):
ByteReadPacket
{
return
this
@
toKotlinByteReadChannel
.
readRemaining
(
limit
,
headerSizeHint
).
readBytes
().
toReadPacket
()
}
@UseExperimental
(
ExperimentalIoApi
::
class
)
@ExperimentalIoApi
override
fun
readSession
(
consumer
:
ReadSession
.()
->
Unit
)
{
@Suppress
(
"DEPRECATION"
)
this
@
toKotlinByteReadChannel
.
readSession
lambda
@
{
consumer
(
object
:
ReadSession
{
override
val
availableForRead
:
Int
get
()
=
this
@
lambda
.
availableForRead
override
fun
discard
(
n
:
Int
):
Int
=
this
@
lambda
.
discard
(
n
)
override
fun
request
(
atLeast
:
Int
):
IoBuffer
?
{
val
ioBuffer
:
io
.
ktor
.
utils
.
io
.
core
.
IoBuffer
=
this
@
lambda
.
request
(
atLeast
)
?:
return
null
val
buffer
=
IoBuffer
.
Pool
.
borrow
()
val
bytes
=
(
ioBuffer
as
Input
).
readBytes
()
buffer
.
writeFully
(
bytes
)
return
buffer
}
})
}
}
override
suspend
fun
readShort
():
Short
=
this
@
toKotlinByteReadChannel
.
readShort
()
@Suppress
(
"EXPERIMENTAL_OVERRIDE"
,
"EXPERIMENTAL_API_USAGE"
)
@ExperimentalIoApi
override
suspend
fun
readSuspendableSession
(
consumer
:
suspend
SuspendableReadSession
.()
->
Unit
)
=
this
@
toKotlinByteReadChannel
.
readSuspendableSession
l
@
{
consumer
(
object
:
SuspendableReadSession
{
override
val
availableForRead
:
Int
get
()
=
this
@
l
.
availableForRead
override
suspend
fun
await
(
atLeast
:
Int
):
Boolean
=
this
@
l
.
await
(
atLeast
)
override
fun
discard
(
n
:
Int
):
Int
=
this
@
l
.
discard
(
n
)
override
fun
request
(
atLeast
:
Int
):
IoBuffer
?
{
@Suppress
(
"DuplicatedCode"
)
val
ioBuffer
:
io
.
ktor
.
utils
.
io
.
core
.
IoBuffer
=
this
@
l
.
request
(
atLeast
)
?:
return
null
val
buffer
=
IoBuffer
.
Pool
.
borrow
()
val
bytes
=
(
ioBuffer
as
Input
).
readBytes
()
buffer
.
writeFully
(
bytes
)
return
buffer
}
})
}
override
suspend
fun
readUTF8Line
(
limit
:
Int
):
String
?
=
this
@
toKotlinByteReadChannel
.
readUTF8Line
(
limit
)
override
suspend
fun
<
A
:
Appendable
>
readUTF8LineTo
(
out
:
A
,
limit
:
Int
):
Boolean
=
this
@
toKotlinByteReadChannel
.
readUTF8LineTo
(
out
,
limit
)
}
}
\ No newline at end of file
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.kt
View file @
e60a6bcf
...
@@ -11,8 +11,8 @@ package net.mamoe.mirai.qqandroid
...
@@ -11,8 +11,8 @@ package net.mamoe.mirai.qqandroid
import
io.ktor.client.request.get
import
io.ktor.client.request.get
import
io.ktor.client.statement.HttpResponse
import
io.ktor.client.statement.HttpResponse
import
io.ktor.utils.io.ByteReadChannel
import
kotlinx.coroutines.CoroutineName
import
kotlinx.coroutines.CoroutineName
import
kotlinx.coroutines.io.ByteReadChannel
import
net.mamoe.mirai.BotAccount
import
net.mamoe.mirai.BotAccount
import
net.mamoe.mirai.BotImpl
import
net.mamoe.mirai.BotImpl
import
net.mamoe.mirai.LowLevelAPI
import
net.mamoe.mirai.LowLevelAPI
...
@@ -222,6 +222,10 @@ internal abstract class QQAndroidBotBase constructor(
...
@@ -222,6 +222,10 @@ internal abstract class QQAndroidBotBase constructor(
}
}
override
suspend
fun
openChannel
(
image
:
Image
):
ByteReadChannel
{
override
suspend
fun
openChannel
(
image
:
Image
):
ByteReadChannel
{
return
Http
.
get
<
HttpResponse
>(
queryImageUrl
(
image
)).
content
return
Http
.
get
<
HttpResponse
>(
queryImageUrl
(
image
)).
content
.
toKotlinByteReadChannel
()
}
}
}
}
\ No newline at end of file
@Suppress
(
"DEPRECATION"
)
@UseExperimental
(
MiraiInternalAPI
::
class
)
internal
expect
fun
io
.
ktor
.
utils
.
io
.
ByteReadChannel
.
toKotlinByteReadChannel
():
ByteReadChannel
\ No newline at end of file
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt
View file @
e60a6bcf
...
@@ -9,12 +9,15 @@
...
@@ -9,12 +9,15 @@
package
net.mamoe.mirai.qqandroid.network
package
net.mamoe.mirai.qqandroid.network
import
io.ktor.utils.io.core.*
import
kotlinx.atomicfu.AtomicRef
import
kotlinx.atomicfu.AtomicRef
import
kotlinx.atomicfu.atomic
import
kotlinx.atomicfu.atomic
import
kotlinx.coroutines.*
import
kotlinx.coroutines.*
import
kotlinx.coroutines.sync.Mutex
import
kotlinx.coroutines.sync.Mutex
import
kotlinx.coroutines.sync.withLock
import
kotlinx.coroutines.sync.withLock
import
kotlinx.io.core.ByteReadPacket
import
kotlinx.io.core.Input
import
kotlinx.io.core.buildPacket
import
kotlinx.io.core.use
import
net.mamoe.mirai.data.MultiPacket
import
net.mamoe.mirai.data.MultiPacket
import
net.mamoe.mirai.data.Packet
import
net.mamoe.mirai.data.Packet
import
net.mamoe.mirai.event.*
import
net.mamoe.mirai.event.*
...
@@ -67,14 +70,14 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
...
@@ -67,14 +70,14 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
_packetReceiverJob
?.
join
()
_packetReceiverJob
?.
join
()
return
this
.
launch
(
CoroutineName
(
"Incoming Packet Receiver"
))
{
return
this
.
launch
(
CoroutineName
(
"Incoming Packet Receiver"
))
{
while
(
channel
.
isOpen
)
{
while
(
channel
.
isOpen
&&
isActive
)
{
val
rawInput
=
try
{
val
rawInput
=
try
{
channel
.
read
()
channel
.
read
()
}
catch
(
e
:
CancellationException
)
{
}
catch
(
e
:
CancellationException
)
{
return
@
launch
return
@
launch
}
catch
(
e
:
Throwable
)
{
}
catch
(
e
:
Throwable
)
{
if
(
this
@QQAndroidBotNetworkHandler
.
isActive
)
{
if
(
this
@QQAndroidBotNetworkHandler
.
isActive
)
{
BotOfflineEvent
.
Dropped
(
bot
,
e
).
broadcast
()
bot
.
launch
{
BotOfflineEvent
.
Dropped
(
bot
,
e
).
broadcast
()
}
}
}
return
@
launch
return
@
launch
}
}
...
@@ -141,10 +144,7 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
...
@@ -141,10 +144,7 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
continue
@
mainloop
continue
@
mainloop
}
}
is
WtLogin
.
Login
.
LoginPacketResponse
.
Captcha
.
Slider
->
{
is
WtLogin
.
Login
.
LoginPacketResponse
.
Captcha
.
Slider
->
{
var
ticket
=
bot
.
configuration
.
loginSolver
.
onSolveSliderCaptcha
(
bot
,
response
.
url
)
val
ticket
=
bot
.
configuration
.
loginSolver
.
onSolveSliderCaptcha
(
bot
,
response
.
url
).
orEmpty
()
if
(
ticket
==
null
)
{
ticket
=
""
}
response
=
WtLogin
.
Login
.
SubCommand2
.
SubmitSliderCaptcha
(
bot
.
client
,
ticket
).
sendAndExpect
()
response
=
WtLogin
.
Login
.
SubCommand2
.
SubmitSliderCaptcha
(
bot
.
client
,
ticket
).
sendAndExpect
()
continue
@
mainloop
continue
@
mainloop
}
}
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidClient.kt
View file @
e60a6bcf
...
@@ -159,8 +159,8 @@ internal open class QQAndroidClient(
...
@@ -159,8 +159,8 @@ internal open class QQAndroidClient(
val
uin
:
Long
get
()
=
_uin
val
uin
:
Long
get
()
=
_uin
@UseExperimental
(
RawAccountIdUse
::
class
)
@UseExperimental
(
RawAccountIdUse
::
class
)
@Suppress
(
"PropertyName"
)
@Suppress
(
"PropertyName"
,
"DEPRECATION_ERROR"
)
internal
var
_uin
:
Long
=
bot
.
uin
internal
var
_uin
:
Long
=
bot
.
account
.
id
var
t530
:
ByteArray
?
=
null
var
t530
:
ByteArray
?
=
null
var
t528
:
ByteArray
?
=
null
var
t528
:
ByteArray
?
=
null
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/highway/HighwayHelper.kt
View file @
e60a6bcf
...
@@ -16,10 +16,10 @@ import io.ktor.http.HttpStatusCode
...
@@ -16,10 +16,10 @@ import io.ktor.http.HttpStatusCode
import
io.ktor.http.URLProtocol
import
io.ktor.http.URLProtocol
import
io.ktor.http.content.OutgoingContent
import
io.ktor.http.content.OutgoingContent
import
io.ktor.http.userAgent
import
io.ktor.http.userAgent
import
io.ktor.utils.io.ByteReadChannel
import
io.ktor.utils.io.ByteWriteChannel
import
io.ktor.utils.io.copyAndClose
import
kotlinx.coroutines.InternalCoroutinesApi
import
kotlinx.coroutines.InternalCoroutinesApi
import
kotlinx.coroutines.flow.collect
import
kotlinx.coroutines.flow.collect
import
kotlinx.coroutines.io.ByteReadChannel
import
kotlinx.io.InputStream
import
kotlinx.io.InputStream
import
kotlinx.io.core.Input
import
kotlinx.io.core.Input
import
kotlinx.io.core.discardExact
import
kotlinx.io.core.discardExact
...
@@ -30,6 +30,7 @@ import net.mamoe.mirai.qqandroid.io.serialization.readProtoBuf
...
@@ -30,6 +30,7 @@ import net.mamoe.mirai.qqandroid.io.serialization.readProtoBuf
import
net.mamoe.mirai.qqandroid.network.QQAndroidClient
import
net.mamoe.mirai.qqandroid.network.QQAndroidClient
import
net.mamoe.mirai.qqandroid.network.protocol.data.proto.CSDataHighwayHead
import
net.mamoe.mirai.qqandroid.network.protocol.data.proto.CSDataHighwayHead
import
net.mamoe.mirai.utils.MiraiInternalAPI
import
net.mamoe.mirai.utils.MiraiInternalAPI
import
net.mamoe.mirai.utils.copyAndClose
import
net.mamoe.mirai.utils.io.ByteArrayPool
import
net.mamoe.mirai.utils.io.ByteArrayPool
import
net.mamoe.mirai.utils.io.PlatformSocket
import
net.mamoe.mirai.utils.io.PlatformSocket
import
net.mamoe.mirai.utils.io.withUse
import
net.mamoe.mirai.utils.io.withUse
...
@@ -67,7 +68,7 @@ internal suspend fun HttpClient.postImage(
...
@@ -67,7 +68,7 @@ internal suspend fun HttpClient.postImage(
override
val
contentType
:
ContentType
=
ContentType
.
Image
.
Any
override
val
contentType
:
ContentType
=
ContentType
.
Image
.
Any
override
val
contentLength
:
Long
=
inputSize
override
val
contentLength
:
Long
=
inputSize
override
suspend
fun
writeTo
(
channel
:
io
.
ktor
.
utils
.
io
.
ByteWriteChannel
)
{
override
suspend
fun
writeTo
(
channel
:
ByteWriteChannel
)
{
ByteArrayPool
.
useInstance
{
buffer
:
ByteArray
->
ByteArrayPool
.
useInstance
{
buffer
:
ByteArray
->
when
(
imageInput
)
{
when
(
imageInput
)
{
is
Input
->
{
is
Input
->
{
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/highway/highway.kt
View file @
e60a6bcf
...
@@ -11,9 +11,9 @@
...
@@ -11,9 +11,9 @@
package
net.mamoe.mirai.qqandroid.network.highway
package
net.mamoe.mirai.qqandroid.network.highway
import
io.ktor.utils.io.ByteReadChannel
import
kotlinx.coroutines.flow.Flow
import
kotlinx.coroutines.flow.Flow
import
kotlinx.coroutines.flow.map
import
kotlinx.coroutines.flow.map
import
kotlinx.coroutines.io.ByteReadChannel
import
kotlinx.io.InputStream
import
kotlinx.io.InputStream
import
kotlinx.io.core.ByteReadPacket
import
kotlinx.io.core.ByteReadPacket
import
kotlinx.io.core.Input
import
kotlinx.io.core.Input
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/Cmd0x857.kt
0 → 100644
View file @
e60a6bcf
This diff is collapsed.
Click to expand it.
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.kt
View file @
e60a6bcf
...
@@ -9,13 +9,10 @@
...
@@ -9,13 +9,10 @@
package
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive
package
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive
import
kotlinx.coroutines.Deferred
import
kotlinx.coroutines.ExperimentalCoroutinesApi
import
kotlinx.coroutines.FlowPreview
import
kotlinx.coroutines.FlowPreview
import
kotlinx.coroutines.flow.*
import
kotlinx.coroutines.flow.*
import
kotlinx.io.core.ByteReadPacket
import
kotlinx.io.core.ByteReadPacket
import
kotlinx.io.core.discardExact
import
kotlinx.io.core.discardExact
import
net.mamoe.mirai.contact.Contact
import
net.mamoe.mirai.contact.Group
import
net.mamoe.mirai.contact.Group
import
net.mamoe.mirai.contact.MemberPermission
import
net.mamoe.mirai.contact.MemberPermission
import
net.mamoe.mirai.data.MemberInfo
import
net.mamoe.mirai.data.MemberInfo
...
@@ -281,60 +278,6 @@ internal class MessageSvc {
...
@@ -281,60 +278,6 @@ internal class MessageSvc {
}
}
}
}
internal
class
MessageSourceFromSendFriend
(
val
messageRandom
:
Int
,
override
val
time
:
Long
,
override
val
qqId
:
Long
,
override
val
groupId
:
Long
,
val
sequenceId
:
Int
)
:
MessageSource
{
@UseExperimental
(
ExperimentalCoroutinesApi
::
class
)
override
val
id
:
Long
get
()
=
sequenceId
.
toLong
().
shl
(
32
)
or
messageRandom
.
toLong
().
and
(
0
xFFFFFFFF
)
override
suspend
fun
ensureSequenceIdAvailable
()
{
// nothing to do
}
override
fun
toString
():
String
{
return
""
}
}
internal
class
MessageSourceFromSendGroup
(
val
messageRandom
:
Int
,
override
val
time
:
Long
,
override
val
qqId
:
Long
,
override
val
groupId
:
Long
// ,
// override val sourceMessage: MessageChain
)
:
MessageSource
{
private
lateinit
var
sequenceIdDeferred
:
Deferred
<
Int
>
@UseExperimental
(
ExperimentalCoroutinesApi
::
class
)
override
val
id
:
Long
get
()
=
sequenceIdDeferred
.
getCompleted
().
toLong
().
shl
(
32
)
or
messageRandom
.
toLong
().
and
(
0
xFFFFFFFF
)
@UseExperimental
(
MiraiExperimentalAPI
::
class
)
fun
startWaitingSequenceId
(
contact
:
Contact
)
{
sequenceIdDeferred
=
contact
.
subscribingGetAsync
<
OnlinePush
.
PbPushGroupMsg
.
SendGroupMessageReceipt
,
Int
>(
timeoutMillis
=
3000
)
{
if
(
it
.
messageRandom
==
this
@MessageSourceFromSendGroup
.
messageRandom
)
{
it
.
sequenceId
}
else
null
}
}
override
suspend
fun
ensureSequenceIdAvailable
()
{
sequenceIdDeferred
.
join
()
}
override
fun
toString
():
String
{
return
""
}
}
inline
fun
ToFriend
(
inline
fun
ToFriend
(
client
:
QQAndroidClient
,
client
:
QQAndroidClient
,
toUin
:
Long
,
toUin
:
Long
,
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/OnlinePush.kt
View file @
e60a6bcf
...
@@ -11,7 +11,7 @@
...
@@ -11,7 +11,7 @@
package
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive
package
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive
import
io.ktor.utils
.io.core.*
import
kotlinx
.io.core.*
import
net.mamoe.mirai.contact.MemberPermission
import
net.mamoe.mirai.contact.MemberPermission
import
net.mamoe.mirai.data.MultiPacketBySequence
import
net.mamoe.mirai.data.MultiPacketBySequence
import
net.mamoe.mirai.data.NoPacket
import
net.mamoe.mirai.data.NoPacket
...
@@ -341,7 +341,7 @@ internal class OnlinePush {
...
@@ -341,7 +341,7 @@ internal class OnlinePush {
}
}
}
}
0
x11
->
{
0
x11
->
{
discard
(
1
)
discard
Exact
(
1
)
val
proto
=
readProtoBuf
(
TroopTips0x857
.
NotifyMsgBody
.
serializer
())
val
proto
=
readProtoBuf
(
TroopTips0x857
.
NotifyMsgBody
.
serializer
())
proto
.
optMsgRecall
?.
let
{
recallReminder
->
proto
.
optMsgRecall
?.
let
{
recallReminder
->
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/WtLogin.kt
View file @
e60a6bcf
...
@@ -127,7 +127,7 @@ internal class WtLogin {
...
@@ -127,7 +127,7 @@ internal class WtLogin {
private
const
val
appId
=
16L
private
const
val
appId
=
16L
private
const
val
subAppId
=
537062845L
private
const
val
subAppId
=
537062845L
@UseExperimental
(
MiraiInternalAPI
::
class
)
@UseExperimental
(
MiraiInternalAPI
::
class
,
MiraiExperimentalAPI
::
class
)
operator
fun
invoke
(
operator
fun
invoke
(
client
:
QQAndroidClient
client
:
QQAndroidClient
):
OutgoingPacket
=
buildLoginOutgoingPacket
(
client
,
bodyType
=
2
)
{
sequenceId
->
):
OutgoingPacket
=
buildLoginOutgoingPacket
(
client
,
bodyType
=
2
)
{
sequenceId
->
...
@@ -288,7 +288,7 @@ internal class WtLogin {
...
@@ -288,7 +288,7 @@ internal class WtLogin {
}
}
class
Picture
(
class
Picture
(
val
data
:
IoBuffer
,
val
data
:
ByteArray
,
val
sign
:
ByteArray
val
sign
:
ByteArray
)
:
Captcha
()
{
)
:
Captcha
()
{
override
fun
toString
():
String
=
"LoginPacketResponse.Captcha.Picture"
override
fun
toString
():
String
=
"LoginPacketResponse.Captcha.Picture"
...
@@ -394,11 +394,8 @@ internal class WtLogin {
...
@@ -394,11 +394,8 @@ internal class WtLogin {
imageData
.
discardExact
(
2
)
//image Length
imageData
.
discardExact
(
2
)
//image Length
val
sign
=
imageData
.
readBytes
(
signInfoLength
.
toInt
())
val
sign
=
imageData
.
readBytes
(
signInfoLength
.
toInt
())
val
buffer
=
IoBuffer
.
Pool
.
borrow
()
imageData
.
readAvailable
(
buffer
)
return
LoginPacketResponse
.
Captcha
.
Picture
(
return
LoginPacketResponse
.
Captcha
.
Picture
(
data
=
buffer
,
data
=
imageData
.
readBytes
()
,
sign
=
sign
sign
=
sign
)
)
// } else error("UNKNOWN CAPTCHA QUESTION: ${question.toUHexString()}, tlvMap=" + tlvMap.contentToString())
// } else error("UNKNOWN CAPTCHA QUESTION: ${question.toUHexString()}, tlvMap=" + tlvMap.contentToString())
...
...
mirai-core-qqandroid/src/jvmMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.kt
View file @
e60a6bcf
...
@@ -9,19 +9,189 @@
...
@@ -9,19 +9,189 @@
package
net.mamoe.mirai.qqandroid
package
net.mamoe.mirai.qqandroid
import
io.ktor.utils.io.ByteReadChannel
import
io.ktor.utils.io.consumeEachBufferRange
import
io.ktor.utils.io.core.Input
import
io.ktor.utils.io.core.readBytes
import
kotlinx.coroutines.io.*
import
kotlinx.io.core.*
import
kotlinx.io.pool.useInstance
import
net.mamoe.mirai.BotAccount
import
net.mamoe.mirai.BotAccount
import
net.mamoe.mirai.utils.BotConfiguration
import
net.mamoe.mirai.utils.BotConfiguration
import
net.mamoe.mirai.utils.Context
import
net.mamoe.mirai.utils.Context
import
net.mamoe.mirai.utils.ContextImpl
import
net.mamoe.mirai.utils.ContextImpl
import
net.mamoe.mirai.utils.MiraiInternalAPI
import
net.mamoe.mirai.utils.MiraiInternalAPI
import
net.mamoe.mirai.utils.io.ByteArrayPool
import
net.mamoe.mirai.utils.io.toReadPacket
import
java.nio.ByteBuffer
@UseExperimental
(
MiraiInternalAPI
::
class
)
@UseExperimental
(
MiraiInternalAPI
::
class
)
@Suppress
(
"FunctionName"
)
@Suppress
(
"FunctionName"
)
internal
fun
QQAndroidBot
(
account
:
BotAccount
,
configuration
:
BotConfiguration
):
QQAndroidBot
=
QQAndroidBot
(
ContextImpl
(),
account
,
configuration
)
internal
fun
QQAndroidBot
(
account
:
BotAccount
,
configuration
:
BotConfiguration
):
QQAndroidBot
=
QQAndroidBot
(
ContextImpl
(),
account
,
configuration
)
@UseExperimental
(
MiraiInternalAPI
::
class
)
@UseExperimental
(
MiraiInternalAPI
::
class
)
internal
actual
class
QQAndroidBot
actual
constructor
(
internal
actual
class
QQAndroidBot
actual
constructor
(
context
:
Context
,
context
:
Context
,
account
:
BotAccount
,
account
:
BotAccount
,
configuration
:
BotConfiguration
configuration
:
BotConfiguration
)
:
QQAndroidBotBase
(
context
,
account
,
configuration
)
)
:
QQAndroidBotBase
(
context
,
account
,
configuration
)
\ No newline at end of file
@UseExperimental
(
MiraiInternalAPI
::
class
)
@Suppress
(
"DEPRECATION"
)
internal
actual
fun
ByteReadChannel
.
toKotlinByteReadChannel
():
kotlinx
.
coroutines
.
io
.
ByteReadChannel
{
return
object
: kotlinx.coroutines.io.
ByteReadChannel
{
override
val
availableForRead
:
Int
get
()
=
this
@
toKotlinByteReadChannel
.
availableForRead
override
val
isClosedForRead
:
Boolean
get
()
=
this
@
toKotlinByteReadChannel
.
isClosedForRead
override
val
isClosedForWrite
:
Boolean
get
()
=
this
@
toKotlinByteReadChannel
.
isClosedForWrite
@Suppress
(
"DEPRECATION_ERROR"
,
"OverridingDeprecatedMember"
)
override
var
readByteOrder
:
ByteOrder
get
()
=
when
(
this
@
toKotlinByteReadChannel
.
readByteOrder
)
{
io
.
ktor
.
utils
.
io
.
core
.
ByteOrder
.
BIG_ENDIAN
->
ByteOrder
.
BIG_ENDIAN
io
.
ktor
.
utils
.
io
.
core
.
ByteOrder
.
LITTLE_ENDIAN
->
ByteOrder
.
LITTLE_ENDIAN
}
set
(
value
)
{
this
@
toKotlinByteReadChannel
.
readByteOrder
=
when
(
value
)
{
ByteOrder
.
BIG_ENDIAN
->
io
.
ktor
.
utils
.
io
.
core
.
ByteOrder
.
BIG_ENDIAN
ByteOrder
.
LITTLE_ENDIAN
->
io
.
ktor
.
utils
.
io
.
core
.
ByteOrder
.
LITTLE_ENDIAN
}
}
@Suppress
(
"DEPRECATION_ERROR"
,
"DEPRECATION"
,
"OverridingDeprecatedMember"
)
override
val
totalBytesRead
:
Long
get
()
=
this
@
toKotlinByteReadChannel
.
totalBytesRead
override
fun
cancel
(
cause
:
Throwable
?):
Boolean
=
this
@
toKotlinByteReadChannel
.
cancel
(
cause
)
override
suspend
fun
consumeEachBufferRange
(
visitor
:
ConsumeEachBufferVisitor
)
=
this
@
toKotlinByteReadChannel
.
consumeEachBufferRange
(
visitor
)
override
suspend
fun
discard
(
max
:
Long
):
Long
=
this
@
toKotlinByteReadChannel
.
discard
(
max
)
@Suppress
(
"EXPERIMENTAL_API_USAGE"
,
"EXPERIMENTAL_OVERRIDE"
)
@ExperimentalIoApi
override
fun
<
R
>
lookAhead
(
visitor
:
LookAheadSession
.()
->
R
):
R
{
return
this
@
toKotlinByteReadChannel
.
lookAhead
l
@
{
visitor
(
object
:
LookAheadSession
{
override
fun
consumed
(
n
:
Int
)
{
return
this
@
l
.
consumed
(
n
)
}
override
fun
request
(
skip
:
Int
,
atLeast
:
Int
):
ByteBuffer
?
{
return
this
@
l
.
request
(
skip
,
atLeast
)
}
})
}
}
@Suppress
(
"EXPERIMENTAL_API_USAGE"
,
"EXPERIMENTAL_OVERRIDE"
)
@ExperimentalIoApi
override
suspend
fun
<
R
>
lookAheadSuspend
(
visitor
:
suspend
LookAheadSuspendSession
.()
->
R
):
R
=
this
@
toKotlinByteReadChannel
.
lookAheadSuspend
l
@
{
visitor
(
object
:
LookAheadSuspendSession
{
override
suspend
fun
awaitAtLeast
(
n
:
Int
):
Boolean
{
return
this
@
l
.
awaitAtLeast
(
n
)
}
override
fun
consumed
(
n
:
Int
)
{
return
this
@
l
.
consumed
(
n
)
}
override
fun
request
(
skip
:
Int
,
atLeast
:
Int
):
ByteBuffer
?
{
return
this
@
l
.
request
(
skip
,
atLeast
)
}
})
}
override
suspend
fun
read
(
min
:
Int
,
consumer
:
(
ByteBuffer
)
->
Unit
)
=
this
@
toKotlinByteReadChannel
.
read
(
min
,
consumer
)
override
suspend
fun
readAvailable
(
dst
:
ByteBuffer
):
Int
=
this
@
toKotlinByteReadChannel
.
readAvailable
(
dst
)
override
suspend
fun
readAvailable
(
dst
:
ByteArray
,
offset
:
Int
,
length
:
Int
):
Int
=
this
@
toKotlinByteReadChannel
.
readAvailable
(
dst
,
offset
,
length
)
override
suspend
fun
readAvailable
(
dst
:
IoBuffer
):
Int
{
ByteArrayPool
.
useInstance
{
val
read
=
this
@
toKotlinByteReadChannel
.
readAvailable
(
it
,
0
,
it
.
size
)
dst
.
writeFully
(
it
,
0
,
read
)
return
read
}
}
override
suspend
fun
readBoolean
():
Boolean
=
this
@
toKotlinByteReadChannel
.
readBoolean
()
override
suspend
fun
readByte
():
Byte
=
this
@
toKotlinByteReadChannel
.
readByte
()
override
suspend
fun
readDouble
():
Double
=
this
@
toKotlinByteReadChannel
.
readDouble
()
override
suspend
fun
readFloat
():
Float
=
this
@
toKotlinByteReadChannel
.
readFloat
()
override
suspend
fun
readFully
(
dst
:
ByteBuffer
):
Int
{
TODO
(
"not implemented"
)
}
override
suspend
fun
readFully
(
dst
:
ByteArray
,
offset
:
Int
,
length
:
Int
)
=
this
@
toKotlinByteReadChannel
.
readFully
(
dst
,
offset
,
length
)
override
suspend
fun
readFully
(
dst
:
IoBuffer
,
n
:
Int
)
{
ByteArrayPool
.
useInstance
{
dst
.
writeFully
(
it
,
0
,
this
.
readAvailable
(
it
,
0
,
it
.
size
))
}
}
override
suspend
fun
readInt
():
Int
=
this
@
toKotlinByteReadChannel
.
readInt
()
override
suspend
fun
readLong
():
Long
=
this
@
toKotlinByteReadChannel
.
readLong
()
override
suspend
fun
readPacket
(
size
:
Int
,
headerSizeHint
:
Int
):
ByteReadPacket
{
return
this
@
toKotlinByteReadChannel
.
readPacket
(
size
,
headerSizeHint
).
readBytes
().
toReadPacket
()
}
override
suspend
fun
readRemaining
(
limit
:
Long
,
headerSizeHint
:
Int
):
ByteReadPacket
{
return
this
@
toKotlinByteReadChannel
.
readRemaining
(
limit
,
headerSizeHint
).
readBytes
().
toReadPacket
()
}
@UseExperimental
(
ExperimentalIoApi
::
class
)
@ExperimentalIoApi
override
fun
readSession
(
consumer
:
ReadSession
.()
->
Unit
)
{
@Suppress
(
"DEPRECATION"
)
this
@
toKotlinByteReadChannel
.
readSession
lambda
@
{
consumer
(
object
:
ReadSession
{
override
val
availableForRead
:
Int
get
()
=
this
@
lambda
.
availableForRead
override
fun
discard
(
n
:
Int
):
Int
=
this
@
lambda
.
discard
(
n
)
override
fun
request
(
atLeast
:
Int
):
IoBuffer
?
{
val
ioBuffer
:
io
.
ktor
.
utils
.
io
.
core
.
IoBuffer
=
this
@
lambda
.
request
(
atLeast
)
?:
return
null
val
buffer
=
IoBuffer
.
Pool
.
borrow
()
val
bytes
=
(
ioBuffer
as
Input
).
readBytes
()
buffer
.
writeFully
(
bytes
)
return
buffer
}
})
}
}
override
suspend
fun
readShort
():
Short
=
this
@
toKotlinByteReadChannel
.
readShort
()
@Suppress
(
"EXPERIMENTAL_OVERRIDE"
,
"EXPERIMENTAL_API_USAGE"
)
@ExperimentalIoApi
override
suspend
fun
readSuspendableSession
(
consumer
:
suspend
SuspendableReadSession
.()
->
Unit
)
=
this
@
toKotlinByteReadChannel
.
readSuspendableSession
l
@
{
consumer
(
object
:
SuspendableReadSession
{
override
val
availableForRead
:
Int
get
()
=
this
@
l
.
availableForRead
override
suspend
fun
await
(
atLeast
:
Int
):
Boolean
=
this
@
l
.
await
(
atLeast
)
override
fun
discard
(
n
:
Int
):
Int
=
this
@
l
.
discard
(
n
)
override
fun
request
(
atLeast
:
Int
):
IoBuffer
?
{
@Suppress
(
"DuplicatedCode"
)
val
ioBuffer
:
io
.
ktor
.
utils
.
io
.
core
.
IoBuffer
=
this
@
l
.
request
(
atLeast
)
?:
return
null
val
buffer
=
IoBuffer
.
Pool
.
borrow
()
val
bytes
=
(
ioBuffer
as
Input
).
readBytes
()
buffer
.
writeFully
(
bytes
)
return
buffer
}
})
}
override
suspend
fun
readUTF8Line
(
limit
:
Int
):
String
?
=
this
@
toKotlinByteReadChannel
.
readUTF8Line
(
limit
)
override
suspend
fun
<
A
:
Appendable
>
readUTF8LineTo
(
out
:
A
,
limit
:
Int
):
Boolean
=
this
@
toKotlinByteReadChannel
.
readUTF8LineTo
(
out
,
limit
)
}
}
\ No newline at end of file
mirai-core/build.gradle.kts
View file @
e60a6bcf
...
@@ -107,6 +107,7 @@ kotlin {
...
@@ -107,6 +107,7 @@ kotlin {
api
(
kotlinx
(
"io-jvm"
,
kotlinXIoVersion
))
api
(
kotlinx
(
"io-jvm"
,
kotlinXIoVersion
))
api
(
kotlinx
(
"serialization-runtime"
,
serializationVersion
))
api
(
kotlinx
(
"serialization-runtime"
,
serializationVersion
))
api
(
kotlinx
(
"coroutines-android"
,
coroutinesVersion
))
api
(
kotlinx
(
"coroutines-android"
,
coroutinesVersion
))
api
(
kotlinx
(
"coroutines-io-jvm"
,
coroutinesIoVersion
))
api
(
ktor
(
"client-android"
,
ktorVersion
))
api
(
ktor
(
"client-android"
,
ktorVersion
))
}
}
...
@@ -131,9 +132,7 @@ kotlin {
...
@@ -131,9 +132,7 @@ kotlin {
api
(
ktor
(
"client-core-jvm"
,
ktorVersion
))
api
(
ktor
(
"client-core-jvm"
,
ktorVersion
))
api
(
kotlinx
(
"io-jvm"
,
kotlinXIoVersion
))
api
(
kotlinx
(
"io-jvm"
,
kotlinXIoVersion
))
api
(
kotlinx
(
"serialization-runtime"
,
serializationVersion
))
api
(
kotlinx
(
"serialization-runtime"
,
serializationVersion
))
api
(
kotlinx
(
"coroutines-io"
,
coroutinesIoVersion
))
api
(
kotlinx
(
"coroutines-io-jvm"
,
coroutinesIoVersion
))
api
(
kotlinx
(
"coroutines-io-jvm"
,
coroutinesIoVersion
))
api
(
kotlinx
(
"io-jvm"
,
coroutinesIoVersion
))
api
(
"org.bouncycastle:bcprov-jdk15on:1.64"
)
api
(
"org.bouncycastle:bcprov-jdk15on:1.64"
)
runtimeOnly
(
files
(
"build/classes/kotlin/jvm/main"
))
// classpath is not properly set by IDE
runtimeOnly
(
files
(
"build/classes/kotlin/jvm/main"
))
// classpath is not properly set by IDE
...
...
mirai-core/src/androidMain/kotlin/net/mamoe/mirai/Bot.kt
View file @
e60a6bcf
...
@@ -2,8 +2,8 @@
...
@@ -2,8 +2,8 @@
package
net.mamoe.mirai
package
net.mamoe.mirai
import
io.ktor.utils.io.ByteReadChannel
import
kotlinx.coroutines.CoroutineScope
import
kotlinx.coroutines.CoroutineScope
import
kotlinx.coroutines.io.ByteReadChannel
import
net.mamoe.mirai.contact.*
import
net.mamoe.mirai.contact.*
import
net.mamoe.mirai.data.AddFriendResult
import
net.mamoe.mirai.data.AddFriendResult
import
net.mamoe.mirai.message.MessageReceipt
import
net.mamoe.mirai.message.MessageReceipt
...
...
mirai-core/src/androidMain/kotlin/net/mamoe/mirai/contact/ContactJavaHappyAPI.kt
View file @
e60a6bcf
...
@@ -10,8 +10,8 @@
...
@@ -10,8 +10,8 @@
package
net.mamoe.mirai.contact
package
net.mamoe.mirai.contact
import
android.graphics.Bitmap
import
android.graphics.Bitmap
import
io.ktor.utils.io.core.Input
import
kotlinx.coroutines.Dispatchers
import
kotlinx.coroutines.Dispatchers
import
kotlinx.io.core.Input
import
net.mamoe.mirai.Bot
import
net.mamoe.mirai.Bot
import
net.mamoe.mirai.JavaHappyAPI
import
net.mamoe.mirai.JavaHappyAPI
import
net.mamoe.mirai.event.events.*
import
net.mamoe.mirai.event.events.*
...
...
mirai-core/src/androidMain/kotlin/net/mamoe/mirai/message/SendImageUtilsAndroid.kt
View file @
e60a6bcf
...
@@ -12,9 +12,9 @@
...
@@ -12,9 +12,9 @@
package
net.mamoe.mirai.message
package
net.mamoe.mirai.message
import
android.graphics.Bitmap
import
android.graphics.Bitmap
import
io.ktor.utils.io.core.Input
import
kotlinx.coroutines.Dispatchers
import
kotlinx.coroutines.Dispatchers
import
kotlinx.coroutines.withContext
import
kotlinx.coroutines.withContext
import
kotlinx.io.core.Input
import
net.mamoe.mirai.contact.Contact
import
net.mamoe.mirai.contact.Contact
import
net.mamoe.mirai.message.data.Image
import
net.mamoe.mirai.message.data.Image
import
net.mamoe.mirai.utils.OverFileSizeMaxException
import
net.mamoe.mirai.utils.OverFileSizeMaxException
...
@@ -36,28 +36,31 @@ import java.net.URL
...
@@ -36,28 +36,31 @@ import java.net.URL
* @throws OverFileSizeMaxException
* @throws OverFileSizeMaxException
*/
*/
@Throws
(
OverFileSizeMaxException
::
class
)
@Throws
(
OverFileSizeMaxException
::
class
)
suspend
fun
Bitmap
.
sendTo
(
contact
:
Contact
)
=
withContext
(
Dispatchers
.
IO
)
{
toExternalImage
()
}.
sendTo
(
contact
)
suspend
fun
<
C
:
Contact
>
Bitmap
.
sendTo
(
contact
:
C
):
MessageReceipt
<
C
>
=
withContext
(
Dispatchers
.
IO
)
{
toExternalImage
()
}.
sendTo
(
contact
)
/**
/**
* 在 [Dispatchers.IO] 中下载 [URL] 到临时文件并将其作为图片发送到指定联系人
* 在 [Dispatchers.IO] 中下载 [URL] 到临时文件并将其作为图片发送到指定联系人
* @throws OverFileSizeMaxException
* @throws OverFileSizeMaxException
*/
*/
@Throws
(
OverFileSizeMaxException
::
class
)
@Throws
(
OverFileSizeMaxException
::
class
)
suspend
fun
URL
.
sendAsImageTo
(
contact
:
Contact
)
=
withContext
(
Dispatchers
.
IO
)
{
toExternalImage
()
}.
sendTo
(
contact
)
suspend
fun
<
C
:
Contact
>
URL
.
sendAsImageTo
(
contact
:
C
):
MessageReceipt
<
C
>
=
withContext
(
Dispatchers
.
IO
)
{
toExternalImage
()
}.
sendTo
(
contact
)
/**
/**
* 在 [Dispatchers.IO] 中读取 [Input] 到临时文件并将其作为图片发送到指定联系人
* 在 [Dispatchers.IO] 中读取 [Input] 到临时文件并将其作为图片发送到指定联系人
* @throws OverFileSizeMaxException
* @throws OverFileSizeMaxException
*/
*/
@Throws
(
OverFileSizeMaxException
::
class
)
@Throws
(
OverFileSizeMaxException
::
class
)
suspend
fun
Input
.
sendAsImageTo
(
contact
:
Contact
)
=
withContext
(
Dispatchers
.
IO
)
{
toExternalImage
()
}.
sendTo
(
contact
)
suspend
fun
<
C
:
Contact
>
Input
.
sendAsImageTo
(
contact
:
C
):
MessageReceipt
<
C
>
=
withContext
(
Dispatchers
.
IO
)
{
toExternalImage
()
}.
sendTo
(
contact
)
/**
/**
* 在 [Dispatchers.IO] 中读取 [InputStream] 到临时文件并将其作为图片发送到指定联系人
* 在 [Dispatchers.IO] 中读取 [InputStream] 到临时文件并将其作为图片发送到指定联系人
* @throws OverFileSizeMaxException
* @throws OverFileSizeMaxException
*/
*/
@Throws
(
OverFileSizeMaxException
::
class
)
@Throws
(
OverFileSizeMaxException
::
class
)
suspend
fun
InputStream
.
sendAsImageTo
(
contact
:
Contact
)
=
suspend
fun
<
C
:
Contact
>
InputStream
.
sendAsImageTo
(
contact
:
C
):
MessageReceipt
<
C
>
=
withContext
(
Dispatchers
.
IO
)
{
toExternalImage
()
}.
sendTo
(
contact
)
withContext
(
Dispatchers
.
IO
)
{
toExternalImage
()
}.
sendTo
(
contact
)
/**
/**
...
@@ -65,9 +68,9 @@ suspend fun InputStream.sendAsImageTo(contact: Contact) =
...
@@ -65,9 +68,9 @@ suspend fun InputStream.sendAsImageTo(contact: Contact) =
* @throws OverFileSizeMaxException
* @throws OverFileSizeMaxException
*/
*/
@Throws
(
OverFileSizeMaxException
::
class
)
@Throws
(
OverFileSizeMaxException
::
class
)
suspend
fun
File
.
sendAsImageTo
(
contact
:
Contact
)
{
suspend
fun
<
C
:
Contact
>
File
.
sendAsImageTo
(
contact
:
C
):
MessageReceipt
<
C
>
{
require
(
this
.
exists
()
&&
this
.
canRead
())
require
(
this
.
exists
()
&&
this
.
canRead
())
withContext
(
Dispatchers
.
IO
)
{
toExternalImage
()
}.
sendTo
(
contact
)
return
withContext
(
Dispatchers
.
IO
)
{
toExternalImage
()
}.
sendTo
(
contact
)
}
}
// endregion
// endregion
...
@@ -124,35 +127,36 @@ suspend fun File.uploadAsImage(contact: Contact): Image {
...
@@ -124,35 +127,36 @@ suspend fun File.uploadAsImage(contact: Contact): Image {
* @throws OverFileSizeMaxException
* @throws OverFileSizeMaxException
*/
*/
@Throws
(
OverFileSizeMaxException
::
class
)
@Throws
(
OverFileSizeMaxException
::
class
)
suspend
inline
fun
Contact
.
sendImage
(
bufferedImage
:
Bitmap
)
=
bufferedImage
.
sendTo
(
this
)
suspend
inline
fun
<
C
:
Contact
>
C
.
sendImage
(
bufferedImage
:
Bitmap
):
MessageReceipt
<
C
>
=
bufferedImage
.
sendTo
(
this
)
/**
/**
* 在 [Dispatchers.IO] 中下载 [URL] 到临时文件并将其作为图片发送到指定联系人
* 在 [Dispatchers.IO] 中下载 [URL] 到临时文件并将其作为图片发送到指定联系人
* @throws OverFileSizeMaxException
* @throws OverFileSizeMaxException
*/
*/
@Throws
(
OverFileSizeMaxException
::
class
)
@Throws
(
OverFileSizeMaxException
::
class
)
suspend
inline
fun
Contact
.
sendImage
(
imageUrl
:
URL
)
=
imageUrl
.
sendAsImageTo
(
this
)
suspend
inline
fun
<
C
:
Contact
>
C
.
sendImage
(
imageUrl
:
URL
):
MessageReceipt
<
C
>
=
imageUrl
.
sendAsImageTo
(
this
)
/**
/**
* 在 [Dispatchers.IO] 中读取 [Input] 到临时文件并将其作为图片发送到指定联系人
* 在 [Dispatchers.IO] 中读取 [Input] 到临时文件并将其作为图片发送到指定联系人
* @throws OverFileSizeMaxException
* @throws OverFileSizeMaxException
*/
*/
@Throws
(
OverFileSizeMaxException
::
class
)
@Throws
(
OverFileSizeMaxException
::
class
)
suspend
inline
fun
Contact
.
sendImage
(
imageInput
:
Input
)
=
imageInput
.
sendAsImageTo
(
this
)
suspend
inline
fun
<
C
:
Contact
>
C
.
sendImage
(
imageInput
:
Input
):
MessageReceipt
<
C
>
=
imageInput
.
sendAsImageTo
(
this
)
/**
/**
* 在 [Dispatchers.IO] 中读取 [InputStream] 到临时文件并将其作为图片发送到指定联系人
* 在 [Dispatchers.IO] 中读取 [InputStream] 到临时文件并将其作为图片发送到指定联系人
* @throws OverFileSizeMaxException
* @throws OverFileSizeMaxException
*/
*/
@Throws
(
OverFileSizeMaxException
::
class
)
@Throws
(
OverFileSizeMaxException
::
class
)
suspend
inline
fun
Contact
.
sendImage
(
imageStream
:
InputStream
)
=
imageStream
.
sendAsImageTo
(
this
)
suspend
inline
fun
<
C
:
Contact
>
C
.
sendImage
(
imageStream
:
InputStream
):
MessageReceipt
<
C
>
=
imageStream
.
sendAsImageTo
(
this
)
/**
/**
* 在 [Dispatchers.IO] 中将文件作为图片发送到指定联系人
* 在 [Dispatchers.IO] 中将文件作为图片发送到指定联系人
* @throws OverFileSizeMaxException
* @throws OverFileSizeMaxException
*/
*/
@Throws
(
OverFileSizeMaxException
::
class
)
@Throws
(
OverFileSizeMaxException
::
class
)
suspend
inline
fun
Contact
.
sendImage
(
file
:
File
)
=
file
.
sendAsImageTo
(
this
)
suspend
inline
fun
<
C
:
Contact
>
C
.
sendImage
(
file
:
File
):
MessageReceipt
<
C
>
=
file
.
sendAsImageTo
(
this
)
// endregion
// endregion
...
...
mirai-core/src/androidMain/kotlin/net/mamoe/mirai/utils/ExternalImageAndroid.kt
View file @
e60a6bcf
...
@@ -31,7 +31,7 @@ import java.net.URL
...
@@ -31,7 +31,7 @@ import java.net.URL
/**
/**
* 读取 [B
ufferedImage
] 的属性, 然后构造 [ExternalImage]
* 读取 [B
itmap
] 的属性, 然后构造 [ExternalImage]
*/
*/
@Throws
(
IOException
::
class
)
@Throws
(
IOException
::
class
)
fun
Bitmap
.
toExternalImage
(
formatName
:
String
=
"gif"
):
Nothing
{
fun
Bitmap
.
toExternalImage
(
formatName
:
String
=
"gif"
):
Nothing
{
...
@@ -123,6 +123,7 @@ fun Input.toExternalImage(): ExternalImage {
...
@@ -123,6 +123,7 @@ fun Input.toExternalImage(): ExternalImage {
*/
*/
suspend
inline
fun
Input
.
suspendToExternalImage
():
ExternalImage
=
withContext
(
IO
)
{
toExternalImage
()
}
suspend
inline
fun
Input
.
suspendToExternalImage
():
ExternalImage
=
withContext
(
IO
)
{
toExternalImage
()
}
/*
/**
/**
* 保存为临时文件然后调用 [File.toExternalImage].
* 保存为临时文件然后调用 [File.toExternalImage].
*/
*/
...
@@ -134,4 +135,4 @@ suspend fun ByteReadChannel.toExternalImage(): ExternalImage {
...
@@ -134,4 +135,4 @@ suspend fun ByteReadChannel.toExternalImage(): ExternalImage {
}
}
return file.suspendToExternalImage()
return file.suspendToExternalImage()
}
}*/
\ No newline at end of file
\ No newline at end of file
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt
View file @
e60a6bcf
...
@@ -11,10 +11,10 @@
...
@@ -11,10 +11,10 @@
package
net.mamoe.mirai
package
net.mamoe.mirai
import
io.ktor.utils.io.ByteReadChannel
import
kotlinx.coroutines.CoroutineName
import
kotlinx.coroutines.CoroutineName
import
kotlinx.coroutines.CoroutineScope
import
kotlinx.coroutines.CoroutineScope
import
kotlinx.coroutines.Job
import
kotlinx.coroutines.Job
import
kotlinx.coroutines.io.ByteReadChannel
import
kotlinx.coroutines.launch
import
kotlinx.coroutines.launch
import
net.mamoe.mirai.contact.*
import
net.mamoe.mirai.contact.*
import
net.mamoe.mirai.data.AddFriendResult
import
net.mamoe.mirai.data.AddFriendResult
...
@@ -89,7 +89,7 @@ expect abstract class Bot() : CoroutineScope, LowLevelBotAPIAccessor {
...
@@ -89,7 +89,7 @@ expect abstract class Bot() : CoroutineScope, LowLevelBotAPIAccessor {
// region contacts
// region contacts
/**
/**
* [
_lowLevelNew
QQ.id] 与 [Bot.uin] 相同的 [_lowLevelNewQQ] 实例
* [QQ.id] 与 [Bot.uin] 相同的 [_lowLevelNewQQ] 实例
*/
*/
abstract
val
selfQQ
:
QQ
abstract
val
selfQQ
:
QQ
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/MessagePacket.kt
View file @
e60a6bcf
...
@@ -11,7 +11,7 @@
...
@@ -11,7 +11,7 @@
package
net.mamoe.mirai.message
package
net.mamoe.mirai.message
import
io.ktor.util
s.io.ByteReadChannel
import
kotlinx.coroutine
s.io.ByteReadChannel
import
net.mamoe.mirai.Bot
import
net.mamoe.mirai.Bot
import
net.mamoe.mirai.contact.Contact
import
net.mamoe.mirai.contact.Contact
import
net.mamoe.mirai.contact.Group
import
net.mamoe.mirai.contact.Group
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/ExternalImage.kt
View file @
e60a6bcf
...
@@ -11,7 +11,7 @@
...
@@ -11,7 +11,7 @@
package
net.mamoe.mirai.utils
package
net.mamoe.mirai.utils
import
io.ktor.util
s.io.ByteReadChannel
import
kotlinx.coroutine
s.io.ByteReadChannel
import
kotlinx.io.InputStream
import
kotlinx.io.InputStream
import
kotlinx.io.core.ByteReadPacket
import
kotlinx.io.core.ByteReadPacket
import
kotlinx.io.core.Input
import
kotlinx.io.core.Input
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/channels.kt
View file @
e60a6bcf
...
@@ -14,8 +14,9 @@
...
@@ -14,8 +14,9 @@
package
net.mamoe.mirai.utils
package
net.mamoe.mirai.utils
import
io.ktor.utils.io.ByteReadChannel
import
kotlinx.coroutines.io.ByteReadChannel
import
io.ktor.utils.io.readAvailable
import
kotlinx.coroutines.io.ByteWriteChannel
import
kotlinx.coroutines.io.readAvailable
import
kotlinx.io.OutputStream
import
kotlinx.io.OutputStream
import
kotlinx.io.core.Output
import
kotlinx.io.core.Output
import
kotlinx.io.pool.useInstance
import
kotlinx.io.pool.useInstance
...
@@ -120,6 +121,7 @@ suspend fun ByteReadChannel.copyAndClose(dst: Output) {
...
@@ -120,6 +121,7 @@ suspend fun ByteReadChannel.copyAndClose(dst: Output) {
* 从接收者管道读取所有数据并写入 [dst], 最终关闭 [dst]
* 从接收者管道读取所有数据并写入 [dst], 最终关闭 [dst]
*/
*/
suspend
fun
ByteReadChannel
.
copyAndClose
(
dst
:
ByteWriteChannel
)
{
suspend
fun
ByteReadChannel
.
copyAndClose
(
dst
:
ByteWriteChannel
)
{
@Suppress
(
"DuplicatedCode"
)
try
{
try
{
@UseExperimental
(
MiraiInternalAPI
::
class
)
@UseExperimental
(
MiraiInternalAPI
::
class
)
ByteArrayPool
.
useInstance
{
buffer
->
ByteArrayPool
.
useInstance
{
buffer
->
...
@@ -130,7 +132,26 @@ suspend fun ByteReadChannel.copyAndClose(dst: ByteWriteChannel) {
...
@@ -130,7 +132,26 @@ suspend fun ByteReadChannel.copyAndClose(dst: ByteWriteChannel) {
}
}
}
finally
{
}
finally
{
@Suppress
(
"DuplicatedCode"
)
@Suppress
(
"DuplicatedCode"
)
dst
.
close
()
dst
.
close
(
null
)
}
}
/**
* 从接收者管道读取所有数据并写入 [dst], 最终关闭 [dst]
*/
suspend
fun
ByteReadChannel
.
copyAndClose
(
dst
:
io
.
ktor
.
utils
.
io
.
ByteWriteChannel
)
{
@Suppress
(
"DuplicatedCode"
)
try
{
@UseExperimental
(
MiraiInternalAPI
::
class
)
ByteArrayPool
.
useInstance
{
buffer
->
var
size
:
Int
while
(
this
.
readAvailable
(
buffer
).
also
{
size
=
it
}
>
0
)
{
dst
.
writeFully
(
buffer
,
0
,
size
)
}
}
}
finally
{
@Suppress
(
"DuplicatedCode"
)
dst
.
close
(
null
)
}
}
}
}
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/io/chunked.kt
View file @
e60a6bcf
...
@@ -9,11 +9,11 @@
...
@@ -9,11 +9,11 @@
package
net.mamoe.mirai.utils.io
package
net.mamoe.mirai.utils.io
import
io.ktor.utils.io.ByteReadChannel
import
kotlinx.coroutines.ExperimentalCoroutinesApi
import
kotlinx.coroutines.ExperimentalCoroutinesApi
import
kotlinx.coroutines.flow.Flow
import
kotlinx.coroutines.flow.Flow
import
kotlinx.coroutines.flow.flow
import
kotlinx.coroutines.flow.flow
import
kotlinx.coroutines.flow.flowOf
import
kotlinx.coroutines.flow.flowOf
import
kotlinx.coroutines.io.ByteReadChannel
import
kotlinx.io.InputStream
import
kotlinx.io.InputStream
import
kotlinx.io.core.ByteReadPacket
import
kotlinx.io.core.ByteReadPacket
import
kotlinx.io.core.Input
import
kotlinx.io.core.Input
...
...
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/Bot.kt
View file @
e60a6bcf
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
package
net.mamoe.mirai
package
net.mamoe.mirai
import
io.ktor.util
s.io.ByteReadChannel
import
kotlinx.coroutine
s.io.ByteReadChannel
import
kotlinx.coroutines.CoroutineScope
import
kotlinx.coroutines.CoroutineScope
import
net.mamoe.mirai.contact.*
import
net.mamoe.mirai.contact.*
import
net.mamoe.mirai.data.AddFriendResult
import
net.mamoe.mirai.data.AddFriendResult
...
...
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/contact/ContactJavaHappyAPI.kt
View file @
e60a6bcf
...
@@ -9,8 +9,8 @@
...
@@ -9,8 +9,8 @@
package
net.mamoe.mirai.contact
package
net.mamoe.mirai.contact
import
io.ktor.utils.io.core.Input
import
kotlinx.coroutines.Dispatchers
import
kotlinx.coroutines.Dispatchers
import
kotlinx.io.core.Input
import
net.mamoe.mirai.Bot
import
net.mamoe.mirai.Bot
import
net.mamoe.mirai.JavaHappyAPI
import
net.mamoe.mirai.JavaHappyAPI
import
net.mamoe.mirai.event.events.*
import
net.mamoe.mirai.event.events.*
...
...
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/message/MessagePacket.kt
View file @
e60a6bcf
...
@@ -11,9 +11,9 @@
...
@@ -11,9 +11,9 @@
package
net.mamoe.mirai.message
package
net.mamoe.mirai.message
import
io.ktor.util
s.io.ByteWriteChannel
import
kotlinx.coroutine
s.io.ByteWriteChannel
import
kotlinx.io.core.Input
import
kotlinx.io.core.Input
import
io.ktor.utils
.io.core.Output
import
kotlinx
.io.core.Output
import
kotlinx.io.core.use
import
kotlinx.io.core.use
import
net.mamoe.mirai.contact.Contact
import
net.mamoe.mirai.contact.Contact
import
net.mamoe.mirai.contact.QQ
import
net.mamoe.mirai.contact.QQ
...
...
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/message/SendImageUtilsJvm.kt
View file @
e60a6bcf
...
@@ -37,28 +37,32 @@ import java.net.URL
...
@@ -37,28 +37,32 @@ import java.net.URL
* @throws OverFileSizeMaxException
* @throws OverFileSizeMaxException
*/
*/
@Throws
(
OverFileSizeMaxException
::
class
)
@Throws
(
OverFileSizeMaxException
::
class
)
suspend
fun
<
C
:
Contact
>
BufferedImage
.
sendTo
(
contact
:
C
):
MessageReceipt
<
C
>
=
withContext
(
Dispatchers
.
IO
)
{
toExternalImage
()
}.
sendTo
(
contact
)
suspend
fun
<
C
:
Contact
>
BufferedImage
.
sendTo
(
contact
:
C
):
MessageReceipt
<
C
>
=
withContext
(
Dispatchers
.
IO
)
{
toExternalImage
()
}.
sendTo
(
contact
)
/**
/**
* 在 [Dispatchers.IO] 中下载 [URL] 到临时文件并将其作为图片发送到指定联系人
* 在 [Dispatchers.IO] 中下载 [URL] 到临时文件并将其作为图片发送到指定联系人
* @throws OverFileSizeMaxException
* @throws OverFileSizeMaxException
*/
*/
@Throws
(
OverFileSizeMaxException
::
class
)
@Throws
(
OverFileSizeMaxException
::
class
)
suspend
fun
<
C
:
Contact
>
URL
.
sendAsImageTo
(
contact
:
C
):
MessageReceipt
<
C
>
=
withContext
(
Dispatchers
.
IO
)
{
toExternalImage
()
}.
sendTo
(
contact
)
suspend
fun
<
C
:
Contact
>
URL
.
sendAsImageTo
(
contact
:
C
):
MessageReceipt
<
C
>
=
withContext
(
Dispatchers
.
IO
)
{
toExternalImage
()
}.
sendTo
(
contact
)
/**
/**
* 在 [Dispatchers.IO] 中读取 [Input] 到临时文件并将其作为图片发送到指定联系人
* 在 [Dispatchers.IO] 中读取 [Input] 到临时文件并将其作为图片发送到指定联系人
* @throws OverFileSizeMaxException
* @throws OverFileSizeMaxException
*/
*/
@Throws
(
OverFileSizeMaxException
::
class
)
@Throws
(
OverFileSizeMaxException
::
class
)
suspend
fun
<
C
:
Contact
>
Input
.
sendAsImageTo
(
contact
:
C
):
MessageReceipt
<
C
>
=
withContext
(
Dispatchers
.
IO
)
{
toExternalImage
()
}.
sendTo
(
contact
)
suspend
fun
<
C
:
Contact
>
Input
.
sendAsImageTo
(
contact
:
C
):
MessageReceipt
<
C
>
=
withContext
(
Dispatchers
.
IO
)
{
toExternalImage
()
}.
sendTo
(
contact
)
/**
/**
* 在 [Dispatchers.IO] 中读取 [InputStream] 到临时文件并将其作为图片发送到指定联系人
* 在 [Dispatchers.IO] 中读取 [InputStream] 到临时文件并将其作为图片发送到指定联系人
* @throws OverFileSizeMaxException
* @throws OverFileSizeMaxException
*/
*/
@Throws
(
OverFileSizeMaxException
::
class
)
@Throws
(
OverFileSizeMaxException
::
class
)
suspend
fun
<
C
:
Contact
>
InputStream
.
sendAsImageTo
(
contact
:
C
):
MessageReceipt
<
C
>
=
withContext
(
Dispatchers
.
IO
)
{
toExternalImage
()
}.
sendTo
(
contact
)
suspend
fun
<
C
:
Contact
>
InputStream
.
sendAsImageTo
(
contact
:
C
):
MessageReceipt
<
C
>
=
withContext
(
Dispatchers
.
IO
)
{
toExternalImage
()
}.
sendTo
(
contact
)
/**
/**
* 在 [Dispatchers.IO] 中将文件作为图片发送到指定联系人
* 在 [Dispatchers.IO] 中将文件作为图片发送到指定联系人
...
@@ -79,28 +83,32 @@ suspend fun <C : Contact> File.sendAsImageTo(contact: C): MessageReceipt<C> {
...
@@ -79,28 +83,32 @@ suspend fun <C : Contact> File.sendAsImageTo(contact: C): MessageReceipt<C> {
* @throws OverFileSizeMaxException
* @throws OverFileSizeMaxException
*/
*/
@Throws
(
OverFileSizeMaxException
::
class
)
@Throws
(
OverFileSizeMaxException
::
class
)
suspend
fun
BufferedImage
.
upload
(
contact
:
Contact
):
OfflineImage
=
withContext
(
Dispatchers
.
IO
)
{
toExternalImage
()
}.
upload
(
contact
)
suspend
fun
BufferedImage
.
upload
(
contact
:
Contact
):
OfflineImage
=
withContext
(
Dispatchers
.
IO
)
{
toExternalImage
()
}.
upload
(
contact
)
/**
/**
* 在 [Dispatchers.IO] 中下载 [URL] 到临时文件并将其作为图片上传后构造 [Image]
* 在 [Dispatchers.IO] 中下载 [URL] 到临时文件并将其作为图片上传后构造 [Image]
* @throws OverFileSizeMaxException
* @throws OverFileSizeMaxException
*/
*/
@Throws
(
OverFileSizeMaxException
::
class
)
@Throws
(
OverFileSizeMaxException
::
class
)
suspend
fun
URL
.
uploadAsImage
(
contact
:
Contact
):
OfflineImage
=
withContext
(
Dispatchers
.
IO
)
{
toExternalImage
()
}.
upload
(
contact
)
suspend
fun
URL
.
uploadAsImage
(
contact
:
Contact
):
OfflineImage
=
withContext
(
Dispatchers
.
IO
)
{
toExternalImage
()
}.
upload
(
contact
)
/**
/**
* 在 [Dispatchers.IO] 中读取 [Input] 到临时文件并将其作为图片上传后构造 [Image]
* 在 [Dispatchers.IO] 中读取 [Input] 到临时文件并将其作为图片上传后构造 [Image]
* @throws OverFileSizeMaxException
* @throws OverFileSizeMaxException
*/
*/
@Throws
(
OverFileSizeMaxException
::
class
)
@Throws
(
OverFileSizeMaxException
::
class
)
suspend
fun
Input
.
uploadAsImage
(
contact
:
Contact
):
OfflineImage
=
withContext
(
Dispatchers
.
IO
)
{
toExternalImage
()
}.
upload
(
contact
)
suspend
fun
Input
.
uploadAsImage
(
contact
:
Contact
):
OfflineImage
=
withContext
(
Dispatchers
.
IO
)
{
toExternalImage
()
}.
upload
(
contact
)
/**
/**
* 在 [Dispatchers.IO] 中读取 [InputStream] 到临时文件并将其作为图片上传后构造 [Image]
* 在 [Dispatchers.IO] 中读取 [InputStream] 到临时文件并将其作为图片上传后构造 [Image]
* @throws OverFileSizeMaxException
* @throws OverFileSizeMaxException
*/
*/
@Throws
(
OverFileSizeMaxException
::
class
)
@Throws
(
OverFileSizeMaxException
::
class
)
suspend
fun
InputStream
.
uploadAsImage
(
contact
:
Contact
):
OfflineImage
=
withContext
(
Dispatchers
.
IO
)
{
toExternalImage
()
}.
upload
(
contact
)
suspend
fun
InputStream
.
uploadAsImage
(
contact
:
Contact
):
OfflineImage
=
withContext
(
Dispatchers
.
IO
)
{
toExternalImage
()
}.
upload
(
contact
)
/**
/**
* 在 [Dispatchers.IO] 中将文件作为图片上传后构造 [Image]
* 在 [Dispatchers.IO] 中将文件作为图片上传后构造 [Image]
...
@@ -121,7 +129,8 @@ suspend fun File.uploadAsImage(contact: Contact): OfflineImage {
...
@@ -121,7 +129,8 @@ suspend fun File.uploadAsImage(contact: Contact): OfflineImage {
* @throws OverFileSizeMaxException
* @throws OverFileSizeMaxException
*/
*/
@Throws
(
OverFileSizeMaxException
::
class
)
@Throws
(
OverFileSizeMaxException
::
class
)
suspend
inline
fun
<
C
:
Contact
>
C
.
sendImage
(
bufferedImage
:
BufferedImage
):
MessageReceipt
<
C
>
=
bufferedImage
.
sendTo
(
this
)
suspend
inline
fun
<
C
:
Contact
>
C
.
sendImage
(
bufferedImage
:
BufferedImage
):
MessageReceipt
<
C
>
=
bufferedImage
.
sendTo
(
this
)
/**
/**
* 在 [Dispatchers.IO] 中下载 [URL] 到临时文件并将其作为图片发送到指定联系人
* 在 [Dispatchers.IO] 中下载 [URL] 到临时文件并将其作为图片发送到指定联系人
...
@@ -142,7 +151,8 @@ suspend inline fun <C : Contact> C.sendImage(imageInput: Input): MessageReceipt<
...
@@ -142,7 +151,8 @@ suspend inline fun <C : Contact> C.sendImage(imageInput: Input): MessageReceipt<
* @throws OverFileSizeMaxException
* @throws OverFileSizeMaxException
*/
*/
@Throws
(
OverFileSizeMaxException
::
class
)
@Throws
(
OverFileSizeMaxException
::
class
)
suspend
inline
fun
<
C
:
Contact
>
C
.
sendImage
(
imageStream
:
InputStream
):
MessageReceipt
<
C
>
=
imageStream
.
sendAsImageTo
(
this
)
suspend
inline
fun
<
C
:
Contact
>
C
.
sendImage
(
imageStream
:
InputStream
):
MessageReceipt
<
C
>
=
imageStream
.
sendAsImageTo
(
this
)
/**
/**
* 在 [Dispatchers.IO] 中将文件作为图片发送到指定联系人
* 在 [Dispatchers.IO] 中将文件作为图片发送到指定联系人
...
...
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/utils/ExternalImageJvm.kt
View file @
e60a6bcf
...
@@ -11,7 +11,7 @@
...
@@ -11,7 +11,7 @@
package
net.mamoe.mirai.utils
package
net.mamoe.mirai.utils
import
io.ktor.util
s.io.ByteReadChannel
import
kotlinx.coroutine
s.io.ByteReadChannel
import
kotlinx.coroutines.Dispatchers.IO
import
kotlinx.coroutines.Dispatchers.IO
import
kotlinx.coroutines.withContext
import
kotlinx.coroutines.withContext
import
kotlinx.io.core.Input
import
kotlinx.io.core.Input
...
...
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