Skip to content
This repository has been archived by the owner on Feb 16, 2023. It is now read-only.

Commit

Permalink
1.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
MarbleGateKeeper committed May 18, 2022
1 parent 15758fa commit b857d7a
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 30 deletions.
14 changes: 5 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,14 @@
A Mirai Console Plugin
### 本插件提供的功能
* 防止撤回,自动将撤回内容重新发布到群中并@发布人(请注意,被管理员撤回的内容将会被本插件忽略)
* ~~将撤回内容保存到本地 (硬编码中默认关闭,需要开启此功能请修改代码并编译自己的版本)~~
* 保存到本地的功能先摆了
* ~~这个插件的测试也先摆了,emo中谁爱怎么弄怎么弄吧~~
* 将撤回内容保存到本地 (硬编码中默认关闭,需要开启此功能请修改代码并编译自己的版本)
### 为什么要有这个插件?
```
null好像在群里发了双丁然后撤回了。
我从中午12点emo到下午一点半,
连null发的图都没看到,
我真的要emo到第二天天亮去。
SO F**K THIS S**T
下次别想撤回了!
连null发的图都没看到。
```

累了,赶紧的,毁灭吧。
累了,赶紧的,毁灭吧。
### Download
自己编译,请。
7 changes: 6 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,14 @@ plugins {
}

group = "love.marblegate"
version = "0.1.0"
version = "1.0.0"

repositories {
maven("https://maven.aliyun.com/repository/public")
mavenCentral()
}

dependencies{
implementation("cn.hutool:hutool-http:5.8.0")
implementation("com.google.guava:guava:31.1-jre")
}
82 changes: 79 additions & 3 deletions src/main/kotlin/love/marblegate/evilgemira/EvilService.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,85 @@
package love.marblegate.evilgemira

import net.mamoe.mirai.message.data.MessageChain
import cn.hutool.http.HttpUtil
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import net.mamoe.mirai.event.events.MessageRecallEvent
import net.mamoe.mirai.message.data.*
import net.mamoe.mirai.message.data.Image.Key.queryUrl
import net.mamoe.mirai.utils.MiraiInternalApi
import java.io.ByteArrayInputStream
import java.io.File
import java.io.IOException
import java.io.OutputStreamWriter
import java.nio.charset.StandardCharsets
import java.nio.file.Files
import java.nio.file.Paths
import java.nio.file.StandardOpenOption
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import javax.imageio.ImageIO

object EvilService{
fun MessageChain.saveTo(path: String){
// TODO
@OptIn(MiraiInternalApi::class)
fun DataUnit.saveTo(filePath: String){
val m = if(this.message.contains(QuoteReply)) "引用消息" else "消息"
val content = this.message.filter { singleMessage -> singleMessage !is MessageMetadata }
val images = content.filterIsInstance<Image>()
if(images.isNotEmpty()){
CoroutineScope(Dispatchers.IO).launch{
for (image in images) {
image.saveTo( "$filePath${this@saveTo.event.group.id}" + File.separator + "image" + File.separator + "${image.imageId}.${image.imageType.formatName}")
}
}
}
val detailedPath = "$filePath${this.event.group.id}" + File.separator + "${LocalDateTime.now().format(DateTimeFormatter.BASIC_ISO_DATE)}.txt"
val ctx = """
群成员${this.event.author.nick}(${this.event.author.id}) 于 ${LocalDateTime.now()} 撤回了一条$m
${
content.joinToString("\n") { singleMessage ->
when (singleMessage) {
is At -> "At@${singleMessage.target}"
is Image -> "图片内容(已保存至/image/${singleMessage.imageId}.${singleMessage.imageType.formatName})"
else -> singleMessage.content
}
}}
""".trimIndent() + "\n"
CoroutineScope(Dispatchers.IO).launch{
ctx.appendToRecord(ensureDir(detailedPath))
}
}

private fun String.appendToRecord(path: String) {
OutputStreamWriter(
Files.newOutputStream(Paths.get(path), StandardOpenOption.APPEND),
StandardCharsets.UTF_8
).use { writer -> writer.write(this) }
}

@OptIn(MiraiInternalApi::class)
private suspend fun Image.saveTo(path:String){
val stream = ByteArrayInputStream(HttpUtil.downloadBytes(this.queryUrl()))
val image = withContext(Dispatchers.IO) {
ImageIO.read(stream)
}
withContext(Dispatchers.IO) {
ImageIO.write(image, this@saveTo.imageType.formatName, File(ensureDir(path)))
}
}

private fun ensureDir(path: String): String {
val file = File(path)
val fileParent = file.parentFile
if (!fileParent.exists()) {
fileParent.mkdirs()
}
if (!file.exists()) {
file.createNewFile()
}
return path
}

data class DataUnit(val event: MessageRecallEvent.GroupRecall, val message: MessageChain);
}
37 changes: 20 additions & 17 deletions src/main/kotlin/love/marblegate/evilgemira/GemiraService.kt
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
package love.marblegate.evilgemira

import com.google.common.collect.HashBasedTable
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import love.marblegate.evilgemira.EvilService.saveTo
import net.mamoe.mirai.event.events.GroupMessageEvent
import net.mamoe.mirai.event.events.MessageRecallEvent
import net.mamoe.mirai.message.data.*
import java.io.File
import java.util.*

object GemiraService {
private val datas = listOf(mutableMapOf(),mutableMapOf<IntArray, MessageChain>())
private val datas = listOf(HashBasedTable.create<Long, Int, MessageChain>(),HashBasedTable.create())
private var activeMap = 0
private val path = System.getProperty("user.dir") + File.separator + "data" + File.separator + "evil_gemira" + File.separator

init {
Timer().schedule(object : TimerTask(){
Expand All @@ -29,17 +32,25 @@ object GemiraService {
val messageChain = event.retrieve()
if(messageChain!=null){
val builder = MessageChainBuilder()
builder.append(At(event.authorId)).append(" 刚刚撤回了:\n").append(messageChain)
CoroutineScope(Dispatchers.Default).launch{
builder.append(At(event.authorId))
if(messageChain.contains(QuoteReply)){
builder.append(" 刚刚撤回一条引用消息,内容如下:\n")
} else {
builder.append(" 刚刚撤回一条消息,内容如下:\n")
}
builder.append(messageChain.filter { singleMessage -> singleMessage !is MessageMetadata }.toMessageChain())
CoroutineScope(Dispatchers.IO).launch{
event.group.sendMessage(builder.asMessageChain())
// Pandora's box
// EvilService.DataUnit(event,messageChain).saveTo(path)
}
}
}
}

fun saveMessageTOData(event: GroupMessageEvent){
if(event.message.valid())
datas[activeMap][event.message.ids] = event.message
datas[activeMap].put(event.group.id,event.time,event.message)
}

private fun MessageRecallEvent.GroupRecall.valid(): Boolean{
Expand All @@ -51,27 +62,19 @@ object GemiraService {
}

private fun MessageRecallEvent.GroupRecall.retrieve(): MessageChain?{
if(datas[0].contains(this.messageIds)){
return datas[0][this.messageIds]
if(datas[0].contains(this.group.id,this.messageTime)){
return datas[0].get(this.group.id,this.messageTime)
} else {
if(datas[1].contains(this.messageIds))
return datas[1][this.messageIds]
if(datas[1].contains(this.group.id,this.messageTime))
return datas[1][this.group.id,this.messageTime]
}
return null
}

private fun MessageChain.valid(): Boolean {
if (this.contains(QuoteReply)) {
return false
}
for (message in this) {
if (!(message is MessageSource || message is PlainText || message is At || message is Image)) return false
if (!(message is QuoteReply || message is MessageSource || message is PlainText || message is At || message is Image)) return false
}
return true
}

private fun save(message: MessageChain) {
message.saveTo("TODO")
// TODO use EvilService shit to save content to local
}
}

0 comments on commit b857d7a

Please sign in to comment.