diff --git a/mvnw.cmd b/mvnw.cmd
index 249bdf3..d8d70f7 100644
--- a/mvnw.cmd
+++ b/mvnw.cmd
@@ -32,7 +32,7 @@
@SET __MVNW_ERROR__=
@SET __MVNW_PSMODULEP_SAVE=%PSModulePath%
@SET PSModulePath=
-@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @(
+@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-info.alinadace.sakuramiki.service.randomphoto.domain.Content -Raw '%~f0'))) -NoNewScope}"`) DO @(
IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B)
)
@SET PSModulePath=%__MVNW_PSMODULEP_SAVE%
@@ -51,7 +51,7 @@ if ($env:MVNW_VERBOSE -eq "true") {
}
# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties
-$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl
+$distributionUrl = (Get-info.alinadace.sakuramiki.service.randomphoto.domain.Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl
if (!$distributionUrl) {
Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
}
@@ -121,7 +121,7 @@ if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) {
$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null
# If specified, validate the SHA-256 sum of the Maven distribution zip file
-$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum
+$distributionSha256Sum = (Get-info.alinadace.sakuramiki.service.randomphoto.domain.Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum
if ($distributionSha256Sum) {
if ($USE_MVND) {
Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties."
diff --git a/pom.xml b/pom.xml
index 4896fd3..db7dccc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -11,8 +11,8 @@
info.alinadace
sakura-miki
0.0.1-SNAPSHOT
- sakuramiki
- sakuramiki
+ Sakura-Miki
+ Sakura-Miki
@@ -127,6 +127,21 @@
org.springframework.boot
spring-boot-starter-actuator
+
+
+ com.beust
+ klaxon
+ 5.6
+
+
+ io.github.1530624156
+ AlistUtil
+ 1.0.0-spring
+
+
+ com.squareup.okhttp3
+ okhttp
+
diff --git a/src/main/kotlin/info/alinadace/sakuramiki/service/ExampleService.kt b/src/main/kotlin/info/alinadace/sakuramiki/service/ExampleService.kt
index 2ffc308..cdb74b9 100644
--- a/src/main/kotlin/info/alinadace/sakuramiki/service/ExampleService.kt
+++ b/src/main/kotlin/info/alinadace/sakuramiki/service/ExampleService.kt
@@ -34,7 +34,7 @@ class ExampleService : Service {
return true
}
}
- return true
+ return false
}
/**
diff --git a/src/main/kotlin/info/alinadace/sakuramiki/service/randomphoto/RandomPhotoService.kt b/src/main/kotlin/info/alinadace/sakuramiki/service/randomphoto/RandomPhotoService.kt
new file mode 100644
index 0000000..a1932c3
--- /dev/null
+++ b/src/main/kotlin/info/alinadace/sakuramiki/service/randomphoto/RandomPhotoService.kt
@@ -0,0 +1,69 @@
+package info.alinadace.sakuramiki.service.randomphoto
+
+import com.mavis.service.AlistService
+import info.alinadace.sakuramiki.annotation.BotFunction
+import info.alinadace.sakuramiki.service.Service
+import info.alinadace.sakuramiki.service.randomphoto.domain.FileList
+import info.alinadace.sakuramiki.service.randomphoto.domain.SingleFile
+import info.alinadace.sakuramiki.util.okHttpClient
+import io.github.kloping.qqbot.api.v2.FriendMessageEvent
+import io.github.kloping.qqbot.api.v2.GroupMessageEvent
+import io.github.kloping.qqbot.api.v2.MessageV2Event
+import io.github.kloping.qqbot.entities.ex.Image
+import io.github.kloping.qqbot.entities.ex.PlainText
+import jakarta.annotation.Resource
+import okhttp3.Request
+
+/**
+ * @author Kane
+ * @since 2024/11/11 19:26
+ */
+@BotFunction(FriendMessageEvent::class, GroupMessageEvent::class)
+class RandomPhotoService : Service {
+
+ @Resource
+ lateinit var alistService: AlistService
+
+ /**
+ * 服务入口
+ */
+ override fun entrance(event: MessageV2Event): Boolean {
+ val chain = event.message
+ if (chain.size == 1 && chain[0] is PlainText && chain[0].toString() == "#photo") {
+ return true
+ }
+ return true
+ }
+
+ /**
+ * 服务行为
+ */
+ override fun active(event: MessageV2Event) {
+ val fileList = alistService.getAlistFileList("/VRChat-Photo")
+ val files = FileList.fromJson(fileList)
+ if (files.code != 200L) {
+ event.send("文件列表获取失败")
+ }
+ val content = files.data.content.filter { x -> !x.isDir }
+ if (content.isEmpty()) {
+ event.send("暂无照片")
+ return
+ }
+ val randomFile = content.random()
+ val fileInfo = alistService.getAlistFileInfo("/VRChat-Photo/" + randomFile.name, "")
+ val file = SingleFile.fromJson(fileInfo)
+ if (file.code != 200L) {
+ event.send("文件获取失败")
+ return
+ }
+ event.send("图片下载中...")
+ val request = Request.Builder().get().url(file.data.rawURL).build()
+ val imageByte = okHttpClient.newCall(request).execute().body?.bytes();
+ if (imageByte == null) {
+ event.send("图片下载失败")
+ return
+ }
+ val image = Image(imageByte)
+ event.send(image)
+ }
+}
diff --git a/src/main/kotlin/info/alinadace/sakuramiki/service/randomphoto/domain/FileList.kt b/src/main/kotlin/info/alinadace/sakuramiki/service/randomphoto/domain/FileList.kt
new file mode 100644
index 0000000..12b8ef9
--- /dev/null
+++ b/src/main/kotlin/info/alinadace/sakuramiki/service/randomphoto/domain/FileList.kt
@@ -0,0 +1,128 @@
+package info.alinadace.sakuramiki.service.randomphoto.domain
+
+// To parse the JSON, install jackson-module-kotlin and do:
+//
+// val response = FileList.fromJson(jsonString)
+
+import com.fasterxml.jackson.annotation.JsonInclude
+import com.fasterxml.jackson.annotation.JsonProperty
+import com.fasterxml.jackson.databind.PropertyNamingStrategies
+import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
+import com.fasterxml.jackson.module.kotlin.readValue
+
+
+data class FileList(
+ /**
+ * 状态码
+ */
+ @get:JsonProperty(required = true) @field:JsonProperty(required = true)
+ val code: Long,
+
+ @get:JsonProperty(required = true) @field:JsonProperty(required = true)
+ val data: Data,
+
+ /**
+ * 信息
+ */
+ @get:JsonProperty(required = true) @field:JsonProperty(required = true)
+ val message: String
+) {
+
+ fun toJson() = mapper.writeValueAsString(this)
+
+ companion object {
+ private var mapper = jacksonObjectMapper().apply {
+ propertyNamingStrategy = PropertyNamingStrategies.LOWER_CAMEL_CASE
+ setSerializationInclusion(JsonInclude.Include.NON_NULL)
+ }
+
+ fun fromJson(json: String) = mapper.readValue(json)
+ }
+
+ data class Data(
+ /**
+ * 内容
+ */
+ @get:JsonProperty(required = true) @field:JsonProperty(required = true)
+ val content: List,
+
+ @get:JsonProperty(required = true) @field:JsonProperty(required = true)
+ val header: String,
+
+ @get:JsonProperty(required = true) @field:JsonProperty(required = true)
+ val provider: String,
+
+ /**
+ * 说明
+ */
+ @get:JsonProperty(required = true) @field:JsonProperty(required = true)
+ val readme: String,
+
+ /**
+ * 总数
+ */
+ @get:JsonProperty(required = true) @field:JsonProperty(required = true)
+ val total: Long,
+
+ /**
+ * 是否可写入
+ */
+ @get:JsonProperty(required = true) @field:JsonProperty(required = true)
+ val write: Boolean
+ ) {
+ data class Content(
+ /**
+ * 创建时间
+ */
+ val created: String? = null,
+
+ @get:JsonProperty("hash_info") @field:JsonProperty("hash_info")
+ val hashInfo: Any? = null,
+
+ val hashinfo: String? = null,
+
+ /**
+ * 是否是文件夹
+ */
+ @get:JsonProperty("is_dir", required = true) @field:JsonProperty("is_dir", required = true)
+ val isDir: Boolean,
+
+ /**
+ * 修改时间
+ */
+ @get:JsonProperty(required = true) @field:JsonProperty(required = true)
+ val modified: String,
+
+ /**
+ * 文件名
+ */
+ @get:JsonProperty(required = true) @field:JsonProperty(required = true)
+ val name: String,
+
+ /**
+ * 签名
+ */
+ @get:JsonProperty(required = true) @field:JsonProperty(required = true)
+ val sign: String,
+
+ /**
+ * 大小
+ */
+ @get:JsonProperty(required = true) @field:JsonProperty(required = true)
+ val size: Long,
+
+ /**
+ * 缩略图
+ */
+ @get:JsonProperty(required = true) @field:JsonProperty(required = true)
+ val thumb: String,
+
+ /**
+ * 类型
+ */
+ @get:JsonProperty(required = true) @field:JsonProperty(required = true)
+ val type: Long
+ )
+ }
+}
+
diff --git a/src/main/kotlin/info/alinadace/sakuramiki/service/randomphoto/domain/SingleFile.kt b/src/main/kotlin/info/alinadace/sakuramiki/service/randomphoto/domain/SingleFile.kt
new file mode 100644
index 0000000..17b5f87
--- /dev/null
+++ b/src/main/kotlin/info/alinadace/sakuramiki/service/randomphoto/domain/SingleFile.kt
@@ -0,0 +1,117 @@
+package info.alinadace.sakuramiki.service.randomphoto.domain
+// To parse the JSON, install jackson-module-kotlin and do:
+//
+// val response = SingleFile.fromJson(jsonString)
+
+import com.fasterxml.jackson.annotation.JsonInclude
+import com.fasterxml.jackson.annotation.JsonProperty
+import com.fasterxml.jackson.databind.PropertyNamingStrategies
+import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
+import com.fasterxml.jackson.module.kotlin.readValue
+
+
+data class SingleFile(
+ /**
+ * 状态码
+ */
+ @get:JsonProperty(required = true) @field:JsonProperty(required = true)
+ val code: Long,
+
+ @get:JsonProperty(required = true) @field:JsonProperty(required = true)
+ val data: Data,
+
+ /**
+ * 信息
+ */
+ @get:JsonProperty(required = true) @field:JsonProperty(required = true)
+ val message: String
+) {
+
+ fun toJson() = mapper.writeValueAsString(this)
+
+ companion object {
+ private val mapper = jacksonObjectMapper().apply {
+ propertyNamingStrategy = PropertyNamingStrategies.LOWER_CAMEL_CASE
+ setSerializationInclusion(JsonInclude.Include.NON_NULL)
+ }
+
+ fun fromJson(json: String) = mapper.readValue(json)
+ }
+
+ data class Data(
+ /**
+ * 创建时间
+ */
+ @get:JsonProperty(required = true) @field:JsonProperty(required = true)
+ val created: String,
+
+ @get:JsonProperty("hash_info") @field:JsonProperty("hash_info")
+ val hashInfo: Any? = null,
+
+ @get:JsonProperty(required = true) @field:JsonProperty(required = true)
+ val hashinfo: String,
+
+ @get:JsonProperty(required = true) @field:JsonProperty(required = true)
+ val header: String,
+
+ /**
+ * 是否是文件夹
+ */
+ @get:JsonProperty("is_dir", required = true) @field:JsonProperty("is_dir", required = true)
+ val isDir: Boolean,
+
+ /**
+ * 修改时间
+ */
+ @get:JsonProperty(required = true) @field:JsonProperty(required = true)
+ val modified: String,
+
+ /**
+ * 文件名
+ */
+ @get:JsonProperty(required = true) @field:JsonProperty(required = true)
+ val name: String,
+
+ @get:JsonProperty(required = true) @field:JsonProperty(required = true)
+ val provider: String,
+
+ /**
+ * 原始url
+ */
+ @get:JsonProperty("raw_url", required = true) @field:JsonProperty("raw_url", required = true)
+ val rawURL: String,
+
+ /**
+ * 说明
+ */
+ @get:JsonProperty(required = true) @field:JsonProperty(required = true)
+ val readme: String,
+
+ val related: Any? = null,
+
+ /**
+ * 签名
+ */
+ @get:JsonProperty(required = true) @field:JsonProperty(required = true)
+ val sign: String,
+
+ /**
+ * 大小
+ */
+ @get:JsonProperty(required = true) @field:JsonProperty(required = true)
+ val size: Long,
+
+ /**
+ * 缩略图
+ */
+ @get:JsonProperty(required = true) @field:JsonProperty(required = true)
+ val thumb: String,
+
+ /**
+ * 类型
+ */
+ @get:JsonProperty(required = true) @field:JsonProperty(required = true)
+ val type: Long
+ )
+}
+
diff --git a/src/main/kotlin/info/alinadace/sakuramiki/util/OkHttp.kt b/src/main/kotlin/info/alinadace/sakuramiki/util/OkHttp.kt
new file mode 100644
index 0000000..7d6b5f0
--- /dev/null
+++ b/src/main/kotlin/info/alinadace/sakuramiki/util/OkHttp.kt
@@ -0,0 +1,12 @@
+package info.alinadace.sakuramiki.util
+
+import okhttp3.OkHttpClient
+
+/**
+ * @author Kane
+ * @since 2024/11/11 20:39
+ */
+
+// 创建 OkHttpClient 实例
+val okHttpClient = OkHttpClient.Builder()
+ .build()
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 219505a..c60bb00 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -12,3 +12,8 @@ bot:
token: sq3CZjEpK7Z65s2xuyhwp8WVBqvx35XP
app-secret: Wgq0BMXit5HTfr3GTgt6JXlzDRgvAPet
admin: 59EC2526FBCC1EC5F851187C0F4F8BA5
+
+alist:
+ alist-base-url: https://alist.alina-dace.info
+ alist-username: admin
+ alist-password: vF7Wb2vo