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
29f416cd
Commit
29f416cd
authored
Feb 23, 2020
by
ryoii
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/master'
parents
c33b0688
971d7e18
Changes
25
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
25 changed files
with
6604 additions
and
261 deletions
+6604
-261
mirai-api-http/src/main/kotlin/net/mamoe/mirai/api/http/data/common/MessageDTO.kt
...kotlin/net/mamoe/mirai/api/http/data/common/MessageDTO.kt
+1
-1
mirai-console/src/main/kotlin/net/mamoe/mirai/console/Setu.kt
...i-console/src/main/kotlin/net/mamoe/mirai/console/Setu.kt
+2
-0
mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/DefaultCommands.kt
...kotlin/net/mamoe/mirai/console/command/DefaultCommands.kt
+0
-8
mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugins/ConfigSection.kt
...n/kotlin/net/mamoe/mirai/console/plugins/ConfigSection.kt
+22
-1
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/ContactImpl.kt
...ommonMain/kotlin/net/mamoe/mirai/qqandroid/ContactImpl.kt
+3
-1
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/message/messages.kt
...Main/kotlin/net/mamoe/mirai/qqandroid/message/messages.kt
+5
-5
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/highway/Codec.kt
...kotlin/net/mamoe/mirai/qqandroid/network/highway/Codec.kt
+15
-8
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
-3
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt
.../src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt
+6
-1
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/MessageReceipt.kt
...mmonMain/kotlin/net.mamoe.mirai/message/MessageReceipt.kt
+1
-0
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/At.kt
.../src/commonMain/kotlin/net.mamoe.mirai/message/data/At.kt
+2
-2
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/AtAll.kt
...c/commonMain/kotlin/net.mamoe.mirai/message/data/AtAll.kt
+1
-1
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/CombinedMessage.kt
...in/kotlin/net.mamoe.mirai/message/data/CombinedMessage.kt
+41
-0
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/Message.kt
...commonMain/kotlin/net.mamoe.mirai/message/data/Message.kt
+5
-6
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/MessageChain.kt
...nMain/kotlin/net.mamoe.mirai/message/data/MessageChain.kt
+28
-159
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/PlainText.kt
...mmonMain/kotlin/net.mamoe.mirai/message/data/PlainText.kt
+9
-1
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/builder.kt
...commonMain/kotlin/net.mamoe.mirai/message/data/builder.kt
+70
-0
mirai-core/src/commonTest/kotlin/net.mamoe.mirai.message.data/CombinedMessageTest.kt
...otlin/net.mamoe.mirai.message.data/CombinedMessageTest.kt
+155
-0
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/utils/ExternalImageJvm.kt
.../jvmMain/kotlin/net/mamoe/mirai/utils/ExternalImageJvm.kt
+1
-3
mirai-core/src/jvmTest/kotlin/net/mamoe/mirai/utils/LockFreeLinkedListTest.kt
...st/kotlin/net/mamoe/mirai/utils/LockFreeLinkedListTest.kt
+1
-0
mirai-plugins/image-sender/src/main/java/net/mamoe/mirai/imageplugin/ImageProvider.kt
...rc/main/java/net/mamoe/mirai/imageplugin/ImageProvider.kt
+0
-48
mirai-plugins/image-sender/src/main/java/net/mamoe/mirai/imageplugin/ImageSenderMain.kt
.../main/java/net/mamoe/mirai/imageplugin/ImageSenderMain.kt
+60
-11
mirai-plugins/image-sender/src/main/java/net/mamoe/mirai/imageplugin/Test.kt
...-sender/src/main/java/net/mamoe/mirai/imageplugin/Test.kt
+144
-0
mirai-plugins/image-sender/src/main/resources/data.yml
mirai-plugins/image-sender/src/main/resources/data.yml
+6030
-0
mirai-plugins/image-sender/src/main/resources/plugin.yml
mirai-plugins/image-sender/src/main/resources/plugin.yml
+2
-2
No files found.
mirai-api-http/src/main/kotlin/net/mamoe/mirai/api/http/data/common/MessageDTO.kt
View file @
29f416cd
...
...
@@ -97,7 +97,7 @@ fun MessageChain.toDTOChain() = mutableListOf(this[MessageSource].toDTO()).apply
}
fun
MessageChainDTO
.
toMessageChain
(
contact
:
Contact
)
=
MessageChain
().
apply
{
this
@
toMessageChain
.
forEach
{
add
(
it
.
toMessage
(
contact
))
}
}
buildMessageChain
{
this
@
toMessageChain
.
forEach
{
add
(
it
.
toMessage
(
contact
))
}
}
@UseExperimental
(
ExperimentalUnsignedTypes
::
class
)
fun
Message
.
toDTO
()
=
when
(
this
)
{
...
...
mirai-console/src/main/kotlin/net/mamoe/mirai/console/Setu.kt
0 → 100644
View file @
29f416cd
package
net.mamoe.mirai.console
mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/DefaultCommands.kt
View file @
29f416cd
...
...
@@ -131,13 +131,6 @@ object DefaultCommands {
}
bot
.
login
()
bot
.
subscribeMessages
{
contains
(
"test"
)
{
if
(
this
is
GroupMessage
)
{
quoteReply
(
"Hello $senderName"
)
}
else
{
reply
(
"Hello!"
)
}
}
this
.
startsWith
(
"/"
)
{
if
(
bot
.
checkManager
(
this
.
sender
.
id
))
{
val
sender
=
ContactCommandSender
(
this
.
subject
)
...
...
@@ -149,7 +142,6 @@ object DefaultCommands {
}
sendMessage
(
"$qqNumber login successes"
)
MiraiConsole
.
frontEnd
.
pushBot
(
bot
)
}
catch
(
e
:
Exception
)
{
sendMessage
(
"$qqNumber login failed -> "
+
e
.
message
)
}
...
...
mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugins/ConfigSection.kt
View file @
29f416cd
...
...
@@ -48,6 +48,7 @@ interface Config {
fun
getFloatList
(
key
:
String
):
List
<
Float
>
fun
getDoubleList
(
key
:
String
):
List
<
Double
>
fun
getLongList
(
key
:
String
):
List
<
Long
>
fun
getConfigSectionList
(
key
:
String
):
List
<
ConfigSection
>
operator
fun
set
(
key
:
String
,
value
:
Any
)
operator
fun
get
(
key
:
String
):
Any
?
operator
fun
contains
(
key
:
String
):
Boolean
...
...
@@ -196,8 +197,14 @@ fun <T : Any> Config._smartCast(propertyName: String, _class: KClass<T>): T {
Float
::
class
-> get
FloatList
(
propertyName
)
Double
::
class
-> get
DoubleList
(
propertyName
)
Long
::
class
-> get
LongList
(
propertyName
)
//不去支持getConfigSectionList(propertyName)
// LinkedHashMap::class -> getConfigSectionList(propertyName)//faster approach
else
->
{
error
(
"unsupported type"
)
//if(list[0]!! is ConfigSection || list[0]!! is Map<*,*>){
// getConfigSectionList(propertyName)
//}else {
error
(
"unsupported type"
+
list
[
0
]
!!::
class
)
//}
}
}
}
as
T
...
...
@@ -271,6 +278,20 @@ interface ConfigSection : Config, MutableMap<String, Any> {
return
((
get
(
key
)
?:
error
(
"ConfigSection does not contain $key "
))
as
List
<
*
>).
map
{
it
.
toString
().
toLong
()
}
}
override
fun
getConfigSectionList
(
key
:
String
):
List
<
ConfigSection
>
{
return
((
get
(
key
)
?:
error
(
"ConfigSection does not contain $key "
))
as
List
<
*
>).
map
{
if
(
it
is
ConfigSection
)
{
it
}
else
{
ConfigSectionDelegation
(
Collections
.
synchronizedMap
(
it
as
MutableMap
<
String
,
Any
>
)
)
}
}
}
override
fun
exist
(
key
:
String
):
Boolean
{
return
get
(
key
)
!=
null
}
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/ContactImpl.kt
View file @
29f416cd
...
...
@@ -147,6 +147,7 @@ internal class QQImpl(
}
}
finally
{
(
image
.
input
as
?
Closeable
)
?.
close
()
(
image
.
input
as
?
io
.
ktor
.
utils
.
io
.
core
.
Closeable
)
?.
close
()
}
@MiraiExperimentalAPI
...
...
@@ -644,7 +645,8 @@ internal class GroupImpl(
}
}
}
finally
{
(
image
.
input
as
Closeable
)
?.
close
()
(
image
.
input
as
?
Closeable
)
?.
close
()
(
image
.
input
as
?
io
.
ktor
.
utils
.
io
.
core
.
Closeable
)
?.
close
()
}
override
fun
toString
():
String
{
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/message/messages.kt
View file @
29f416cd
...
...
@@ -326,10 +326,10 @@ internal class NotOnlineImageFromServer(
internal
fun
MsgComm
.
Msg
.
toMessageChain
():
MessageChain
{
val
elements
=
this
.
msgBody
.
richText
.
elems
val
message
=
MessageChain
(
initialCapacity
=
elements
.
size
+
1
)
val
message
=
ArrayList
<
Message
>(
elements
.
size
+
1
)
message
.
add
(
MessageSourceFromMsg
(
delegate
=
this
))
elements
.
joinToMessageChain
(
message
)
return
message
return
message
.
asMessageChain
()
}
// These two functions are not the same.
...
...
@@ -338,15 +338,15 @@ internal fun MsgComm.Msg.toMessageChain(): MessageChain {
internal
fun
ImMsgBody
.
SourceMsg
.
toMessageChain
():
MessageChain
{
val
elements
=
this
.
elems
!!
val
message
=
MessageChain
(
initialCapacity
=
elements
.
size
+
1
)
val
message
=
ArrayList
<
Message
>(
elements
.
size
+
1
)
message
.
add
(
MessageSourceFromServer
(
delegate
=
this
))
elements
.
joinToMessageChain
(
message
)
return
message
return
message
.
asMessageChain
()
}
@UseExperimental
(
MiraiInternalAPI
::
class
,
ExperimentalUnsignedTypes
::
class
,
MiraiDebugAPI
::
class
)
internal
fun
List
<
ImMsgBody
.
Elem
>.
joinToMessageChain
(
message
:
M
essageChain
)
{
internal
fun
List
<
ImMsgBody
.
Elem
>.
joinToMessageChain
(
message
:
M
utableList
<
Message
>
)
{
this
.
forEach
{
when
{
it
.
srcMsg
!=
null
->
message
.
add
(
QuoteReply
(
MessageSourceFromServer
(
it
.
srcMsg
)))
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/highway/Codec.kt
View file @
29f416cd
...
...
@@ -86,25 +86,32 @@ object Highway {
writeFully
(
head
)
when
(
body
)
{
is
ByteReadPacket
->
writePacket
(
body
)
is
Input
->
ByteArrayPool
.
useInstance
{
buffer
->
is
Input
->
body
.
use
{
ByteArrayPool
.
useInstance
{
buffer
->
var
size
:
Int
while
(
body
.
readAvailable
(
buffer
).
also
{
size
=
it
}
!=
0
)
{
this
@
buildPacket
.
writeFully
(
buffer
,
0
,
size
)
}
}
}
is
ByteReadChannel
->
ByteArrayPool
.
useInstance
{
buffer
->
var
size
:
Int
while
(
body
.
readAvailable
(
buffer
,
0
,
buffer
.
size
).
also
{
size
=
it
}
!=
0
)
{
this
@
buildPacket
.
writeFully
(
buffer
,
0
,
size
)
}
}
is
InputStream
->
ByteArrayPool
.
useInstance
{
buffer
->
is
InputStream
->
try
{
ByteArrayPool
.
useInstance
{
buffer
->
var
size
:
Int
while
(
body
.
read
(
buffer
).
also
{
size
=
it
}
!=
0
)
{
this
@
buildPacket
.
writeFully
(
buffer
,
0
,
size
)
}
}
}
finally
{
body
.
close
()
}
}
writeByte
(
41
)
}
}
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.kt
View file @
29f416cd
...
...
@@ -26,7 +26,6 @@ import net.mamoe.mirai.event.subscribingGetAsync
import
net.mamoe.mirai.message.FriendMessage
import
net.mamoe.mirai.message.data.MessageChain
import
net.mamoe.mirai.message.data.MessageSource
import
net.mamoe.mirai.message.data.addOrRemove
import
net.mamoe.mirai.qqandroid.GroupImpl
import
net.mamoe.mirai.qqandroid.QQAndroidBot
import
net.mamoe.mirai.qqandroid.io.serialization.decodeUniPacket
...
...
@@ -398,8 +397,6 @@ internal class MessageSvc {
msgVia
=
1
)
)
message
.
addOrRemove
(
source
)
}
override
suspend
fun
ByteReadPacket
.
decode
(
bot
:
QQAndroidBot
):
Response
{
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt
View file @
29f416cd
...
...
@@ -139,3 +139,8 @@ suspend inline fun <C : Contact> C.sendMessage(message: Message): MessageReceipt
* @see Contact.sendMessage
*/
suspend
inline
fun
<
C
:
Contact
>
C
.
sendMessage
(
plain
:
String
):
MessageReceipt
<
C
>
=
sendMessage
(
plain
.
toMessage
())
/**
* @see Contact.sendMessage
*/
suspend
inline
fun
<
C
:
Contact
>
C
.
sendMessage
(
plain
:
CombinedMessage
):
MessageReceipt
<
C
>
=
sendMessage
(
MessageChain
(
plain
as
Message
))
as
MessageReceipt
<
C
>
\ No newline at end of file
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/MessageReceipt.kt
View file @
29f416cd
...
...
@@ -15,6 +15,7 @@ import net.mamoe.mirai.Bot
import
net.mamoe.mirai.contact.Contact
import
net.mamoe.mirai.contact.Group
import
net.mamoe.mirai.contact.QQ
import
net.mamoe.mirai.contact.sendMessage
import
net.mamoe.mirai.message.data.*
import
net.mamoe.mirai.recallIn
import
net.mamoe.mirai.utils.MiraiExperimentalAPI
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/At.kt
View file @
29f416cd
...
...
@@ -36,8 +36,8 @@ class At @MiraiInternalAPI constructor(val target: Long, val display: String) :
// 自动为消息补充 " "
override
fun
followedBy
(
tail
:
Message
):
MessageChain
{
if
(
tail
is
PlainText
&&
tail
.
stringValue
.
startsWith
(
' '
))
{
override
fun
followedBy
(
tail
:
Message
):
CombinedMessage
{
if
(
tail
is
PlainText
&&
tail
.
stringValue
.
startsWith
(
' '
))
{
return
super
.
followedBy
(
tail
)
}
return
super
.
followedBy
(
PlainText
(
" "
))
+
tail
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/AtAll.kt
View file @
29f416cd
...
...
@@ -27,7 +27,7 @@ object AtAll : Message, Message.Key<AtAll> {
// 自动为消息补充 " "
override
fun
followedBy
(
tail
:
Message
):
MessageChain
{
override
fun
followedBy
(
tail
:
Message
):
CombinedMessage
{
if
(
tail
is
PlainText
&&
tail
.
stringValue
.
startsWith
(
' '
))
{
return
super
.
followedBy
(
tail
)
}
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/CombinedMessage.kt
0 → 100644
View file @
29f416cd
/*
* Copyright 2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
package
net.mamoe.mirai.message.data
/**
* Left-biased list
*/
class
CombinedMessage
(
val
left
:
Message
,
val
element
:
Message
)
:
Iterable
<
Message
>,
Message
{
private
suspend
fun
SequenceScope
<
Message
>.
yieldCombinedOrElements
(
message
:
Message
)
{
when
(
message
)
{
is
CombinedMessage
->
{
yieldCombinedOrElements
(
message
.
element
)
yieldCombinedOrElements
(
message
.
left
)
}
is
MessageChain
->
message
.
forEach
{
yieldCombinedOrElements
(
it
)
}
else
->
yield
(
message
)
}
}
fun
asSequence
():
Sequence
<
Message
>
=
sequence
{
yieldCombinedOrElements
(
this
@CombinedMessage
)
}
override
fun
iterator
():
Iterator
<
Message
>
{
return
asSequence
().
iterator
()
}
override
fun
toString
():
String
{
return
left
.
toString
()
+
element
.
toString
()
}
}
\ No newline at end of file
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/Message.kt
View file @
29f416cd
...
...
@@ -85,20 +85,19 @@ interface Message {
* ```
*/
@JvmSynthetic
// in java they should use `plus` instead
fun
followedBy
(
tail
:
Message
):
MessageChain
{
fun
followedBy
(
tail
:
Message
):
CombinedMessage
{
require
(
tail
!
is
SingleOnly
)
{
"SingleOnly Message cannot follow another message"
}
require
(
this
!
is
SingleOnly
)
{
"SingleOnly Message cannot be followed"
}
return
if
(
tail
is
MessageChain
)
tail
.
followedBy
(
this
)
/*MessageChainImpl(this).also { tail.forEach { child -> it.concat(child) } }*/
else
MessageChainImpl
(
this
,
tail
)
return
CombinedMessage
(
tail
,
this
)
}
override
fun
toString
():
String
operator
fun
plus
(
another
:
Message
):
MessageChain
=
this
.
followedBy
(
another
)
operator
fun
plus
(
another
:
Message
):
CombinedMessage
=
this
.
followedBy
(
another
)
operator
fun
plus
(
another
:
String
):
MessageChain
=
this
.
followedBy
(
another
.
toMessage
())
operator
fun
plus
(
another
:
String
):
CombinedMessage
=
this
.
followedBy
(
another
.
toMessage
())
// `+ ""` will be resolved to `plus(String)` instead of `plus(CharSeq)`
operator
fun
plus
(
another
:
CharSequence
):
MessageChain
=
this
.
followedBy
(
another
.
toString
().
toMessage
())
operator
fun
plus
(
another
:
CharSequence
):
CombinedMessage
=
this
.
followedBy
(
another
.
toString
().
toMessage
())
}
/**
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/MessageChain.kt
View file @
29f416cd
This diff is collapsed.
Click to expand it.
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/PlainText.kt
View file @
29f416cd
...
...
@@ -14,6 +14,7 @@ package net.mamoe.mirai.message.data
import
kotlin.jvm.JvmMultifileClass
import
kotlin.jvm.JvmName
import
kotlin.jvm.JvmStatic
/**
* 纯文本. 可含 emoji 表情.
...
...
@@ -21,10 +22,17 @@ import kotlin.jvm.JvmName
* 一般不需要主动构造 [PlainText], [Message] 可直接与 [String] 相加. Java 用户请使用 [MessageChain.plus]
*/
inline
class
PlainText
(
val
stringValue
:
String
)
:
Message
{
constructor
(
charSequence
:
CharSequence
)
:
this
(
charSequence
.
toString
())
override
operator
fun
contains
(
sub
:
String
):
Boolean
=
sub
in
stringValue
override
fun
toString
():
String
=
stringValue
companion
object
Key
:
Message
.
Key
<
PlainText
>
companion
object
Key
:
Message
.
Key
<
PlainText
>
{
@JvmStatic
val
Empty
=
PlainText
(
""
)
@JvmStatic
val
Null
=
PlainText
(
"null"
)
}
}
/**
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/builder.kt
0 → 100644
View file @
29f416cd
/*
* Copyright 2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
package
net.mamoe.mirai.message.data
import
kotlin.jvm.JvmOverloads
/**
* 构造一个 [MessageChain]
*
* @see MessageChainBuilder
*/
inline
fun
buildMessageChain
(
block
:
MessageChainBuilder
.()
->
Unit
):
MessageChain
{
return
MessageChainBuilder
().
apply
(
block
).
asMessageChain
()
}
class
MessageChainBuilder
@JvmOverloads
constructor
(
private
val
container
:
MutableList
<
Message
>
=
mutableListOf
()
)
:
MutableList
<
Message
>
by
container
,
Appendable
{
operator
fun
Message
.
unaryPlus
()
{
add
(
this
)
}
operator
fun
String
.
unaryPlus
()
{
add
(
this
.
toMessage
())
}
operator
fun
plusAssign
(
plain
:
String
)
{
this
.
add
(
plain
.
toMessage
())
}
operator
fun
plusAssign
(
message
:
Message
)
{
this
.
add
(
message
)
}
fun
add
(
plain
:
String
)
{
this
.
add
(
plain
.
toMessage
())
}
operator
fun
plusAssign
(
charSequence
:
CharSequence
)
{
this
.
add
(
PlainText
(
charSequence
))
}
override
fun
append
(
c
:
Char
):
Appendable
=
apply
{
this
.
add
(
PlainText
(
c
.
toString
()))
}
override
fun
append
(
csq
:
CharSequence
?):
Appendable
=
apply
{
when
{
csq
==
null
->
this
.
add
(
PlainText
.
Null
)
csq
.
isEmpty
()
->
this
.
add
(
PlainText
.
Empty
)
else
->
this
.
add
(
PlainText
(
csq
))
}
}
override
fun
append
(
csq
:
CharSequence
?,
start
:
Int
,
end
:
Int
):
Appendable
=
apply
{
when
{
csq
==
null
->
this
.
add
(
PlainText
.
Null
)
csq
.
isEmpty
()
->
this
.
add
(
PlainText
.
Empty
)
else
->
this
.
add
(
PlainText
(
csq
.
substring
(
start
,
end
)))
}
}
}
\ No newline at end of file
mirai-core/src/commonTest/kotlin/net.mamoe.mirai.message.data/CombinedMessageTest.kt
0 → 100644
View file @
29f416cd
package
net.mamoe.mirai.message.data
import
kotlin.test.Test
import
kotlin.test.assertEquals
import
kotlin.time.ExperimentalTime
import
kotlin.time.measureTime
internal
class
CombinedMessageTest
{
@Test
fun
testAsSequence
()
{
var
message
:
Message
=
"Hello "
.
toMessage
()
message
+=
"World"
assertEquals
(
"Hello World"
,
(
message
as
CombinedMessage
).
asSequence
().
joinToString
(
separator
=
""
)
)
}
@Test
fun
testAsSequence2
()
{
var
message
:
Message
=
"Hello "
.
toMessage
()
message
+=
MessageChain
(
PlainText
(
"W"
),
PlainText
(
"o"
),
PlainText
(
"r"
)
+
PlainText
(
"ld"
)
)
assertEquals
(
"Hello World"
,
(
message
as
CombinedMessage
).
asSequence
().
joinToString
(
separator
=
""
)
)
}
private
val
toAdd
=
"1"
.
toMessage
()
@UseExperimental
(
ExperimentalTime
::
class
)
@Test
fun
speedTest
()
=
repeat
(
100
)
{
var
count
=
1L
repeat
(
Int
.
MAX_VALUE
)
{
count
++
}
var
combineMessage
:
Message
=
toAdd
println
(
"init combine ok "
+
measureTime
{
repeat
(
1000
)
{
combineMessage
+=
toAdd
}
}.
inMilliseconds
)
val
list
=
mutableListOf
<
Message
>()
println
(
"init messageChain ok "
+
measureTime
{
repeat
(
1000
)
{
list
+=
toAdd
}
}.
inMilliseconds
)
measureTime
{
list
.
joinToString
(
separator
=
""
)
}.
let
{
time
->
println
(
"list foreach: ${time.inMilliseconds} ms"
)
}
measureTime
{
(
combineMessage
as
CombinedMessage
).
iterator
().
joinToString
(
separator
=
""
)
}.
let
{
time
->
println
(
"combined iterate: ${time.inMilliseconds} ms"
)
}
measureTime
{
(
combineMessage
as
CombinedMessage
).
asSequence
().
joinToString
(
separator
=
""
)
}.
let
{
time
->
println
(
"combined sequence: ${time.inMilliseconds} ms"
)
}
repeat
(
5
)
{
println
()
}
}
@UseExperimental
(
ExperimentalTime
::
class
)
@Test
fun
testFastIteration
()
{
println
(
"start!"
)
println
(
"start!"
)
println
(
"start!"
)
println
(
"start!"
)
var
combineMessage
:
Message
=
toAdd
println
(
"init combine ok "
+
measureTime
{
repeat
(
1000
)
{
combineMessage
+=
toAdd
}
}.
inMilliseconds
)
measureTime
{
(
combineMessage
as
CombinedMessage
).
iterator
().
joinToString
(
separator
=
""
)
}.
let
{
time
->
println
(
"combine: ${time.inMilliseconds} ms"
)
}
}
}
public
fun
<
T
>
Iterator
<
T
>.
joinToString
(
separator
:
CharSequence
=
", "
,
prefix
:
CharSequence
=
""
,
postfix
:
CharSequence
=
""
,
limit
:
Int
=
-
1
,
truncated
:
CharSequence
=
"..."
,
transform
:
((
T
)
->
CharSequence
)?
=
null
):
String
{
return
joinTo
(
StringBuilder
(),
separator
,
prefix
,
postfix
,
limit
,
truncated
,
transform
).
toString
()
}
public
fun
<
T
,
A
:
Appendable
>
Iterator
<
T
>.
joinTo
(
buffer
:
A
,
separator
:
CharSequence
=
", "
,
prefix
:
CharSequence
=
""
,
postfix
:
CharSequence
=
""
,
limit
:
Int
=
-
1
,
truncated
:
CharSequence
=
"..."
,
transform
:
((
T
)
->
CharSequence
)?
=
null
):
A
{
buffer
.
append
(
prefix
)
var
count
=
0
for
(
element
in
this
)
{
if
(++
count
>
1
)
buffer
.
append
(
separator
)
if
(
limit
<
0
||
count
<=
limit
)
{
buffer
.
appendElement
(
element
,
transform
)
}
else
break
}
if
(
limit
>=
0
&&
count
>
limit
)
buffer
.
append
(
truncated
)
buffer
.
append
(
postfix
)
return
buffer
}
internal
fun
<
T
>
Appendable
.
appendElement
(
element
:
T
,
transform
:
((
T
)
->
CharSequence
)?)
{
when
{
transform
!=
null
->
append
(
transform
(
element
))
element
is
CharSequence
?
->
append
(
element
)
element
is
Char
->
append
(
element
)
else
->
append
(
element
.
toString
())
}
}
\ No newline at end of file
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/utils/ExternalImageJvm.kt
View file @
29f416cd
...
...
@@ -68,14 +68,12 @@ fun File.toExternalImage(): ExternalImage {
?:
error
(
"Unable to read file(path=${this.path}), no ImageReader found"
)
image
.
input
=
input
val
inputStream
=
this
.
inputStream
()
return
ExternalImage
(
width
=
image
.
getWidth
(
0
),
height
=
image
.
getHeight
(
0
),
md5
=
this
.
inputStream
().
md5
(),
// dont change
imageFormat
=
image
.
formatName
,
input
=
inputStream
.
asInput
(),
inputSize
=
inputStream
.
available
().
toLong
(),
input
=
this
.
inputStream
(),
filename
=
this
.
name
)
}
...
...
mirai-core/src/jvmTest/kotlin/net/mamoe/mirai/utils/LockFreeLinkedListTest.kt
View file @
29f416cd
...
...
@@ -58,6 +58,7 @@ internal class LockFreeLinkedListTest {
@Test
fun
`so
many
concurrent
add
remove
and
foreach`
()
=
runBlocking
{
return
@
runBlocking
// 测试通过了, 加快速度. 因为 kotlin 一些其他 bug
val
list
=
LockFreeLinkedList
<
Int
>()
val
addJob
=
async
{
list
.
concurrentDo
(
2
,
30000
)
{
addLast
(
1
)
}
}
...
...
mirai-plugins/image-sender/src/main/java/net/mamoe/mirai/imageplugin/ImageProvider.kt
deleted
100644 → 0
View file @
c33b0688
/*
* Copyright 2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
package
net.mamoe.mirai.imageplugin
import
com.alibaba.fastjson.JSON
import
kotlinx.coroutines.*
import
net.mamoe.mirai.contact.Contact
import
net.mamoe.mirai.message.data.Image
import
net.mamoe.mirai.message.uploadAsImage
import
org.jsoup.Jsoup
class
ImageProvider
{
lateinit
var
contact
:
Contact
// `Deferred<Image?>` causes a runtime ClassCastException
val
image
:
Deferred
<
Image
>
by
lazy
{
GlobalScope
.
async
{
withTimeoutOrNull
(
5
*
1000
)
{
withContext
(
Dispatchers
.
IO
)
{
val
result
=
JSON
.
parseArray
(
Jsoup
.
connect
(
"https://yande.re/post.json?limit=1&page=${(Math.random() * 10000).toInt()}"
).
ignoreContentType
(
true
).
timeout
(
10
_0000
).
get
().
body
().
text
()
)
Jsoup
.
connect
(
result
.
getJSONObject
(
0
).
getString
(
"jpeg_url"
))
.
userAgent
(
"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; ja-jp) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27"
)
.
timeout
(
10
_0000
)
.
ignoreContentType
(
true
)
.
maxBodySize
(
Int
.
MAX_VALUE
)
.
execute
()
.
bodyStream
()
}
}
?.
uploadAsImage
(
contact
)
?:
error
(
"Unable to download image|连接这个图站需要你的网络在外网"
)
}
}
}
mirai-plugins/image-sender/src/main/java/net/mamoe/mirai/imageplugin/ImageSenderMain.kt
View file @
29f416cd
...
...
@@ -9,15 +9,27 @@
package
net.mamoe.mirai.imageplugin
import
kotlinx.coroutines.ExperimentalCoroutinesApi
import
kotlinx.coroutines.GlobalScope
import
kotlinx.coroutines.*
import
net.mamoe.mirai.console.plugins.Config
import
net.mamoe.mirai.console.plugins.ConfigSection
import
net.mamoe.mirai.event.events.BotOnlineEvent
import
net.mamoe.mirai.event.subscribeAlways
import
net.mamoe.mirai.event.subscribeMessages
import
net.mamoe.mirai.console.plugins.PluginBase
import
net.mamoe.mirai.contact.Contact
import
net.mamoe.mirai.message.data.Image
import
net.mamoe.mirai.message.uploadAsImage
import
net.mamoe.mirai.utils.MiraiExperimentalAPI
import
org.jsoup.Jsoup
import
java.io.File
import
kotlin.random.Random
class
ImageSenderMain
:
PluginBase
()
{
lateinit
var
images
:
Config
lateinit
var
normal
:
List
<
ConfigSection
>
lateinit
var
r18
:
List
<
ConfigSection
>
@ExperimentalCoroutinesApi
@MiraiExperimentalAPI
override
fun
onEnable
()
{
...
...
@@ -25,24 +37,61 @@ class ImageSenderMain : PluginBase() {
GlobalScope
.
subscribeAlways
<
BotOnlineEvent
>
{
logger
.
info
(
"${this.bot.uin} login succeed, it will be controlled by Image Sender Plugin"
)
this
.
bot
.
subscribeMessages
{
case
(
"at me"
)
{
reply
(
sender
.
at
()
+
" ? "
)
(
contains
(
"色图"
))
{
try
{
with
(
normal
.
random
())
{
getImage
(
subject
,
this
.
getString
(
"url"
),
this
.
getString
(
"pid"
)
).
plus
(
this
.
getString
(
"tags"
)).
send
()
}
}
catch
(
e
:
Exception
)
{
reply
(
e
.
message
?:
"unknown error"
)
}
}
(
contains
(
"image"
)
or
contains
(
"图"
))
{
"图片发送中"
.
reply
()
ImageProvider
().
apply
{
this
.
contact
=
sender
}.
image
.
await
().
reply
()
(
contains
(
"不够色"
))
{
try
{
with
(
r18
.
random
())
{
getImage
(
subject
,
this
.
getString
(
"url"
),
this
.
getString
(
"pid"
)
).
plus
(
this
.
getString
(
"tags"
)).
send
()
}
}
catch
(
e
:
Exception
)
{
reply
(
e
.
message
?:
"unknown error"
)
}
}
}
}
}
suspend
fun
getImage
(
contact
:
Contact
,
url
:
String
,
pid
:
String
):
Image
{
return
withTimeoutOrNull
(
20
*
1000
)
{
withContext
(
Dispatchers
.
IO
)
{
Jsoup
.
connect
(
url
)
.
followRedirects
(
true
)
.
timeout
(
180
_000
)
.
ignoreContentType
(
true
)
.
userAgent
(
"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; ja-jp) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27"
)
.
referrer
(
"https://www.pixiv.net/member_illust.php?mode=medium&illust_id=$pid"
)
.
ignoreHttpErrors
(
true
)
.
maxBodySize
(
100000000
)
.
execute
().
also
{
check
(
it
.
statusCode
()
==
200
)
{
"Failed to download image"
}
}
}
}
?.
bodyStream
()
?.
uploadAsImage
(
contact
)
?:
error
(
"Unable to download image"
)
}
override
fun
onLoad
()
{
logger
.
info
(
"loading..."
)
logger
.
info
(
"loading local image data"
)
try
{
images
=
Config
.
load
(
this
.
javaClass
.
classLoader
.
getResource
(
"data.yml"
)
!!
.
path
!!
)
}
catch
(
e
:
Exception
)
{
logger
.
info
(
"无法加载本地图片"
)
}
logger
.
info
(
"本地图片版本"
+
images
.
getString
(
"version"
))
logger
.
info
(
"Normal * "
+
images
.
getList
(
"normal"
).
size
)
logger
.
info
(
"R18 * "
+
images
.
getList
(
"R18"
).
size
)
}
override
fun
onDisable
()
{
...
...
mirai-plugins/image-sender/src/main/java/net/mamoe/mirai/imageplugin/Test.kt
0 → 100644
View file @
29f416cd
import
com.alibaba.fastjson.JSONObject
import
com.google.gson.JsonObject
import
net.mamoe.mirai.console.plugins.*
import
net.mamoe.mirai.utils.cryptor.contentToString
import
org.jsoup.Connection
import
org.jsoup.Jsoup
import
java.io.File
import
kotlin.concurrent.thread
object
Data
{
val
section
=
(
File
(
System
.
getProperty
(
"user.dir"
)
+
"/setu.yml"
)).
loadAsConfig
()
val
abstract
=
section
.
getStringList
(
"abstract"
).
toMutableList
()
val
R18
=
section
.
getConfigSectionList
(
"R18"
).
toMutableList
()
val
normal
=
section
.
getConfigSectionList
(
"normal"
).
toMutableList
()
fun
init
()
{
section
.
setIfAbsent
(
"abstract"
,
mutableListOf
<
String
>())
section
.
setIfAbsent
(
"R18"
,
mutableListOf
<
ConfigSection
>())
section
.
setIfAbsent
(
"Normal"
,
mutableListOf
<
ConfigSection
>())
}
fun
save
()
{
section
[
"abstract"
]
=
abstract
section
[
"R18"
]
=
R18
section
[
"normal"
]
=
normal
section
.
save
()
}
}
fun
main
()
{
val
abstract_file
=
(
File
(
System
.
getProperty
(
"user.dir"
)
+
"/abstractSetu.yml"
)).
loadAsConfig
()
abstract_file
.
setIfAbsent
(
"R18"
,
mutableListOf
<
ConfigSection
>())
abstract_file
.
setIfAbsent
(
"normal"
,
mutableListOf
<
ConfigSection
>())
val
r18
=
abstract_file
.
getConfigSectionList
(
"R18"
).
toMutableList
()
val
normal
=
abstract_file
.
getConfigSectionList
(
"normal"
).
toMutableList
()
Data
.
R18
.
forEach
{
val
forbid
=
with
(
it
.
getString
(
"tags"
))
{
this
.
contains
(
"初音ミク"
)
||
this
.
contains
(
"VOCALOID"
)
||
this
.
contains
(
"Miku"
)
||
this
.
contains
(
"东方"
)
||
this
.
contains
(
"東方"
)
}
if
(
forbid
)
{
println
(
"过滤掉了一张图"
)
}
else
{
r18
.
add
(
ConfigSectionImpl
().
apply
{
this
[
"pid"
]
=
it
[
"pid"
]
!!
this
[
"author"
]
=
it
[
"author"
]
!!
this
[
"uid"
]
=
it
[
"uid"
]
!!
this
[
"tags"
]
=
it
[
"tags"
]
!!
this
[
"url"
]
=
it
[
"url"
]
!!
}
)
}
}
Data
.
normal
.
forEach
{
val
forbid
=
with
(
it
.
getString
(
"tags"
))
{
this
.
contains
(
"初音ミク"
)
||
this
.
contains
(
"VOCALOID"
)
||
this
.
contains
(
"Miku"
)
||
this
.
contains
(
"东方"
)
||
this
.
contains
(
"東方"
)
}
if
(
forbid
)
{
println
(
"过滤掉了一张图"
)
}
else
{
normal
.
add
(
ConfigSectionImpl
().
apply
{
this
[
"pid"
]
=
it
[
"pid"
]
!!
this
[
"author"
]
=
it
[
"author"
]
!!
this
[
"uid"
]
=
it
[
"uid"
]
!!
this
[
"tags"
]
=
it
[
"tags"
]
!!
this
[
"url"
]
=
it
[
"url"
]
!!
}
)
}
}
abstract_file
.
set
(
"R18"
,
r18
)
abstract_file
.
set
(
"normal"
,
normal
)
abstract_file
.
save
()
/**
Data.init()
Runtime.getRuntime().addShutdownHook(thread(start = false) {
Data.save()
})
while (true){
try {
val val0 = JSONObject.parseObject(Jsoup
.connect("https://api.lolicon.app/setu/")
.ignoreContentType(true)
.method(Connection.Method.GET)
.data("r18","1")
.data("num","10")
.execute().body())
val val1 = val0.getJSONArray("data")
for(index in 0 until val1.size - 1){
val content = val1.getJSONObject(index)
val pid = content.getString("pid")
if(Data.abstract.contains(pid)){
println("获取到了一张重复图$pid")
continue
}
val configSection = ConfigSectionImpl()
val isR18 = content.getBoolean("r18")
configSection["author"] = content.getString("author")
configSection["pid"] = pid
configSection["uid"] = content.getInteger("uid")
configSection["width"] = content.getInteger("width")
configSection["height"] = content.getInteger("height")
configSection["tags"] = content.getJSONArray("tags").map {
it.toString()
}.joinToString(",")
configSection["url"] = content.getString("url")
if(isR18){
Data.R18.add(configSection)
print("获取到了一张R18")
}else{
Data.normal.add(configSection)
print("获取到了一张Normal")
}
Data.abstract.add(pid)
println(configSection.contentToString())
}
}catch (e:Exception){
println(e.message)
}
Data.save()
println("SAVED")
Thread.sleep(1000)
}
*/
}
\ No newline at end of file
mirai-plugins/image-sender/src/main/resources/data.yml
0 → 100644
View file @
29f416cd
This diff is collapsed.
Click to expand it.
mirai-plugins/image-sender/src/main/resources/plugin.yml
View file @
29f416cd
name
:
ImageSender
main
:
net.mamoe.mirai.imageplugin.ImageSenderMain
version
:
1.0.0
author
:
mamoe
info
:
a demo plugin of mirai
author
:
不想写代码
info
:
a demo
[hso]
plugin of mirai
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