Commit 29f416cd authored by ryoii's avatar ryoii

Merge remote-tracking branch 'origin/master'

parents c33b0688 971d7e18
......@@ -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) {
......
......@@ -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)
}
......
......@@ -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 -> getFloatList(propertyName)
Double::class -> getDoubleList(propertyName)
Long::class -> getLongList(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
}
......
......@@ -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 {
......
......@@ -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: MessageChain) {
internal fun List<ImMsgBody.Elem>.joinToMessageChain(message: MutableList<Message>) {
this.forEach {
when {
it.srcMsg != null -> message.add(QuoteReply(MessageSourceFromServer(it.srcMsg)))
......
......@@ -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)
}
}
......
......@@ -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 {
......
......@@ -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
......@@ -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
......
......@@ -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
......
......@@ -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)
}
......
/*
* 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
......@@ -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())
}
/**
......
......@@ -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")
}
}
/**
......
/*
* 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
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
......@@ -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
)
}
......
......@@ -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) } }
......
/*
* 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|连接这个图站需要你的网络在外网")
}
}
}
......@@ -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() {
......
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
This diff is collapsed.
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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment