Compare commits

..

No commits in common. "main" and "init-try" have entirely different histories.

21 changed files with 43 additions and 395 deletions

View File

@ -1,18 +1,19 @@
name: Mirai-build name: Gitea Actions Demo
run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀 run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀
on: [ push ] on: [ push ]
env:
BARE_REPO_DIR: https://git.alina-dace.info/Dace/Mirai-bot.git
CLONED_REPO_DIR: ./
jobs: jobs:
Explore-Gitea-Actions: Explore-Gitea-Actions:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- run: | - run: echo "🎉 The job was automatically triggered by a ${{ gitea.event_name }} event."
rm -rf ./* - run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by Gitea!"
git clone $BARE_REPO_DIR $CLONED_REPO_DIR - run: echo "🔎 The name of your branch is ${{ gitea.ref }} and your repository is ${{ gitea.repository }}."
- run: pwd - name: Check out repository code
# - run: ls -sl uses: actions/checkout@v4
# - run: chmod +x ./mvnw - run: echo "💡 The ${{ gitea.repository }} repository has been cloned to the runner."
- run: docker run -it --rm --name my-maven-project -v "$(pwd)":/usr/src/mymaven -v maven-repo:/root/.m2 -w /usr/src/mymaven maven mvn -DskipTests=true clean package -P prod-remote - run: echo "🖥️ The workflow is now ready to test your code on the runner."
- run: docker build -t mirai-bot:latest - name: List files in the repository
run: |
ls ${{ gitea.workspace }}
- run: echo "🍏 This job's status is ${{ job.status }}."

View File

@ -6,7 +6,7 @@
# "License"); you may not use this file except in compliance # "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at # with the License. You may obtain a copy of the License at
# #
# http://www.apache.org/licenses/LICENSE-2.0 # https://www.apache.org/licenses/LICENSE-2.0
# #
# Unless required by applicable law or agreed to in writing, # Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an # software distributed under the License is distributed on an
@ -16,4 +16,4 @@
# under the License. # under the License.
wrapperVersion=3.3.2 wrapperVersion=3.3.2
distributionType=only-script distributionType=only-script
distributionUrl=https://mirrors.huaweicloud.com/repository/maven//org/apache/maven/apache-maven/3.9.7/apache-maven-3.9.7-bin.zip distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.7/apache-maven-3.9.7-bin.zip

View File

@ -1,13 +0,0 @@
#FROM maven as builder
#WORKDIR /app
#COPY . .
#RUN mvn clean package
FROM bellsoft/liberica-openjdk-debian:17.0.11-cds
LABEL authors="Kane"
WORKDIR /opt
#COPY --from=builder /app/target/Mirai-bot-0.0.1-SNAPSHOT.jar /opt/Mirai-bot.jar
COPY target/Mirai-bot-0.0.1-SNAPSHOT.jar /opt/Mirai-bot.jar
ENTRYPOINT java -jar /opt/Mirai-bot.jar

2
mvnw vendored
View File

@ -8,7 +8,7 @@
# "License"); you may not use this file except in compliance # "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at # with the License. You may obtain a copy of the License at
# #
# http://www.apache.org/licenses/LICENSE-2.0 # https://www.apache.org/licenses/LICENSE-2.0
# #
# Unless required by applicable law or agreed to in writing, # Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an # software distributed under the License is distributed on an

2
mvnw.cmd vendored
View File

@ -8,7 +8,7 @@
@REM "License"); you may not use this file except in compliance @REM "License"); you may not use this file except in compliance
@REM with the License. You may obtain a copy of the License at @REM with the License. You may obtain a copy of the License at
@REM @REM
@REM http://www.apache.org/licenses/LICENSE-2.0 @REM https://www.apache.org/licenses/LICENSE-2.0
@REM @REM
@REM Unless required by applicable law or agreed to in writing, @REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an @REM software distributed under the License is distributed on an

58
pom.xml
View File

@ -42,37 +42,11 @@
<profiles.active>prod</profiles.active> <profiles.active>prod</profiles.active>
</properties> </properties>
</profile> </profile>
<profile>
<id>prod-remote</id>
<properties>
<profiles.active>prod-remote</profiles.active>
</properties>
</profile>
</profiles> </profiles>
<properties> <properties>
<java.version>17</java.version> <java.version>17</java.version>
<kotlin.version>1.9.25</kotlin.version> <kotlin.version>1.9.25</kotlin.version>
</properties> </properties>
<repositories>
<repository>
<id>HuaweiCloud</id>
<name>HuaweiCloud</name>
<url>https://mirrors.huaweicloud.com/repository/maven</url>
</repository>
<!-- Maven 官方仓库 -->
<repository>
<id>MavenOfficial</id>
<name>MavenOfficial</name>
<url>https://repo.maven.apache.org/maven2</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>HuaweiCloud</id>
<name>HuaweiCloud</name>
<url>https://mirrors.huaweicloud.com/repository/maven</url>
</pluginRepository>
</pluginRepositories>
<dependencies> <dependencies>
<!-- 运行依赖 --> <!-- 运行依赖 -->
<dependency> <dependency>
@ -103,6 +77,10 @@
<groupId>org.jetbrains.kotlinx</groupId> <groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx-coroutines-reactor</artifactId> <artifactId>kotlinx-coroutines-reactor</artifactId>
</dependency> </dependency>
<!-- <dependency>-->
<!-- <groupId></groupId>-->
<!-- <artifactId></artifactId>-->
<!-- </dependency>-->
<dependency> <dependency>
<groupId>com.mysql</groupId> <groupId>com.mysql</groupId>
@ -121,16 +99,9 @@
</dependency> </dependency>
<!-- 核心 机器人 --> <!-- 核心 机器人 -->
<!-- https://mvnrepository.com/artifact/top.mrxiaom.mirai/overflow-core -->
<dependency>
<groupId>top.mrxiaom.mirai</groupId>
<artifactId>overflow-core</artifactId>
<version>1.0.1</version>
</dependency>
<dependency> <dependency>
<groupId>net.mamoe</groupId> <groupId>net.mamoe</groupId>
<artifactId>mirai-core-api-jvm</artifactId> <artifactId>mirai-core-jvm</artifactId>
<version>2.16.0</version> <version>2.16.0</version>
</dependency> </dependency>
@ -139,22 +110,6 @@
<artifactId>hutool-http</artifactId> <artifactId>hutool-http</artifactId>
<version>5.8.27</version> <version>5.8.27</version>
</dependency> </dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>3.5.7</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.asynchttpclient/async-http-client -->
<dependency>
<groupId>org.asynchttpclient</groupId>
<artifactId>async-http-client</artifactId>
<version>3.0.0</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
@ -164,9 +119,6 @@
<plugin> <plugin>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId> <artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<includeSystemScope>true</includeSystemScope>
</configuration>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.jetbrains.kotlin</groupId> <groupId>org.jetbrains.kotlin</groupId>

View File

@ -1,13 +1,9 @@
package info.alinadace.miraibot package info.alinadace.miraibot
import org.mybatis.spring.annotation.MapperScan
import org.springframework.boot.autoconfigure.SpringBootApplication import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication import org.springframework.boot.runApplication
import org.springframework.scheduling.annotation.EnableScheduling
@SpringBootApplication @SpringBootApplication
@EnableScheduling
@MapperScan("info.alinadace.miraibot.service")
class MiraiBotApplication class MiraiBotApplication
fun main(args: Array<String>) { fun main(args: Array<String>) {

View File

@ -13,5 +13,5 @@ import kotlin.reflect.KClass
*/ */
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME) @Retention(AnnotationRetention.RUNTIME)
@org.springframework.stereotype.Service @org.springframework.stereotype.Service("BotFunction")
annotation class BotFunction(vararg val value: KClass<out Event>) annotation class BotFunction(vararg val value: KClass<out Event>)

View File

@ -2,14 +2,15 @@ package info.alinadace.miraibot.bean
import info.alinadace.miraibot.annotation.BotFunction import info.alinadace.miraibot.annotation.BotFunction
import info.alinadace.miraibot.configuration.BotConfig import info.alinadace.miraibot.configuration.BotConfig
import info.alinadace.miraibot.enums.LoginType
import info.alinadace.miraibot.service.Service import info.alinadace.miraibot.service.Service
import kotlinx.coroutines.async
import kotlinx.coroutines.runBlocking
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.BotFactory
import net.mamoe.mirai.auth.BotAuthorization
import net.mamoe.mirai.event.Event import net.mamoe.mirai.event.Event
import net.mamoe.mirai.utils.BotConfiguration
import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration import org.springframework.context.annotation.Configuration
import top.mrxiaom.overflow.BotBuilder
import kotlin.reflect.KClass import kotlin.reflect.KClass
/** /**
@ -22,13 +23,15 @@ class BotConfiguration {
@Bean @Bean
fun bot(config: BotConfig): Bot { fun bot(config: BotConfig): Bot {
val connect = runBlocking { return when (config.type) {
val bot = async { LoginType.PASSWORD -> BotFactory.newBot(config.id, config.password) {
BotBuilder.positive(config.ws).token(config.token).connect() ?: throw Exception("Bot connect failed") extracted()
}
LoginType.QRCODE -> BotFactory.newBot(config.id, BotAuthorization.byQRCode()) {
extracted()
} }
bot.await()
} }
return connect
} }
@Bean("functionMap") @Bean("functionMap")
@ -54,4 +57,10 @@ class BotConfiguration {
} }
return eventMap return eventMap
} }
private fun BotConfiguration.extracted() {
fileBasedDeviceInfo()
protocol = BotConfiguration.MiraiProtocol.MACOS
enableContactCache()
}
} }

View File

@ -6,54 +6,25 @@ import org.springframework.context.annotation.Configuration
/** /**
* 机器人配置 * 机器人配置
* @param id 机器人QQ号
* @param password 机器人密码
* @author Kane * @author Kane
* @since 2024/8/29 下午2:39 * @since 2024/8/29 下午2:39
*/ */
@Configuration @Configuration
@ConfigurationProperties("bot") @ConfigurationProperties("bot")
class BotConfig { class BotConfig {
/**
* 机器人QQ号
*/
@Deprecated(message = "内部认证已失效")
final var id: Long = 0L final var id: Long = 0L
/**
* 机器人密码
*/
@Deprecated(message = "内部认证已失效")
final var password: String = "" final var password: String = ""
/**
* 机器人登录方式
*/
@Deprecated(message = "内部认证已失效")
final var type: LoginType = LoginType.PASSWORD final var type: LoginType = LoginType.PASSWORD
/**
* 机器人ws地址
*/
final var ws: String = ""
/**
* 机器人token
*/
final var token: String = ""
/**
* 管理员QQ
*/
final var admin: Long = 0L final var admin: Long = 0L
constructor() constructor()
constructor(id: Long, password: String, type: LoginType, ws: String, token: String, admin: Long) { constructor(id: Long, password: String, type: LoginType, admin: Long) {
this.id = id this.id = id
this.password = password this.password = password
this.type = type this.type = type
this.ws = ws
this.token = token
this.admin = admin this.admin = admin
} }
} }

View File

@ -18,7 +18,6 @@ import kotlin.reflect.KClass
*/ */
@org.springframework.stereotype.Service @org.springframework.stereotype.Service
class Initialization { class Initialization {
@Suppress("SpringJavaInjectionPointsAutowiringInspection")
@Resource(name = "functionMap") @Resource(name = "functionMap")
lateinit var functionMap: HashMap<KClass<out Event>, MutableList<Service<Event>>> lateinit var functionMap: HashMap<KClass<out Event>, MutableList<Service<Event>>>
@ -37,10 +36,6 @@ class Initialization {
} }
} }
GlobalEventChannel.subscribeAlways(Event::class) {
log.info("GlobalEvent: {}", this)
}
log.info("Channel complete") log.info("Channel complete")
log.info("Login: id:{}", bot.id) log.info("Login: id:{}", bot.id)
bot.login() bot.login()

View File

@ -1,68 +0,0 @@
package info.alinadace.miraibot.service.drink_water
import com.baomidou.mybatisplus.extension.kotlin.KtQueryWrapper
import info.alinadace.miraibot.annotation.BotFunction
import info.alinadace.miraibot.service.Service
import info.alinadace.miraibot.service.drink_water.domain.DrinkWaterUser
import info.alinadace.miraibot.service.drink_water.mapper.DrinkWaterMapper
import jakarta.annotation.Resource
import net.mamoe.mirai.event.events.FriendMessageEvent
import net.mamoe.mirai.message.data.MessageSource
import net.mamoe.mirai.message.data.PlainText
import org.slf4j.Logger
import org.slf4j.LoggerFactory
/**
* 定时喝水提醒关闭服务
* @author Kane
* @since 2024/9/18 13:27
*/
@BotFunction(FriendMessageEvent::class)
class DisableService : Service<FriendMessageEvent> {
companion object {
val log: Logger = LoggerFactory.getLogger(this::class.java)
}
@Resource
lateinit var drinkWaterMapper: DrinkWaterMapper
/**
* 服务入口
*/
override fun entrance(event: FriendMessageEvent): Boolean {
val chain = event.message
val filter = chain.filter { it !is MessageSource }
if (filter.size == 1 && filter[0] is PlainText) {
if (filter[0].contentToString() == "关闭喝水提醒") {
return true
}
}
return false
}
/**
* 服务行为
*/
override suspend fun active(event: FriendMessageEvent) {
log.info("服务关闭请求 - DrinkWater - target:{}", event.sender.id)
val one = drinkWaterMapper.selectOne(
KtQueryWrapper(DrinkWaterUser())
.eq(DrinkWaterUser::botId, event.sender.id)
)
if (one == null) {
event.subject.sendMessage("服务已关闭 - DrinkWater")
log.info("服务已关闭 - DrinkWater - target:{} - 无记录", event.sender.id)
return
}
if (one.enable == DrinkWaterUser.ENABLE) {
one.enable = DrinkWaterUser.DISABLE
val updateById = drinkWaterMapper.updateById(one)
event.subject.sendMessage("服务已关闭 - DrinkWater")
log.info("服务已关闭 - DrinkWater - target:{} - 记录更新 - {}", event.sender.id, updateById)
return
}
event.subject.sendMessage("服务已关闭 - DrinkWater")
}
}

View File

@ -1,73 +0,0 @@
package info.alinadace.miraibot.service.drink_water
import com.baomidou.mybatisplus.extension.kotlin.KtQueryWrapper
import info.alinadace.miraibot.annotation.BotFunction
import info.alinadace.miraibot.service.Service
import info.alinadace.miraibot.service.drink_water.domain.DrinkWaterUser
import info.alinadace.miraibot.service.drink_water.mapper.DrinkWaterMapper
import jakarta.annotation.Resource
import net.mamoe.mirai.event.events.FriendMessageEvent
import net.mamoe.mirai.message.data.MessageSource
import net.mamoe.mirai.message.data.PlainText
import org.slf4j.Logger
import org.slf4j.LoggerFactory
/**
* 定时喝水提醒开启服务
* @author Kane
* @since 2024/9/18 13:27
*/
@BotFunction(FriendMessageEvent::class)
class EnableService : Service<FriendMessageEvent> {
companion object {
val log: Logger = LoggerFactory.getLogger(this::class.java)
}
@Resource
lateinit var drinkWaterMapper: DrinkWaterMapper
/**
* 服务入口
*/
override fun entrance(event: FriendMessageEvent): Boolean {
val chain = event.message
val filter = chain.filter { it !is MessageSource }
if (filter.size == 1 && filter[0] is PlainText) {
if (filter[0].contentToString() == "开启喝水提醒") {
return true
}
}
return false
}
/**
* 服务行为
*/
override suspend fun active(event: FriendMessageEvent) {
log.info("服务开启请求 - DrinkWater - target:{}", event.sender.id)
val one = drinkWaterMapper.selectOne(
KtQueryWrapper(DrinkWaterUser())
.eq(DrinkWaterUser::botId, event.sender.id)
)
if (one == null) {
val let = DrinkWaterUser().apply {
botId = event.sender.id
enable = DrinkWaterUser.ENABLE
}.let {
drinkWaterMapper.insert(it)
}
event.subject.sendMessage("服务已开启 - DrinkWater")
log.info("服务开启请求 - DrinkWater - target:{} - 记录创建 - {}", event.sender.id, let)
return
}
if (one.enable == DrinkWaterUser.DISABLE) {
one.enable = DrinkWaterUser.ENABLE
val updateById = drinkWaterMapper.updateById(one)
event.subject.sendMessage("服务已开启 - DrinkWater")
log.info("服务开启请求 - DrinkWater - target:{} - 记录更新 - {}", event.sender.id, updateById)
return
}
event.subject.sendMessage("服务已开启 - DrinkWater")
}
}

View File

@ -1,18 +0,0 @@
package info.alinadace.miraibot.service.drink_water.domain
import com.baomidou.mybatisplus.annotation.TableId
/**
* 喝水提醒用户
*/
class DrinkWaterUser {
@TableId
var id: Long? = null
var botId: Long? = null
var enable: Byte? = null
companion object {
const val ENABLE: Byte = 1
const val DISABLE: Byte = 0
}
}

View File

@ -1,11 +0,0 @@
package info.alinadace.miraibot.service.drink_water.mapper
import com.baomidou.mybatisplus.core.mapper.BaseMapper
import info.alinadace.miraibot.service.drink_water.domain.DrinkWaterUser
/**
* 喝水提醒用户Mapper
* @author Kane
* @since 2024/9/18 13:39
*/
interface DrinkWaterMapper : BaseMapper<DrinkWaterUser>

View File

@ -1,49 +0,0 @@
package info.alinadace.miraibot.service.drink_water.task
import com.baomidou.mybatisplus.extension.kotlin.KtQueryWrapper
import info.alinadace.miraibot.service.drink_water.domain.DrinkWaterUser
import info.alinadace.miraibot.service.drink_water.mapper.DrinkWaterMapper
import jakarta.annotation.Resource
import net.mamoe.mirai.Bot
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.scheduling.annotation.Scheduled
import org.springframework.stereotype.Service
/**
* 定时喝水提醒服务
* @author Kane
* @since 2024/9/18 13:59
*/
@Service
class ReminderService {
companion object {
val log: Logger = LoggerFactory.getLogger(this::class.java)
}
@Resource
lateinit var bot: Bot
@Resource
lateinit var drinkWaterMapper: DrinkWaterMapper
@Scheduled(cron = "0 0 0,8-23/2 * * *")
suspend fun reminder() {
log.info("定时喝水提醒服务 - 开始")
val list = drinkWaterMapper.selectList(
KtQueryWrapper(DrinkWaterUser())
.eq(DrinkWaterUser::enable, DrinkWaterUser.ENABLE)
)
log.info("定时喝水提醒服务 - 查询结果 - {}", list)
list.forEach {
if (it.botId == null || it.botId == 0L) {
return@forEach
}
bot.getFriend(it.botId!!)?.sendMessage("请喝水")
log.info("定时喝水提醒服务 - 发送消息 - {}", it.botId)
}
log.info("定时喝水提醒服务 - 结束")
}
}

View File

@ -1,17 +1,2 @@
bot: bot:
id: 3437522130 id: 3437522130
type: password
password: nobuts001
spring:
data:
redis:
host: 101.35.164.171
password: wTE32JjsieQ2JTOwsg9X
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mirai?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
username: root
password: nobuts001
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

View File

@ -1,14 +0,0 @@
bot:
id: 3437522130
type: password
password: nobuts001
spring:
data:
redis:
host: 101.35.164.171
password: wTE32JjsieQ2JTOwsg9X
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://101.35.164.171:3306/mirai?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
username: mirai
password: FydsaZsFm5w26We6

View File

@ -1,14 +0,0 @@
bot:
id: 3437522130
type: password
password: nobuts001
spring:
data:
redis:
host: 10.0.4.16
password: wTE32JjsieQ2JTOwsg9X
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://10.0.4.16:3306/mirai?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
username: mirai
password: FydsaZsFm5w26We6

View File

@ -8,4 +8,3 @@ bot:
admin: 1075576561 admin: 1075576561
server: server:
port: 25684 # 无用随机端口 port: 25684 # 无用随机端口