82 Commits
Author SHA1 Message Date
RTAkland a134406764 Remove 2025-05-22 01:11:36 +08:00
RTAkland 93a2bf949a Fix nslookup 2025-05-22 01:08:19 +08:00
RTAkland 11e65d99ba Update 2025-05-16 02:36:37 +08:00
RTAkland c049fb1d8a Upgrade rob 2025-05-06 02:42:19 +08:00
RTAkland bfbba46d0a fix: fix niuzi manager command 2025-03-17 08:29:15 +08:00
RTAkland f6f83e2454 update rob version 2025-02-21 18:35:14 +08:00
RTAkland cb5b989b38 feat: add mrrhr image generate 2025-02-21 17:38:54 +08:00
RTAkland 586714d704 remove unused func 2025-02-20 19:36:24 +08:00
RTAkland 510fdc0c60 faet: add good news command 2025-02-20 19:19:18 +08:00
RTAkland d68753df98 feat: add today somke 2025-02-18 22:18:16 +08:00
RTAkland 5852ceb5ba feat: add osu pp query 2025-02-06 22:39:24 +08:00
RTAkland b7db3b3e98 chore: update osu command progress style 2025-02-05 13:28:27 +08:00
RTAkland 6bce847a0f feat: add osu command 2025-02-05 13:24:18 +08:00
RTAkland 24c8ef0cb7 fix 2025-01-18 19:27:37 +08:00
RTAkland 411b468e5e fix 2025-01-18 19:14:09 +08:00
RTAkland 5060afd43e adjust font position 2025-01-15 16:23:24 +08:00
RTAkland 5e4d4e4bfc add sh command 2025-01-15 16:21:41 +08:00
RTAkland d406e74659 add sj command 2025-01-15 16:21:24 +08:00
RTAkland a6b8698a68 add xnm command 2025-01-15 14:06:02 +08:00
RTAkland 4be2791c92 add command alia 2025-01-15 13:51:34 +08:00
RTAkland cc0c0f4022 chore: adjust font size 2025-01-15 13:46:56 +08:00
RTAkland 8589951cc4 feat: add tjbgxl command 2025-01-15 13:45:54 +08:00
RTAkland 7f199959f1 feat: add nwwn command 2025-01-15 00:27:37 +08:00
RTAkland 5584b18f2f feat: add nwwn command 2025-01-15 00:24:50 +08:00
RTAkland 64f256fb25 feat: add nwwn command 2025-01-15 00:23:31 +08:00
RTAkland 8107117e5f update maven repo 2025-01-12 16:45:50 +08:00
RTAkland 59105331fb fix 2025-01-03 19:52:05 +08:00
RTAkland c1172b8867 fix: remove genshin reply and fix bug 2025-01-03 19:10:30 +08:00
RTAkland f925a77cdb bump ronebot 2024-12-17 18:13:23 +08:00
RTAkland c376612d77 chore: update maven repository 2024-12-17 13:40:07 +08:00
RTAkland 8b90790395 feat: add split frame and upgrade ronebot to 2.5.2 2024-11-14 20:09:15 +08:00
RTAkland ca304874dc chore: format code 2024-11-09 20:55:14 +08:00
RTAkland 56270771b0 chore: upgrade ronebot to 2.4.8 use space split command 2024-11-09 20:45:32 +08:00
RTAkland 12064dfe10 feat: upgrade ronebot to 2.4.7, now it can send command without space 2024-11-09 19:05:13 +08:00
RTAkland 6b5ca9c38b chore: format code 2024-11-09 13:22:12 +08:00
RTAkland 5b8de20430 chore: upgrade ronebot to 2.4.5 2024-11-08 20:59:51 +08:00
RTAkland a2bdcc5232 chore: upgrade ronebot to 2.4.4 2024-11-08 20:33:55 +08:00
RTAkland 9838d90855 chore: remove nailong dectect 2024-11-08 12:22:25 +08:00
RTAkland 43b3e96881 chore: upgrade ronebot to 2.4.3 2024-11-08 12:20:13 +08:00
RTAkland be03a90d72 chore: upgrade ronebot to 2.4.2 2024-11-07 19:44:07 +08:00
RTAkland 159f83a89f chore: upgrade ronebot to 2.4.1 2024-11-07 19:09:08 +08:00
RTAkland 760aeeca82 chore: remove sensitive word filter 2024-11-07 18:34:59 +08:00
RTAkland 42c215420a feat: add command execution times counter 2024-11-07 17:07:05 +08:00
RTAkland 5320836d26 feat: add sensitive word filter 2024-11-07 17:02:49 +08:00
RTAkland 4117c3d253 chore: upgrade ronebot to 2.3.6 2024-11-07 15:24:11 +08:00
RTAkland 9a018c0bdd chore: upgrade gradle to 8.10.2 2024-11-04 19:04:46 +08:00
RTAkland 8dee66d022 chore: upgrade ronebot 2024-11-04 18:45:10 +08:00
RTAkland b3410e6d07 feat: add ai tts command 2024-11-03 20:15:53 +08:00
RTAkland 7935597a05 chore: upgrade ronebot 2024-11-03 15:35:31 +08:00
RTAkland 217e465d62 chore: reduce jar file size and unsupport sqlite/postgresql/mysql 2024-11-02 19:19:57 +08:00
RTAkland 1cd2242c6f chore: remove repeater 2024-11-01 19:06:05 +08:00
RTAkland 229c73b6ac fix: while repeat 2024-11-01 18:55:09 +08:00
RTAkland 4be023282e fix: fix repeater 2024-11-01 17:21:49 +08:00
RTAkland 8541358348 feat: add repeater 2024-11-01 17:12:53 +08:00
RTAkland 81e2169c1e chore: remove unused maven repo 2024-11-01 09:38:52 +08:00
RTAkland fac2d5491a feat: add more feature 2024-10-31 21:32:42 +08:00
RTAkland 2c0ca2f739 chore: bump rob 2024-10-31 14:02:04 +08:00
RTAkland b85b0bf33a feat: add help help 2024-10-30 18:14:26 +08:00
RTAkland 321a82e599 chore: bump rob 2024-10-30 15:33:38 +08:00
RTAkland 8c7227c77d chore: bump rob 2024-10-30 12:05:03 +08:00
RTAkland 82c1f4f89d chore: bumo rob 2024-10-29 19:32:38 +08:00
RTAkland 9af2916dfc feat: support greyscale a gif 2024-10-29 11:47:25 +08:00
RTAkland 40d4661e1b chore: bump rob 2024-10-28 19:09:19 +08:00
RTAkland b1405ad3e8 chore: bump rob 2024-10-28 12:32:51 +08:00
RTAkland edfbb820a0 chore: remove double reply 2024-10-28 11:26:44 +08:00
RTAkland c139c09b1a fix: fix reaction target 2024-10-27 18:42:30 +08:00
RTAkland 9ee543b1e1 feat: add greyscale command 2024-10-27 18:25:34 +08:00
RTAkland d45ab4e286 ci: remove code line count 2024-10-27 18:20:25 +08:00
RTAkland ad12ff5ce8 feat: add get avatar command 2024-10-27 18:19:32 +08:00
RTAkland f9b52c8c4b chore: add command prefix 2024-10-27 18:01:54 +08:00
RTAkland a99f636158 fix: fix speed up will reverse gif 2024-10-27 18:00:34 +08:00
RTAkland c0fa5c3a49 feat: add gif speed up and speed down command 2024-10-27 17:43:06 +08:00
RTAkland c3dc3fa4e5 chore: bump rob 2024-10-27 11:02:06 +08:00
RTAkland 7e851e831a feat: add nailong detect 2024-10-26 11:46:32 +08:00
RTAkland b238ec5f30 chore: bump rob version 2024-10-25 19:44:33 +08:00
RTAkland b0446d9baf ci 2024-10-25 17:50:36 +08:00
RTAkland 7994861348 ci 2024-10-25 17:32:52 +08:00
RTAkland 64c4fd04b1 chore: format code 2024-10-25 14:26:45 +08:00
RTAkland 2115f3d63a fix: fix music command not work and bump ronebot version 2024-10-25 14:25:43 +08:00
RTAkland c1ba1cd5b1 fix: bump rob to fix command pattern 2024-10-24 21:29:40 +08:00
RTAkland b1f13b6754 chore: bump rob 2024-10-24 19:27:06 +08:00
RTAkland 41463b8b18 feat: migrate to multi-instance ronebot 2024-10-24 16:55:14 +08:00
160 changed files with 1220 additions and 826 deletions

No files matched your search

-19
View File
@@ -1,19 +0,0 @@
name: Count Lines of Code
on:
push:
branches:
- main
jobs:
count-loc:
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v3
- name: Install cloc
run: sudo apt-get install -y cloc
- name: Count lines of code
id: cloc
run: |
cloc . >> $GITHUB_STEP_SUMMARY
+3 -10
View File
@@ -15,12 +15,10 @@ version = fancyBotVersion
repositories {
mavenCentral()
mavenLocal()
maven("https://jitpack.io")
maven("https://repo.opencollab.dev/main/")
maven("https://oss.sonatype.org/content/repositories/snapshots")
maven("https://repo.rtast.cn/api/v4/projects/33/packages/maven")
maven("https://repo.rtast.cn/api/v4/projects/19/packages/maven")
maven("https://repo.rtast.cn/api/v4/projects/3/packages/maven")
maven("https://repo.maven.rtast.cn/releases/")
maven("https://libraries.minecraft.net")
}
tasks.compileKotlin {
@@ -32,16 +30,13 @@ tasks.compileJava {
targetCompatibility = "17"
}
dependencies {
implementation(libs.ronebot)
implementation(libs.okhttp)
implementation(libs.exposed.core)
implementation(libs.exposed.jdbc)
implementation(libs.exposed.dao)
implementation(libs.sqlite.jdbc)
implementation(libs.mysql.jdbc)
implementation(libs.postgressql.jdbc)
implementation(libs.h2.jdbc)
implementation(libs.motd.pinger)
implementation(libs.animated.gif.lib)
implementation(libs.simple.java.mail)
@@ -49,8 +44,6 @@ dependencies {
implementation(libs.nashorn.core)
implementation(libs.zxing.core)
implementation(libs.zxing.javase)
implementation(libs.logback.classic)
implementation(libs.slf4j.api)
implementation(libs.aws.s3.sdk)
implementation(libs.rconlib)
implementation(libs.mcprotocollib)
+5
View File
@@ -1,2 +1,7 @@
kotlin.code.style=official
fancyBotVersion=1.0.0
#systemProp.http.proxyHost=127.0.0.1
#systemProp.http.proxyPort=12334
#systemProp.https.proxyHost=127.0.0.1
#systemProp.https.proxyPort=12334
+7 -15
View File
@@ -1,45 +1,37 @@
[versions]
kotlinVersion = "2.0.20"
ronebotVersion = "1.14.1"
ronebotVersion = "2.7.4"
shadowVersion = "8.3.0"
okhttpVersion = "5.0.0-alpha.14"
exposedVersion = "0.53.0"
sqliteJDBCVersion = "3.46.1.0"
motdPingerVersion = "1.1.4"
animatedGifLibVersion = "1.4"
simpleJavaMailVersion = "8.12.2"
jsoupVersion = "1.18.1"
nashornVersion = "15.4"
zxingVersion = "3.5.3"
logbackClassicVersion = "1.5.8"
slf4jVersion = "2.0.16"
awsS3SDKVersion = "2.28.18"
rconLibVersion = "1.1.0"
mysqlConnectorVersion = "9.1.0"
postgresqlVersion = "42.7.4"
rconLibVersion = "1.1.1"
mcprotolobVersion = "1.21-SNAPSHOT"
h2Version = "2.3.232"
[libraries]
ronebot = { group = "cn.rtast", name = "ROneBot", version.ref = "ronebotVersion" }
motd-pinger = { group = "cn.rtast", name = "MotdPinger", version.ref = "motdPingerVersion" }
ronebot = { group = "cn.rtast.rob", name = "ronebot-onebot-v11", version.ref = "ronebotVersion" }
motd-pinger = { group = "cn.rtast", name = "motd-pinger", version.ref = "motdPingerVersion" }
okhttp = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okhttpVersion" }
exposed-core = { group = "org.jetbrains.exposed", name = "exposed-core", version.ref = "exposedVersion" }
exposed-jdbc = { group = "org.jetbrains.exposed", name = "exposed-jdbc", version.ref = "exposedVersion" }
exposed-dao = { group = "org.jetbrains.exposed", name = "exposed-dao", version.ref = "exposedVersion" }
sqlite-jdbc = { group = "org.xerial", name = "sqlite-jdbc", version.ref = "sqliteJDBCVersion" }
mysql-jdbc = { group = "com.mysql", name = "mysql-connector-j", version.ref = "mysqlConnectorVersion" }
postgressql-jdbc = { group = "org.postgresql", name = "postgresql", version.ref = "postgresqlVersion" }
animated-gif-lib = { group = "com.madgag", name = "animated-gif-lib", version.ref = "animatedGifLibVersion" }
simple-java-mail = { group = "org.simplejavamail", name = "simple-java-mail", version.ref = "simpleJavaMailVersion" }
jsoup = { group = "org.jsoup", name = "jsoup", version.ref = "jsoupVersion" }
nashorn-core = { group = "org.openjdk.nashorn", name = "nashorn-core", version.ref = "nashornVersion" }
zxing-core = { group = "com.google.zxing", name = "core", version.ref = "zxingVersion" }
zxing-javase = { group = "com.google.zxing", name = "javase", version.ref = "zxingVersion" }
logback-classic = { group = "ch.qos.logback", name = "logback-classic", version.ref = "logbackClassicVersion" }
slf4j-api = { group = "org.slf4j", name = "slf4j-api", version.ref = "slf4jVersion" }
aws-s3-sdk = { group = "software.amazon.awssdk", name = "s3", version.ref = "awsS3SDKVersion" }
rconlib = { group = "cn.rtast", name = "RCONLib", version.ref = "rconLibVersion" }
rconlib = { group = "cn.rtast", name = "rconlib", version.ref = "rconLibVersion" }
mcprotocollib = { group = "org.geysermc.mcprotocollib", name = "protocol", version.ref = "mcprotolobVersion" }
h2-jdbc = { group = "com.h2database", name = "h2", version.ref = "h2Version" }
[bundles]
Binary file not shown.
+3 -2
View File
@@ -1,6 +1,7 @@
#Mon Aug 26 20:47:33 CST 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Vendored
+31 -13
View File
@@ -15,6 +15,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#
##############################################################################
#
@@ -55,7 +57,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
@@ -80,13 +82,12 @@ do
esac
done
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
@@ -133,22 +134,29 @@ location of your Java installation."
fi
else
JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
@@ -193,11 +201,15 @@ if "$cygwin" || "$msys" ; then
done
fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
@@ -205,6 +217,12 @@ set -- \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
Vendored
+21 -16
View File
@@ -13,8 +13,10 @@
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%" == "" @echo off
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@@ -25,7 +27,8 @@
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@@ -40,13 +43,13 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
@@ -56,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
@@ -75,13 +78,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
+12 -35
View File
@@ -8,35 +8,22 @@
package cn.rtast.fancybot
import cn.rtast.fancybot.commands.AboutCommand
import cn.rtast.fancybot.commands.EchoCommand
import cn.rtast.fancybot.commands.HelpCommand
import cn.rtast.fancybot.commands.ShuffleEchoCommand
import cn.rtast.fancybot.commands.StatusCommand
import cn.rtast.fancybot.commands.SupportMeCommand
import cn.rtast.fancybot.commands.*
import cn.rtast.fancybot.commands.lookup.*
import cn.rtast.fancybot.commands.misc.*
import cn.rtast.fancybot.commands.misc.JrrpCommand
import cn.rtast.fancybot.commands.misc.ShortLinkCommand
import cn.rtast.fancybot.commands.niuzi.*
import cn.rtast.fancybot.commands.niuzi.NiuziRedeemCommand
import cn.rtast.fancybot.commands.parse.AsciiArtCommand
import cn.rtast.fancybot.commands.parse.ReverseGIFCommand
import cn.rtast.fancybot.entity.Config
import cn.rtast.fancybot.enums.DatabaseType
import cn.rtast.fancybot.enums.ImageBedType
import cn.rtast.fancybot.enums.ImageType
import cn.rtast.fancybot.enums.WSType
import cn.rtast.fancybot.items.*
import cn.rtast.fancybot.util.file.BlackListManager
import cn.rtast.fancybot.util.file.ConfigManager
import cn.rtast.fancybot.util.file.NiuziBankManager
import cn.rtast.fancybot.util.file.NiuziManager
import cn.rtast.fancybot.util.file.RCONManager
import cn.rtast.fancybot.util.file.*
import cn.rtast.fancybot.util.item.ItemManager
import cn.rtast.rob.ROneBotFactory
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import java.io.File
import java.time.Instant
val gson: Gson = GsonBuilder()
@@ -45,19 +32,12 @@ val gson: Gson = GsonBuilder()
.create()
const val ROOT_PATH = "./data"
val ROOT_PATH_ = File(ROOT_PATH).apply { mkdirs() }
const val ASSETS_BASE_URL = "https://static.rtast.cn"
const val API_RTAST_URL = "https://api.rtast.cn"
const val PBI_API_URL = "https://pbi.us.kg"
val DEFAULT_CONFIG = Config(
database = Config.Database(
DatabaseType.SQLite,
"127.0.0.1",
3306,
"root",
"114514",
"fancybot"
),
ncmAPI = "https://ncm.rtast.cn",
wsAddress = "ws://127.0.0.1",
wsType = WSType.Client,
@@ -94,7 +74,10 @@ val DEFAULT_CONFIG = Config(
apiSpaceKey = "114514",
apiRtastKey = "114514",
azureAppClientId = "114514",
youtubeDataApiKey = "114514"
youtubeDataApiKey = "114514",
naiLongApiUrl = "http://127.0.0.1:5000/nailong",
osuClientId = 111,
osuClientSecret = "222"
)
val configManager = ConfigManager()
@@ -112,19 +95,11 @@ val items = listOf(
TenSetuItem(), TenSetuR18Item()
)
val tasks = mapOf(
10000000L to suspend {
configManager.admins.forEach {
ROneBotFactory.action.sendLike(it, 1)
}
}
)
val commands = listOf(
EchoCommand(), JrrpCommand(), NiuziRedeemCommand(), HitokotoCommand(),
KFCCommand(), GenerateQRCodeCommand(), AntiRevokeCommand(), MCPingCommand(),
WeatherCommand(), CigaretteCommand(), RemakeCommand(), PixivCommand(),
RUACommand(), NslookupCommand(), CompilerCommand(), AICommand(),
RUACommand(), CompilerCommand(), AICommand(),
GithubUserCommand(), AboutCommand(), MusicPlayUrlCommand(), DomainPriceCommand(),
SendMailCommand(), ZiBiCommand(), UnsetZiBiCommand(), WikipediaCommand(),
AsciiArtCommand(), StatusCommand(), JueCommand(), ShortLinkCommand(),
@@ -140,5 +115,7 @@ val commands = listOf(
MinecraftWikiCommand(), GaoKaoDaysRemainCommand(), IdiomExplainCommand(), NiuziManagerCommand(),
TodayEatCommand(), TodayDrinkCommand(), MCLoginCommand(), RCONCommand(),
GravatarCommand(), PastebinCommand(), ShuffleEchoCommand(), TodayDontEatCommand(),
TodayDontDrinkCommand(), MCBotCommand(), HTTPCatCommand(), HTTPDogCommand()
TodayDontDrinkCommand(), MCBotCommand(), HTTPCatCommand(), HTTPDogCommand(),
AITTSCommand(), NWWNCommand(), TJBGXLCommand(), XNMCommand(), SJCommand(),
OSUCommand(), TodaySmokeCommand(), GoodNewsCommand(), MRRHRCommand()
)
+165 -77
View File
@@ -7,41 +7,54 @@
package cn.rtast.fancybot
import cn.rtast.fancybot.commands.misc.JueCommand
import cn.rtast.fancybot.commands.misc.PastebinCommand
import cn.rtast.fancybot.commands.misc.ReactionCommand
import cn.rtast.fancybot.commands.misc.ScanQRCodeCommand
import cn.rtast.fancybot.commands.misc.ShortLinkCommand.Companion.makeShortLink
import cn.rtast.fancybot.commands.parse.*
import cn.rtast.fancybot.commands.reply.ImageBedCommand
import cn.rtast.fancybot.commands.reply.InvertImageCommand
import cn.rtast.fancybot.commands.reply.RandomRGBCommand
import cn.rtast.fancybot.commands.reply.SpeedUpGIFCommand
import cn.rtast.fancybot.enums.WSType
import cn.rtast.fancybot.util.*
import cn.rtast.fancybot.util.misc.convertToDate
import cn.rtast.fancybot.util.misc.initBackgroundTasks
import cn.rtast.fancybot.util.misc.initCommand
import cn.rtast.fancybot.util.misc.initFilesDir
import cn.rtast.fancybot.util.misc.initItems
import cn.rtast.fancybot.util.misc.initSetuIndex
import cn.rtast.fancybot.util.Logger
import cn.rtast.fancybot.util.initDatabase
import cn.rtast.fancybot.util.misc.*
import cn.rtast.fancybot.util.str.encodeToBase64
import cn.rtast.rob.ROneBotFactory
import cn.rtast.rob.entity.*
import cn.rtast.rob.entity.custom.BeKickEvent
import cn.rtast.rob.entity.custom.ErrorEvent
import cn.rtast.rob.entity.custom.MemberKickEvent
import cn.rtast.rob.entity.custom.MemberLeaveEvent
import cn.rtast.rob.entity.lagrange.FileEvent
import cn.rtast.rob.entity.lagrange.PokeEvent
import cn.rtast.rob.enums.ArrayMessageType
import cn.rtast.rob.enums.QQFace
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.onebot.OneBotAction
import cn.rtast.rob.onebot.OneBotListener
import cn.rtast.rob.segment.NewLine
import cn.rtast.rob.segment.Text
import com.madgag.gif.fmsware.GifDecoder
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.ByteArrayOutputStream
import java.io.File
import java.net.URI
import java.util.zip.ZipEntry
import java.util.zip.ZipOutputStream
import javax.imageio.ImageIO
class FancyBot : OneBotListener {
private val logger = Logger.getLogger<FancyBot>()
private val coroutineScope = CoroutineScope(Dispatchers.IO)
override suspend fun onWebsocketOpenEvent() {
this.sendPrivateMessage(configManager.noticeUser, "FancyBot启动完成~")
override suspend fun onWebsocketOpenEvent(action: OneBotAction) {
action.sendPrivateMessage(configManager.noticeUser, "FancyBot启动完成~")
}
override suspend fun onGroupMessage(message: GroupMessage, json: String) {
@@ -53,72 +66,138 @@ class FancyBot : OneBotListener {
logger.info("$sender($senderId: $groupId >>> $messageId): $msg")
logger.trace("$sender($senderId: $groupId >>> $messageId: $json")
if (message.message.any { it.type == ArrayMessageType.face && it.data.id.toString() == "419" }) {
message.reply("你发牛魔的火车呢, 我直接就是打断")
}
// if (message.message.any { it.type == ArrayMessageType.face && it.data.id.toString() == "419" }) {
// message.reply("你发牛魔的火车呢, 我直接就是打断")
// }
if (message.rawMessage.contains("原神")) {
(0..10).forEach { _ ->
message.reaction(QQFace.entries.random())
}
message.reply("你原神牛魔呢")
}
// if (message.text.contains("原神")) {
// (0..10).forEach { _ -> message.reaction(QQFace.entries.random()) }
// message.reply("你原神牛魔呢")
// delay(1500L)
// message.reply("但是话又说回来.....启动!!")
// }
GitHubParseCommand.parse(message)
ReverseGIFCommand.callback(message)
AsciiArtCommand.callback(message)
ScanQRCodeCommand.callback(message)
BiliVideoParseCommand.parse(this, message)
BiliUserParseCommand.parse(this, message)
BiliVideoParseCommand.parse(message)
BiliUserParseCommand.parse(message)
DouyinVideoParseCommand.parse(message)
YoutubeVideoParseCommand.parse(message)
if (message.rawMessage.toList().any { it in arrayListOf('*', '-', '/', '+', '=') }) {
if (message.text.toList().any { it in arrayListOf('*', '-', '/', '+', '=') }) {
val calculateResult = CalculateCommand.parse(message.rawMessage)
calculateResult?.let { message.reply(calculateResult) }
}
if (message.message.any { it.type == ArrayMessageType.at }) {
if (message.text.contains("/取头像")) {
val target = message.message.find { it.type == ArrayMessageType.at }?.data?.qq!!
val avatar = JueCommand.AVATAR_REPLACE_URL.replace("#{}", target)
val msg = MessageChain.Builder()
if (message.text.contains("黑白")) {
val greyscale = avatar.toURL()
.readBytes().toBufferedImage()
.toGrayscale().toByteArray()
val greyscaleShortLink = ImageBed.upload(greyscale).makeShortLink()
msg.addImage(greyscale.encodeToBase64(), true)
.addText(greyscaleShortLink)
} else {
val shortLink = avatar.makeShortLink()
msg.addImage(avatar).addText(shortLink)
}
message.reply(msg.build())
}
}
if (message.message.any { it.type == ArrayMessageType.reply }) {
val command = message.message.reversed().find { it.type == ArrayMessageType.text }!!.data.text!!
val command = message.text.trim()
val replyId = message.message.find { it.type == ArrayMessageType.reply }!!.data.id!!
val getMsg = this.getMessage(replyId.toString().toLong())
val plainTextContent = getMsg.message
.filter { it.type == ArrayMessageType.text }
.joinToString { it.data.text!! }
if (command.contains("倒放") || command.contains("/df")) {
// 使用回复消息的方式对一个gif倒放
ReverseGIFCommand.reverse(message, getMsg)
}
if (command.contains("/sl") || command.contains("/short")) {
// 使用回复消息的方式快速对一个url消息创建一个短链接
message.reply(plainTextContent.trim().makeShortLink())
}
if (command.contains("/pb") || command.contains("/pastebin")) {
// 使用回复消息的方式快速将创建一个pastebin
val pastebinUrl = PastebinCommand.createPastebin(plainTextContent)
message.reply(pastebinUrl)
}
if (command.contains("/ascii") || command.contains("/asc")) {
// 使用回复消息的方式直接对一个图片进行生成Ascii art的操作
val getMsg = message.action.getMessage(replyId.toString().toLong())
val plainTextContent = getMsg.text
when (command) {
"/倒放", "/df" -> ReverseGIFCommand.reverse(message, getMsg)
"/图来", "/图链" -> ImageURLCommand.callback(message, getMsg)
"/图床" -> ImageBedCommand.execute(getMsg, message)
"/reaction" -> ReactionCommand.reaction(message.action, message.groupId, getMsg.messageId)
"/sl", "/short" -> message.reply(plainTextContent.trim().makeShortLink())
"/rc", "/随机颜色" -> RandomRGBCommand.random(message, getMsg)
"/颜色反转", "/iv" -> InvertImageCommand.invert(message, getMsg)
"/ascii", "/asc" -> {
val url = AsciiArtCommand.getImageUrl(getMsg)
val image = AsciiArtCommand.generateAsciiArt(url)
message.reply(image)
}
if (command.contains("图来") || command.contains("图链")) {
// 获取一个或多个图片的链接, 并且生成一个或多个短链接
ImageURLCommand.callback(message, getMsg)
"/pb", "/pastebin" -> {
val pastebinUrl = PastebinCommand.createPastebin(plainTextContent)
message.reply(pastebinUrl)
}
if (command.contains("reaction")) {
// 使用reaction刷屏回应一条消息
ReactionCommand.reaction(this, message, getMsg.messageId)
"/加速" -> {
val multiply = command.split("加速").last().toFloat()
SpeedUpGIFCommand.speedUp(message, getMsg, multiply)
}
"/黑白", "/灰度" -> {
val msg = MessageChain.Builder()
getMsg.message.filter { it.type == ArrayMessageType.image || it.type == ArrayMessageType.mface }
.forEach {
val imgUrl = it.data.file!!
val decoder = GifDecoder()
val imageStream = withContext(Dispatchers.IO) { imgUrl.toURL().openStream() }
decoder.read(imageStream)
if (decoder.frameCount == 0) {
msg.addImage(
imageStream.readBytes().toBufferedImage().toByteArray().encodeToBase64(), true
)
} else {
val frames = (0 until decoder.frameCount).map { decoder.getFrame(it).toGrayscale() }
val base64 = decoder.makeGif(frames).encodeToBase64()
msg.addImage(base64, true)
}
}
message.reply(msg.build())
}
"/拆帧", "/cj" -> {
val gifStream = getMsg.images.first().file.toURL().openStream()
val decoder = GifDecoder()
decoder.read(gifStream)
val frames = (0 until decoder.frameCount).map { decoder.getFrame(it) }
val byteArrayOutputStream = ByteArrayOutputStream()
ZipOutputStream(byteArrayOutputStream).use { zipOut ->
for ((index, image) in frames.withIndex()) {
val imageOutputStream = ByteArrayOutputStream()
ImageIO.write(image, "png", imageOutputStream)
val entry = ZipEntry("frame_$index.png")
zipOut.putNextEntry(entry)
zipOut.write(imageOutputStream.toByteArray())
zipOut.closeEntry()
}
}
val zipBytes = byteArrayOutputStream.toByteArray()
logger.info("Split frame size: ${zipBytes.size / 1024 / 1024}MB")
val imgBedUrl = ImageBed.upload(zipBytes, "zip")
val shortLink = imgBedUrl.makeShortLink()
val msg = Text(imgBedUrl) + NewLine() + Text(shortLink)
message.reply(msg)
}
if (command.contains("图床")) {
// 将一个图片上传到图床
ImageBedCommand.execute(getMsg, message)
}
}
coroutineScope.launch {
// if (message.images.isNotEmpty()) {
// message.images.forEach {
// val payload = NaiLongDetectPayload(it.file).toJson()
// val result = Http.post<NaiLongDetectResponse>(configManager.naiLongApiUrl, payload)
// logger.info("奶龙识别结果: ${result.result}")
// if (result.result) {
// message.reply("本群禁止发奶龙!")
// }
// }
// }
message.message.forEach {
if (it.type == ArrayMessageType.image) {
val filename = it.data.file!!.split("=").last() + ".png"
@@ -139,14 +218,14 @@ class FancyBot : OneBotListener {
.addNewLine()
.addText("使用/revoke ${message.messageId} 来获取被撤回的消息")
.build()
this.sendGroupMessage(message.groupId, msg)
message.action.sendGroupMessage(message.groupId, msg)
}
override suspend fun onWebsocketErrorEvent(ex: Exception) {
ex.printStackTrace()
override suspend fun onWebsocketErrorEvent(event: ErrorEvent) {
event.exception.printStackTrace()
}
override suspend fun onAddFriendRequest(event: AddFriendRequest) {
override suspend fun onAddFriendRequest(event: AddFriendRequestEvent) {
event.approve()
}
@@ -154,32 +233,45 @@ class FancyBot : OneBotListener {
event.saveTo("$ROOT_PATH/caches/")
}
override suspend fun onLeaveEvent(groupId: Long, userId: Long, operator: Long, time: Long) {
override suspend fun onLeaveEvent(event: MemberLeaveEvent) {
val nickname = event.action.getGroupMemberInfo(event.groupId, event.userId).nickname
val msg = MessageChain.Builder()
.addText("有人坐飞船离开了本星系~")
.addText("有人坐飞船离开了本星系~(主动退出)")
.addNewLine()
.addText("QQ: $userId | 操作者: ${if (operator == 0L) "主动退出" else operator}")
.addText("QQ: $nickname(${event.userId})")
.addNewLine()
.addText("下次再见吧~~~")
.build()
this.sendGroupMessage(groupId, msg)
event.action.sendGroupMessage(event.groupId, msg)
}
override suspend fun onMemberKick(event: MemberKickEvent) {
val nickname = event.action.getGroupMemberInfo(event.groupId, event.userId).nickname
val msg = MessageChain.Builder()
.addText("有人坐飞船离开了本星系~(管理员踢出)")
.addNewLine()
.addText("QQ: $nickname(${event.userId})")
.addNewLine()
.addText("下次再见吧~~~")
.build()
event.action.sendGroupMessage(event.groupId, msg)
}
override suspend fun onGroupPoke(event: PokeEvent) {
if (event.targetId == configManager.selfId) {
val msg = MessageChain.Builder()
.addAt(event.userId)
.addText("${event.action.first()}牛魔呢")
.addText("${event.pokeAction.first()}牛魔呢")
.build()
this.sendGroupMessage(event.groupId!!, msg)
event.action.sendGroupMessage(event.groupId!!, msg)
}
}
override suspend fun onBeKicked(groupId: Long, operator: Long, time: Long) {
blackListManager.insertGroup(groupId, operator, time)
this.sendPrivateMessage(
override suspend fun onBeKicked(event: BeKickEvent) {
blackListManager.insertGroup(event.groupId, event.operator, event.time)
event.action.sendPrivateMessage(
configManager.noticeUser,
"被: ${groupId}踢出! 操作人: $operator 时间: ${time.convertToDate()} 已将其拉入黑名单!"
"被: ${event.groupId}踢出! 操作人: ${event.operator} 时间: ${event.time.convertToDate()} 已将其拉入黑名单!"
)
}
}
@@ -188,19 +280,15 @@ suspend fun main() {
val fancyBot = FancyBot()
val workType = configManager.wsType
val accessToken = configManager.accessToken
val rob = if (workType == WSType.Client) {
val address = configManager.wsAddress
ROneBotFactory.createClient(address, accessToken, fancyBot)
.also { it.addListeningGroups(*configManager.listeningGroups.toLongArray()) }
} else {
val port = configManager.wsPort
ROneBotFactory.createServer(port, accessToken, fancyBot)
.also { it.addListeningGroups(*configManager.listeningGroups.toLongArray()) }
val instance = when (workType) {
WSType.Client -> ROneBotFactory.createClient(configManager.wsAddress, accessToken, fancyBot)
WSType.Server -> ROneBotFactory.createServer(configManager.wsPort, accessToken, fancyBot)
}
instance.addListeningGroups(*configManager.listeningGroups.toLongArray())
initDatabase()
initFilesDir()
initCommand(rob)
initCommand()
initSetuIndex()
initItems()
initBackgroundTasks(rob)
initBackgroundTasks(instance)
}
@@ -9,15 +9,14 @@ package cn.rtast.fancybot.commands
import cn.rtast.fancybot.annotations.CommandDescription
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("关于")
class AboutCommand : BaseCommand() {
override val commandNames = listOf("/about", "/关于")
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
val msg = MessageChain.Builder()
.addText("Bot名称: FancyBot")
.addNewLine()
@@ -8,20 +8,18 @@
package cn.rtast.fancybot.commands
import cn.rtast.fancybot.annotations.CommandDescription
import cn.rtast.fancybot.configManager
import cn.rtast.fancybot.enums.CommandAction
import cn.rtast.fancybot.util.file.insertActionRecord
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("Echo")
class EchoCommand : BaseCommand() {
override val commandNames = listOf("/echo")
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
if (message.sender.isAdmin || message.sender.isOwner) {
listener.sendGroupMessage(message.groupId, args.joinToString(" "))
message.reply(args.joinToString(" "))
insertActionRecord(CommandAction.Echo, message.sender.userId)
} else {
message.reply("你不许用echo")
@@ -33,11 +31,11 @@ class EchoCommand : BaseCommand() {
class ShuffleEchoCommand : BaseCommand() {
override val commandNames = listOf("/secho", "/se")
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
if (message.sender.isAdmin || message.sender.isOwner) {
message.reply(message.rawMessage.toList().shuffled().joinToString(""))
insertActionRecord(CommandAction.Echo, message.sender.userId)
} else{
} else {
message.reply("你不许用echo")
}
}
@@ -11,10 +11,9 @@ import cn.rtast.fancybot.annotations.CommandDescription
import cn.rtast.fancybot.commands
import cn.rtast.fancybot.configManager
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.onebot.NodeMessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.NodeMessageChain
import cn.rtast.rob.util.ob.OneBotListener
import kotlin.reflect.full.findAnnotation
import kotlin.reflect.full.hasAnnotation
@@ -22,7 +21,7 @@ import kotlin.reflect.full.hasAnnotation
class HelpCommand : BaseCommand() {
override val commandNames = listOf("/help", "/帮助")
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
if (args.isEmpty()) {
val node = NodeMessageChain.Builder()
val msg = MessageChain.Builder()
@@ -34,6 +33,10 @@ class HelpCommand : BaseCommand() {
msg.addText("[$commandName] [$description] 命令: $commandNames").addNewLine()
}
msg.addText("共计${commands.size}条命令")
node.addMessageChain(
MessageChain.Builder().addText("你可以使用`/help <指令>`来获取这个指令的帮助信息").build(),
configManager.selfId
)
node.addMessageChain(msg.build(), configManager.selfId)
message.reply(node.build())
} else {
@@ -12,16 +12,15 @@ import cn.rtast.fancybot.annotations.CommandDescription
import cn.rtast.fancybot.enums.CommandAction
import cn.rtast.fancybot.util.file.insertActionRecord
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
import java.time.Instant
@CommandDescription("状态")
class StatusCommand : BaseCommand() {
override val commandNames = listOf("/status")
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
val runtime = Runtime.getRuntime()
val maxMemory = runtime.maxMemory() / (1024 * 1024)
val allocatedMemory = runtime.totalMemory() / (1024 * 1024)
@@ -11,21 +11,15 @@ import cn.rtast.fancybot.ASSETS_BASE_URL
import cn.rtast.fancybot.annotations.CommandDescription
import cn.rtast.fancybot.util.str.encodeToBase64
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
import java.net.URI
@CommandDescription("给我打钱!")
class SupportMeCommand : BaseCommand() {
override val commandNames = listOf("打钱", "给我打钱", "给满子打钱")
override suspend fun executeGroup(
listener: OneBotListener,
message: GroupMessage,
args: List<String>,
matchedCommand: String
) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>, matchedCommand: String) {
if (matchedCommand == "给满子打钱") {
message.reply("你打牛魔呢?")
return
@@ -18,10 +18,9 @@ import cn.rtast.fancybot.util.Http
import cn.rtast.fancybot.util.file.insertActionRecord
import cn.rtast.fancybot.util.str.toJson
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.onebot.NodeMessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.NodeMessageChain
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("问AI(GPT)")
class AICommand : BaseCommand() {
@@ -29,7 +28,7 @@ class AICommand : BaseCommand() {
private val openAIModel = configManager.openAIModel
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
if (args.isEmpty()) {
val msg = MessageChain.Builder()
.addText("发送`/ai [模型] <问题>`即可询问AI哦~")
@@ -69,7 +68,7 @@ class AICommand : BaseCommand() {
.addText(response.choices.first().message.content)
.build()
nodeMsg.addMessageChain(msg, configManager.selfId)
listener.sendGroupForwardMsg(message.groupId, nodeMsg.build())
message.action.sendGroupForwardMsg(message.groupId, nodeMsg.build())
insertActionRecord(CommandAction.AI, message.sender.userId, "$content-$model-GPT")
}
}
@@ -81,7 +80,7 @@ class LlamaCommand : BaseCommand() {
private val llamaURL = configManager.llamaUrl
private val llamaModel = configManager.llamaModel
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
if (args.isEmpty()) {
message.reply("发送`/llama <问题>`即可使用llama模型来回复")
return
@@ -96,7 +95,7 @@ class LlamaCommand : BaseCommand() {
.addText(response.message.content)
.build()
nodeMsg.addMessageChain(msg, configManager.selfId)
listener.sendGroupForwardMsg(message.groupId, nodeMsg.build())
message.action.sendGroupForwardMsg(message.groupId, nodeMsg.build())
insertActionRecord(CommandAction.AI, message.sender.userId, "$prompt-LLAMA")
}
}
@@ -13,10 +13,9 @@ import cn.rtast.fancybot.entity.bgm.BGMSearch
import cn.rtast.fancybot.util.Http
import cn.rtast.fancybot.util.str.encodeToBase64
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.onebot.NodeMessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.NodeMessageChain
import cn.rtast.rob.util.ob.OneBotListener
import okhttp3.OkHttpClient
import okhttp3.Request
@@ -37,7 +36,7 @@ class AnimeSearchCommand : BaseCommand() {
}
}
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
if (args.isEmpty()) {
message.reply("发送`/dm <关键词>`即可搜索番剧啦~")
return
@@ -58,7 +57,7 @@ class AnimeSearchCommand : BaseCommand() {
}
val footerNode = MessageChain.Builder().addText("数据来源: Bangumi").build()
nodeMsg.addMessageChain(footerNode, configManager.selfId)
listener.sendGroupForwardMsg(message.groupId, nodeMsg.build())
message.action.sendGroupForwardMsg(message.groupId, nodeMsg.build())
} catch (_: Exception) {
message.reply("没有搜索到结果呢~")
}
@@ -13,10 +13,9 @@ import cn.rtast.fancybot.entity.cigarette.Cigarette
import cn.rtast.fancybot.util.Http
import cn.rtast.fancybot.util.str.encodeToBase64
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.onebot.NodeMessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.NodeMessageChain
import cn.rtast.rob.util.ob.OneBotListener
import java.net.URI
@CommandDescription("查询香烟价格")
@@ -25,7 +24,7 @@ class CigaretteCommand : BaseCommand() {
private val apiUrl = "https://www.yanyue.cn/api/rc/product/yanlist"
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
if (args.isEmpty()) {
val msg = MessageChain.Builder()
.addText("发送/tobacco <名称> [数量] 来搜索结果哦~")
@@ -15,9 +15,8 @@ import cn.rtast.fancybot.util.misc.toByteArray
import cn.rtast.fancybot.util.str.encodeToBase64
import cn.rtast.fancybot.util.str.toJson
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
import java.awt.Color
import java.awt.Font
import java.awt.image.BufferedImage
@@ -61,7 +60,7 @@ class DomainPriceCommand : BaseCommand() {
domain: String,
available: Boolean,
premium: Boolean,
domainPrice: Pair<Int, Int>
domainPrice: Pair<Int, Int>,
): String {
val canvas = this.createCommonCanvas()
val g2d = canvas.createGraphics()
@@ -77,7 +76,7 @@ class DomainPriceCommand : BaseCommand() {
}
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
if (args.isEmpty()) {
val msg = MessageChain.Builder()
.addText("发送`/domain <域名>`即可查询对应的注册和续费价格~")
@@ -14,9 +14,8 @@ import cn.rtast.fancybot.entity.github.LatestCommit
import cn.rtast.fancybot.util.Http
import cn.rtast.fancybot.util.str.fromArrayJson
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("查询Github上的仓库的最新一次的提交信息")
class GithubLatestCommitCommand : BaseCommand() {
@@ -24,7 +23,7 @@ class GithubLatestCommitCommand : BaseCommand() {
private val userInfoUrl = "https://api.github.com/repos"
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
if (args.isEmpty()) {
message.reply("发送`.commit <用户名/仓库名>`即可查询仓库最新一次的提交信息")
}
@@ -17,9 +17,8 @@ import cn.rtast.fancybot.util.misc.toBufferedImage
import cn.rtast.fancybot.util.misc.toByteArray
import cn.rtast.fancybot.util.str.encodeToBase64
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
import java.awt.Color
import java.awt.Font
import java.awt.image.BufferedImage
@@ -67,7 +66,7 @@ class GithubUserCommand : BaseCommand() {
return canvas.toByteArray().encodeToBase64()
}
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
if (args.isEmpty()) {
val msg = MessageChain.Builder().addText("发送`gh <用户名>`即可查询用户的信息~").build()
message.reply(msg)
@@ -12,9 +12,8 @@ import cn.rtast.fancybot.util.misc.toURL
import cn.rtast.fancybot.util.str.encodeToBase64
import cn.rtast.fancybot.util.str.getMD5
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("查询用户的Gravatar头像")
class GravatarCommand : BaseCommand() {
@@ -24,7 +23,7 @@ class GravatarCommand : BaseCommand() {
private const val GRAVATAR_URL = "https://gravatar.rtast.cn/avatar"
}
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
val emailMD5 = if (args.first().trim().lowercase().contains("@")) args.first().trim().lowercase().getMD5()
else args.first().trim().lowercase()
val avatarImage = "$GRAVATAR_URL/$emailMD5?size=256".toURL().readBytes().encodeToBase64()
@@ -12,9 +12,8 @@ import cn.rtast.fancybot.configManager
import cn.rtast.fancybot.entity.apispace.IdiomExplainResponse
import cn.rtast.fancybot.util.Http
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("解释一个成语")
class IdiomExplainCommand : BaseCommand() {
@@ -22,7 +21,7 @@ class IdiomExplainCommand : BaseCommand() {
private val apiSpaceUrl = "https://eolink.o.apispace.com/cyudac/api/v1/idioms/SearchIdiomsByPinyin/search"
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
if (args.isEmpty()) {
message.reply("发送`成语解释 <成语>`就能解释这个成语的意思了")
return
@@ -16,9 +16,8 @@ import cn.rtast.fancybot.entity.music.qq.QQMSearch
import cn.rtast.fancybot.util.Http
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.enums.MusicShareType
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
import java.time.Instant
@CommandDescription("网易云音乐点歌")
@@ -38,7 +37,7 @@ class MusicCommand : BaseCommand() {
}
}
private suspend fun legacyMusicCommand(listener: OneBotListener, message: GroupMessage, args: List<String>) {
private suspend fun legacyMusicCommand(message: GroupMessage, args: List<String>) {
if (args.isEmpty()) {
message.reply("发送`/点歌` <关键词> 来搜索音乐~")
return
@@ -63,7 +62,7 @@ class MusicCommand : BaseCommand() {
val msg = MessageChain.Builder()
.addMusicShare(MusicShareType.Netease, finalResult.id.toString())
.build()
listener.sendGroupMessage(message.groupId, msg)
message.reply(msg)
} catch (_: Exception) {
message.reply("输入有误请重新搜索本次搜索结果已清除")
}
@@ -93,9 +92,9 @@ class MusicCommand : BaseCommand() {
}
}
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
if (args.last() == "legacy" || args.last() == "l" || args.last() in "0".."4") {
this.legacyMusicCommand(listener, message, args)
this.legacyMusicCommand(message, args)
return
}
if (args.isEmpty()) {
@@ -105,7 +104,7 @@ class MusicCommand : BaseCommand() {
.addNewLine()
.addText("发送`点歌 <歌名> [l|legacy]`即可使用旧版点歌系统")
.build()
listener.sendGroupMessage(message.groupId, msg)
message.reply(msg)
return
}
@@ -114,7 +113,7 @@ class MusicCommand : BaseCommand() {
val msg = MessageChain.Builder()
.addMusicShare(MusicShareType.Netease, result.toString())
.build()
listener.sendGroupMessage(message.groupId, msg)
message.action.sendGroupMessage(message.groupId, msg)
}
}
@@ -128,7 +127,7 @@ class MusicPlayUrlCommand : BaseCommand() {
return Http.get<SongUrl>("$musicApiUrl/song/url", mapOf("id" to id)).data.first().url
}
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
val url = if (args.last() == "id" || args.last() == "i") {
val id = args.first()
this.getPlayUrl(id)
@@ -141,7 +140,7 @@ class MusicPlayUrlCommand : BaseCommand() {
.addReply(message.messageId)
.addText(url)
.build()
listener.sendGroupMessage(message.groupId, msg)
message.reply(msg)
}
}
@@ -151,7 +150,7 @@ class QQMusicCommand : BaseCommand() {
private val qqMusicApiUrl = configManager.qqMusicApiUrl
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
if (args.isEmpty()) {
message.reply("发送`/qm <关键词>`即可搜索qq音乐的音乐哦")
return
@@ -162,6 +161,6 @@ class QQMusicCommand : BaseCommand() {
mapOf("key" to keyword)
).response.data.song.list.first().songId
val msg = MessageChain.Builder().addMusicShare(MusicShareType.QQ, response.toString()).build()
listener.sendGroupMessage(message.groupId, msg)
message.action.sendGroupMessage(message.groupId, msg)
}
}
@@ -1,103 +0,0 @@
/*
* Copyright © 2024 RTAkland
* Author: RTAkland
* Date: 2024/9/6
*/
package cn.rtast.fancybot.commands.lookup
import cn.rtast.fancybot.annotations.CommandDescription
import cn.rtast.fancybot.configManager
import cn.rtast.fancybot.entity.IPGeo
import cn.rtast.fancybot.util.Http
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
import cn.rtast.rob.util.ob.asNode
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.net.InetAddress
import java.net.UnknownHostException
import java.util.Hashtable
import javax.naming.directory.InitialDirContext
@CommandDescription("解析域名获取IP地址")
class NslookupCommand : BaseCommand() {
override val commandNames = listOf("/ns")
companion object {
private const val MC_SRV_PREFIX = "_minecraft._tcp"
private const val IP_INFO_API = "https://ipinfo.io/###/json"
private val env = Hashtable<String, String>().also {
it["java.naming.factory.initial"] = "com.sun.jndi.dns.DnsContextFactory"
}
private val dirContext = InitialDirContext(env)
fun srv(host: String): MutableList<String> {
val srvDomain = "$MC_SRV_PREFIX.$host"
val attrs = dirContext.getAttributes(srvDomain, arrayOf("SRV"))
val srvRecords = mutableListOf<String>()
val srvAttr = attrs.get("SRV")
if (srvAttr != null) {
for (i in 0 until srvAttr.size()) {
val srvRecord = srvAttr.get(i) as String
srvRecords.add(srvRecord)
}
}
return srvRecords
}
}
private fun geo(ip: String) = Http.get<IPGeo>(IP_INFO_API.replace("###", ip))
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
val host = args.first()
val nsType = if (args.size == 3) args[1] else "common"
val srvType = if (args.size == 3) args.last() else "mc"
try {
if (nsType == "srv") {
when (srvType) {
"mc" -> {
val srvRecords = srv(host)
val messages = mutableListOf<MessageChain>()
srvRecords.forEach {
val srv = it.split(" ")
val priority = srv.first().toInt()
val weight = srv[1].toInt()
val port = srv[2].toInt()
val host = srv.last()
val ip = InetAddress.getByName(host).hostAddress
val geo = this.geo(ip)
val msg = MessageChain.Builder()
.addText("解析后的地址: $host:$port")
.addNewLine()
.addText("权重: $weight | 优先级: $priority")
.addNewLine()
.addText("$host -> $ip")
.addNewLine()
.addText("国家: ${geo.country} 地区: ${geo.region} 城市: ${geo.city} | 所属组织: ${geo.org}")
.build()
messages.add(msg)
}
message.reply(messages.asNode(configManager.selfId))
}
}
} else {
val ip = withContext(Dispatchers.IO) { InetAddress.getByName(host) }.hostAddress
val geo = this.geo(ip)
val msg = MessageChain.Builder()
.addText("$host -> $ip")
.addNewLine()
.addText("国家: ${geo.country} 地区: ${geo.region} 城市: ${geo.city} | 所属组织: ${geo.org}")
.build()
message.reply(msg)
}
} catch (_: UnknownHostException) {
message.reply("未知的主机名: $host")
} catch (e: Exception) {
message.reply("未知错误: ${e.message}")
}
}
}
@@ -0,0 +1,87 @@
/*
* Copyright © 2025 RTAkland
* Author: RTAkland
* Date: 2025/2/4
*/
package cn.rtast.fancybot.commands.lookup
import cn.rtast.fancybot.annotations.CommandDescription
import cn.rtast.fancybot.configManager
import cn.rtast.fancybot.entity.osu.OSUAccessToken
import cn.rtast.fancybot.entity.osu.OSUUserData
import cn.rtast.fancybot.util.Http
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand
import java.awt.Color
import java.awt.RenderingHints
import java.awt.image.BufferedImage
@CommandDescription("osu!")
class OSUCommand : BaseCommand() {
override val commandNames = listOf("/osu")
private val clientSecret = configManager.osuClientSecret
private val clientId = configManager.osuClientId
private fun getAccessToken(): String {
return Http.post<OSUAccessToken>(
"https://osu.ppy.sh/oauth/token",
formBody = mapOf(
"client_id" to clientId, "client_secret" to clientSecret,
"grant_type" to "client_credentials", "scope" to "public"
),
headers = mapOf("Content-Type" to "application/x-www-form-urlencoded", "Accept" to "application/json")
).accessToken
}
private fun getUser(username: String): OSUUserData {
val token = this.getAccessToken()
val resp = Http.get<OSUUserData>(
"https://osu.ppy.sh/api/v2/users/$username/osu",
headers = mapOf("Authorization" to "Bearer $token"),
)
return resp
}
private fun generateProgressBar(percent: Int, length: Int = 10): String {
val completedLength = (percent * length) / 100
val remainingLength = length - completedLength
val progressBar = "".repeat(completedLength) + "=".repeat(remainingLength)
return "[$progressBar] $percent%"
}
private fun formatDuration(seconds: Long): String {
val days = seconds / (24 * 3600)
val hours = (seconds % (24 * 3600)) / 3600
val minutes = (seconds % 3600) / 60
val parts = mutableListOf<String>()
if (days > 0) parts.add("${days}d")
if (hours > 0) parts.add("${hours}h")
if (minutes > 0) parts.add("${minutes}m")
return parts.joinToString(" ")
}
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
val username = args.first()
val userData = getUser(username)
val msg = MessageChain.Builder()
.addText(userData.username)
.addNewLine()
.addText("等级 | Lv.${userData.statistics.level.current} ${generateProgressBar(userData.statistics.level.progress)}")
.addNewLine()
.addText("排名 | #${userData.statistics.globalRank} / ${userData.countryCode} #${userData.statistics.countryRank}")
.addNewLine()
.addText("准确率 | ${userData.statistics.hitAccuracy}%")
.addNewLine()
.addText("游玩时间 | ${formatDuration(userData.statistics.playTime)}")
.addNewLine()
.addText("游玩次数 | ${userData.statistics.playCount}")
.addNewLine()
.addText("表现分/PP | ${userData.statistics.pp.toInt()}")
.build()
message.reply(msg)
}
}
@@ -13,10 +13,9 @@ import cn.rtast.fancybot.entity.pixiv.Ranking
import cn.rtast.fancybot.util.Http
import cn.rtast.fancybot.util.str.encodeToBase64
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.onebot.NodeMessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.NodeMessageChain
import cn.rtast.rob.util.ob.OneBotListener
import java.net.URI
@CommandDescription("获取Pixiv上的图片")
@@ -26,7 +25,7 @@ class PixivCommand : BaseCommand() {
private val pixivRankingURL = "https://proxy.rtast.cn/https/www.pixiv.net/ranking.php?format=json&mode=daily&p=1"
private val imageProxyURL = "https://pixiv.re"
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
if (args.isEmpty()) {
val msg = MessageChain.Builder()
.addText("发送`/pixiv <id> | rank` 来进行操作哦~")
@@ -10,10 +10,9 @@ package cn.rtast.fancybot.commands.lookup
import cn.rtast.fancybot.annotations.CommandDescription
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.enums.ArrayMessageType
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.onebot.NodeMessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.NodeMessageChain
import cn.rtast.rob.util.ob.OneBotListener
private fun generateNodeMessage(targetId: String, times: Int = 10): NodeMessageChain {
@@ -29,8 +28,8 @@ private fun generateNodeMessage(targetId: String, times: Int = 10): NodeMessageC
class ShotSelfCommand : BaseCommand() {
override val commandNames = listOf("骂我")
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
listener.sendGroupForwardMsg(message.groupId, generateNodeMessage(message.sender.userId.toString()))
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
message.action.sendGroupForwardMsg(message.groupId, generateNodeMessage(message.sender.userId.toString()))
}
}
@@ -38,14 +37,16 @@ class ShotSelfCommand : BaseCommand() {
class ShotOtherCommand : BaseCommand() {
override val commandNames = listOf("")
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
if (args.isEmpty()) {
listener.sendGroupForwardMsg(message.groupId, generateNodeMessage(message.sender.userId.toString(), 20))
message.action.sendGroupForwardMsg(
message.groupId, generateNodeMessage(message.sender.userId.toString(), 20)
)
return
}
var times = if (args.size == 1) 10 else if (args.last() == "") 10 else args.last().toInt()
if (times >= 200) times = 10
val target = message.message.find { it.type == ArrayMessageType.at }?.data!!
listener.sendGroupForwardMsg(message.groupId, generateNodeMessage(target.qq!!, times))
message.action.sendGroupForwardMsg(message.groupId, generateNodeMessage(target.qq!!, times))
}
}
@@ -15,9 +15,8 @@ import cn.rtast.fancybot.util.str.encodeToBase64
import cn.rtast.fancybot.util.str.fromArrayJson
import cn.rtast.fancybot.util.str.proxy
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("随机猫猫图")
class TheCatCommand : BaseCommand() {
@@ -25,7 +24,7 @@ class TheCatCommand : BaseCommand() {
private val theCatApiUrl = "https://api.thecatapi.com/v1/images/search"
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
val imageBase64 = Http.get(theCatApiUrl)
.fromArrayJson<List<Cat>>().first().url
.proxy.toURL().readBytes().encodeToBase64()
@@ -12,10 +12,9 @@ import cn.rtast.fancybot.configManager
import cn.rtast.fancybot.entity.tianxing.HistoryOfToday
import cn.rtast.fancybot.util.Http
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.onebot.toNode
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
import cn.rtast.rob.util.ob.asNode
import java.time.LocalDateTime
import java.time.ZoneId
import java.time.format.DateTimeFormatter
@@ -27,7 +26,7 @@ class TheHistoryOfTodayCommand : BaseCommand() {
private val tianXingApiUrl = "https://apis.tianapi.com/lishi/index"
private val tianXingApiKey = configManager.tianXingApiKey
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
val currentDateTime = LocalDateTime.now(ZoneId.of("Asia/Shanghai"))
val formatter = DateTimeFormatter.ofPattern("MMdd")
val currentDate = currentDateTime.format(formatter)
@@ -47,6 +46,6 @@ class TheHistoryOfTodayCommand : BaseCommand() {
.build()
)
}
message.reply(messages.asNode(configManager.selfId))
message.reply(messages.toNode(configManager.selfId))
}
}
@@ -19,9 +19,8 @@ import cn.rtast.fancybot.util.misc.toBufferedImage
import cn.rtast.fancybot.util.misc.toByteArray
import cn.rtast.fancybot.util.str.encodeToBase64
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
import java.awt.Color
import java.awt.Font
import java.awt.image.BufferedImage
@@ -58,13 +57,13 @@ class WeatherCommand : BaseCommand() {
return emptyImage.toByteArray().encodeToBase64()
}
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
if (args.isEmpty()) {
val msg = MessageChain.Builder()
.addAt(message.sender.userId)
.addText("发送/weather <地区名>即可查看实时天气哦~")
.build()
listener.sendGroupMessage(message.groupId, msg)
message.reply(msg)
return
}
try {
@@ -81,13 +80,13 @@ class WeatherCommand : BaseCommand() {
.addReply(message.messageId)
.addImage(this.createWeatherCard(weather, lookupLocation), true)
.build()
listener.sendGroupMessage(message.groupId, msg)
message.reply(msg)
} catch (_: NullPointerException) {
val msg = MessageChain.Builder()
.addAt(message.sender.userId)
.addText("没有查询到该城市的天气信息哦~")
.build()
listener.sendGroupMessage(message.groupId, msg)
message.reply(msg)
}
}
}
@@ -14,9 +14,8 @@ import cn.rtast.fancybot.enums.CommandAction
import cn.rtast.fancybot.util.Http
import cn.rtast.fancybot.util.file.insertActionRecord
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
import org.jsoup.Jsoup
@CommandDescription("查询wiki百科")
@@ -32,7 +31,7 @@ class WikipediaCommand : BaseCommand() {
}
}
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
if (args.isEmpty()) {
val msg = MessageChain.Builder()
.addText("发送`/wiki <关键字>`即可查询出最匹配的wiki页面~")
@@ -14,21 +14,20 @@ import cn.rtast.rob.entity.ArrayMessage
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.enums.ArrayMessageType
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("防撤回(获取消息)")
class AntiRevokeCommand : BaseCommand() {
override val commandNames = listOf("/revoke", "/rv")
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
if (message.sender.isAdmin || message.sender.isOwner) {
val messageId = args.first().toLong()
val getMsg = listener.getMessage(messageId)
val getMsg = message.action.getMessage(messageId)
val msgList = mutableListOf<ArrayMessage>()
msgList.add(ArrayMessage(ArrayMessageType.at, ArrayMessage.Data(qq = message.sender.userId.toString())))
msgList.add(ArrayMessage(ArrayMessageType.text, ArrayMessage.Data(text = "\n被撤回的消息如下: \n")))
msgList.addAll(getMsg.message)
listener.sendGroupMessage(message.groupId, msgList)
message.action.sendGroupMessage(message.groupId, msgList)
insertActionRecord(CommandAction.AntiRevoke, message.sender.userId, getMsg.messageId.toString())
} else {
message.reply("你不许用防撤回")
@@ -13,10 +13,9 @@ import cn.rtast.fancybot.entity.bullshit.BullShit
import cn.rtast.fancybot.util.misc.Resources
import cn.rtast.fancybot.util.str.fromJson
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.onebot.NodeMessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.NodeMessageChain
import cn.rtast.rob.util.ob.OneBotListener
import kotlin.random.Random
@CommandDescription("狗屁不通文章生成器")
@@ -47,7 +46,7 @@ class BullShitGenerateCommand : BaseCommand() {
return ".\n\n "
}
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
val topic = args.joinToString(" ")
val nextFamousQuote = shuffleList(bullShitData.famous)
val nextBosh = shuffleList(bullShitData.bosh)
@@ -17,9 +17,8 @@ import cn.rtast.fancybot.util.Http
import cn.rtast.fancybot.util.file.insertActionRecord
import cn.rtast.fancybot.util.str.toJson
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("执行不同语言的代码")
class CompilerCommand : BaseCommand() {
@@ -28,7 +27,7 @@ class CompilerCommand : BaseCommand() {
private val kotlinCompilerServer = "https://api.kotlinlang.org/api/2.0.20/compiler/run"
private val glotCompilerServer = "https://glot.io/run"
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
if (args.isEmpty()) {
message.reply("使用`/exec` <语言> <代码> 即可执行~")
return
@@ -63,7 +62,7 @@ class CompilerCommand : BaseCommand() {
.addNewLine()
.addText(response.replace("<outStream>", "").replace("</outStream>", ""))
.build()
listener.sendGroupMessage(message.groupId, msg)
message.reply(msg)
} catch (e: Exception) {
message.reply("执行错误: ${e.message}")
} finally {
@@ -10,7 +10,6 @@ package cn.rtast.fancybot.commands.misc
import cn.rtast.fancybot.annotations.CommandDescription
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.OneBotListener
import java.time.LocalDate
import java.time.temporal.ChronoUnit
@@ -18,7 +17,7 @@ import java.time.temporal.ChronoUnit
class GaoKaoDaysRemainCommand : BaseCommand() {
override val commandNames = listOf("高考倒计时")
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
val gaoKaoDate = LocalDate.of(LocalDate.now().year, 6, 7)
val currentDate = LocalDate.now()
val adjustedGaoKaoDate = if (currentDate.isAfter(gaoKaoDate)) gaoKaoDate.plusYears(1) else gaoKaoDate
@@ -0,0 +1,45 @@
/*
* Copyright © 2025 RTAkland
* Author: RTAkland
* Date: 2025/2/20
*/
package cn.rtast.fancybot.commands.misc
import cn.rtast.fancybot.util.misc.Resources
import cn.rtast.fancybot.util.misc.drawCenteredText
import cn.rtast.fancybot.util.misc.toByteArray
import cn.rtast.fancybot.util.str.encodeToBase64
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.segment.Image
import cn.rtast.rob.util.BaseCommand
import java.awt.Color
import java.awt.Font
import java.awt.RenderingHints
import javax.imageio.ImageIO
class GoodNewsCommand: BaseCommand() {
override val commandNames = listOf("xb", "喜报")
private val goodNewsImageBytes = Resources.loadFromResourcesAsBytes("misc/good_news.png")
private val font = Font("SimSun", Font.BOLD, 130)
private fun generateImage(content: String): String {
val img = ImageIO.read(goodNewsImageBytes!!.inputStream())
val g2d = img.createGraphics()
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
g2d.color = Color.RED
g2d.font = font
g2d.drawCenteredText(content, 650, 500)
g2d.dispose()
val imgBase64 = img.toByteArray().encodeToBase64()
return imgBase64
}
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
val content = args.joinToString(" ")
val imgBase64 = generateImage(content)
message.reply(Image(imgBase64, true))
}
}
@@ -12,9 +12,8 @@ import cn.rtast.fancybot.enums.HttpStatusCode
import cn.rtast.fancybot.util.misc.Resources
import cn.rtast.fancybot.util.str.encodeToBase64
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("随机HTTP猫猫")
class HTTPCatCommand : BaseCommand() {
@@ -26,7 +25,7 @@ class HTTPCatCommand : BaseCommand() {
return Resources.loadFromResourcesAsBytes("httpcat/${code}.jpg")?.encodeToBase64() ?: notFoundCatBase64
}
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
val statusCode = if (args.isEmpty()) HttpStatusCode.entries.random().code.toString() else args.first()
val image = loadHTTPCat(statusCode)
val msg = MessageChain.Builder().addImage(image, true).build()
@@ -12,9 +12,8 @@ import cn.rtast.fancybot.enums.HttpStatusCode
import cn.rtast.fancybot.util.misc.Resources
import cn.rtast.fancybot.util.str.encodeToBase64
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("随机HTTP狗狗")
class HTTPDogCommand : BaseCommand() {
@@ -26,7 +25,7 @@ class HTTPDogCommand : BaseCommand() {
return Resources.loadFromResourcesAsBytes("httpdog/${code}.jpg")?.encodeToBase64() ?: notFoundCatBase64
}
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
val statusCode = if (args.isEmpty()) HttpStatusCode.entries.random().code.toString() else args.first()
val image = loadHTTPDog(statusCode)
val msg = MessageChain.Builder().addImage(image, true).build()
@@ -11,15 +11,14 @@ import cn.rtast.fancybot.annotations.CommandDescription
import cn.rtast.fancybot.entity.Hitokoto
import cn.rtast.fancybot.util.Http
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("一言")
class HitokotoCommand : BaseCommand() {
override val commandNames = listOf("/1")
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
val response = Http.get<Hitokoto>("https://v1.hitokoto.cn/?c=b")
val msg = MessageChain.Builder()
.addText("${response.sentence}⌉ ---《${response.from}")
@@ -10,9 +10,8 @@ package cn.rtast.fancybot.commands.misc
import cn.rtast.fancybot.annotations.CommandDescription
import cn.rtast.fancybot.util.file.JrrpManager
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("今日人品~")
class JrrpCommand : BaseCommand() {
@@ -20,13 +19,13 @@ class JrrpCommand : BaseCommand() {
private val jrrpManager = JrrpManager()
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
if (jrrpManager.isJrrped(message.sender.userId)) {
val msg = MessageChain.Builder()
.addAt(message.sender.userId)
.addText("你今天已经今日人品过啦, 明天再来吧~")
.build()
listener.sendGroupMessage(message.groupId, msg)
message.reply(msg)
return
}
val randomPoint = jrrpManager.jrrp(message.sender.userId)
@@ -41,6 +40,6 @@ class JrrpCommand : BaseCommand() {
.addAt(message.sender.userId)
.addText("$scoreDesc($randomPoint)")
.build()
listener.sendGroupMessage(message.groupId, msg)
message.reply(msg)
}
}
@@ -15,9 +15,8 @@ import cn.rtast.fancybot.util.misc.toBufferedImage
import cn.rtast.fancybot.util.str.encodeToBase64
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.enums.ArrayMessageType
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
import com.madgag.gif.fmsware.GifDecoder
import java.awt.image.BufferedImage
import java.net.URI
@@ -26,12 +25,14 @@ import java.net.URI
class JueCommand : BaseCommand() {
override val commandNames = listOf("")
private val avatarUrl = "https://q1.qlogo.cn/g?b=qq&nk=#{}&s=640"
companion object {
const val AVATAR_REPLACE_URL = "https://q1.qlogo.cn/g?b=qq&nk=#{}&s=640"
}
private fun createJueGIF(source: String, target: String): String {
val baseGIF = Resources.loadFromResources("misc/jue.gif")
val sourceAvatar = URI(avatarUrl.replace("#{}", source)).toURL().readBytes().toBufferedImage()
val targetAvatar = URI(avatarUrl.replace("#{}", target)).toURL().readBytes().toBufferedImage()
val sourceAvatar = URI(AVATAR_REPLACE_URL.replace("#{}", source)).toURL().readBytes().toBufferedImage()
val targetAvatar = URI(AVATAR_REPLACE_URL.replace("#{}", target)).toURL().readBytes().toBufferedImage()
val decoder = GifDecoder()
decoder.read(baseGIF)
val frames = mutableListOf<BufferedImage>()
@@ -57,11 +58,11 @@ class JueCommand : BaseCommand() {
return gif
}
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
val target = message.message.find { it.type == ArrayMessageType.at }?.data?.qq.toString()
val source = message.sender.userId.toString()
val gif = this.createJueGIF(source, target)
val msg = MessageChain.Builder().addImage(gif, true).build()
listener.sendGroupMessage(message.groupId, msg)
message.reply(msg)
}
}
@@ -12,7 +12,6 @@ import cn.rtast.fancybot.entity.KFC
import cn.rtast.fancybot.util.Http
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.OneBotListener
import java.time.DayOfWeek
import java.time.Instant
import java.time.LocalDateTime
@@ -32,7 +31,7 @@ class KFCCommand : BaseCommand() {
}
}
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
if (!isThursday()) {
message.reply("很可惜今天并不是星期四~")
return
@@ -0,0 +1,47 @@
/*
* Copyright © 2025 RTAkland
* Author: RTAkland
* Date: 2025/2/21
*/
package cn.rtast.fancybot.commands.misc
import cn.rtast.fancybot.annotations.CommandDescription
import cn.rtast.fancybot.util.misc.Resources
import cn.rtast.fancybot.util.misc.drawCenteredText
import cn.rtast.fancybot.util.misc.toByteArray
import cn.rtast.fancybot.util.str.encodeToBase64
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.segment.Image
import cn.rtast.rob.util.BaseCommand
import java.awt.Color
import java.awt.Font
import java.awt.RenderingHints
import javax.imageio.ImageIO
@CommandDescription("没惹任何人")
class MRRHRCommand : BaseCommand() {
override val commandNames = listOf("/mr")
private val mrrhrImageBytes = Resources.loadFromResourcesAsBytes("misc/mrrhr.png")
private val font = Font("SimSun", Font.BOLD, 60)
private fun generateImage(content: String): String {
val img = ImageIO.read(mrrhrImageBytes!!.inputStream())
val g2d = img.createGraphics()
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
g2d.color = Color.BLACK
g2d.font = font
g2d.drawCenteredText(content, 315, 466)
g2d.dispose()
val imgBase64 = img.toByteArray().encodeToBase64()
return imgBase64
}
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
val content = args.joinToString(" ")
val image = generateImage(content)
message.reply(Image(image, true))
}
}
@@ -48,16 +48,16 @@ import cn.rtast.motdpinger.JavaPing
import cn.rtast.rcon.exceptions.AuthFailedException
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.entity.PrivateMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.onebot.toNode
import cn.rtast.rob.segment.NewLine
import cn.rtast.rob.segment.Text
import cn.rtast.rob.segment.toMessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
import cn.rtast.rob.util.ob.asMessageChain
import cn.rtast.rob.util.ob.asNode
import okhttp3.FormBody
import java.awt.AlphaComposite
import java.awt.Color
import java.awt.image.BufferedImage
import java.net.InetAddress
import java.net.SocketException
import java.net.URI
import java.util.concurrent.Executors
@@ -71,7 +71,7 @@ class MCVersionCommand : BaseCommand() {
private val javaEditionAPI = "https://launchermeta.mojang.com/mc/game/version_manifest.json"
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
val mcVersion = Http.get<MCVersion>(javaEditionAPI)
val msg = MessageChain.Builder()
.addText("最新正式版: ${mcVersion.latest.release}")
@@ -93,13 +93,13 @@ class MinecraftWikiCommand : BaseCommand() {
private val baseApiUrl = "https://zh.minecraft.wiki/rest.php/v1"
private val logger = Logger.getLogger<MinecraftWikiCommand>()
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
val action = args.first()
when (action) {
"s", "搜索" -> {
val searchKeyword = args.drop(1).joinToString(" ").trim()
val messages = mutableListOf<MessageChain>()
val headerMessage = listOf("结果如下:").asMessageChain()
val headerMessage = MessageChain.Builder().addText("结果如下:").build()
messages.add(headerMessage)
Http.get<MCWikiSearchResponse>(
"$baseApiUrl/search/title",
@@ -118,7 +118,7 @@ class MinecraftWikiCommand : BaseCommand() {
.addText("https://zh.minecraft.wiki/w/${it.title.uriEncode}")
messages.add(msg.build())
}
message.reply(messages.asNode(configManager.selfId))
message.reply(messages.toNode(configManager.selfId))
}
else -> {
@@ -134,18 +134,19 @@ class MinecraftWikiCommand : BaseCommand() {
response = Http.get<MCWikiPageResponse>(response.redirectTarget)
}
val messages = mutableListOf<MessageChain>()
val headerMsg = listOf("标题${response.title}的内容如下").asMessageChain()
val headerMsg = MessageChain.Builder().addText("标题${response.title}的内容如下").build()
val footerMsg = listOf(
"数据来源: https://zh.minecraft.wiki",
"协议: ${response.license.title}(${response.license.url})"
).asMessageChain(true)
Text("数据来源: https://zh.minecraft.wiki"),
NewLine(),
Text("协议: ${response.license.title}(${response.license.url})")
).toMessageChain()
val bodyMsg = MessageChain.Builder()
.addText(response.source.convertToHTML().extractPlainTextFromHtml())
.build()
messages.add(headerMsg)
messages.add(bodyMsg)
messages.add(footerMsg)
message.reply(messages.asNode(configManager.selfId))
message.reply(messages.toNode(configManager.selfId))
}
}
}
@@ -179,7 +180,7 @@ class SlimeChunkHelperCommand : BaseCommand() {
private fun findMaxSlimeChunks(
worldSeed: Long,
searchRange: Int,
chunkSize: Int
chunkSize: Int,
): Pair<Pair<Pair<Int, Int>, Pair<Int, Int>>, Int> {
var maxCount = 0
var bestStartLocation = Pair(0, 0)
@@ -222,7 +223,7 @@ class SlimeChunkHelperCommand : BaseCommand() {
return image.toByteArray().encodeToBase64()
}
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
if (args.isEmpty()) {
val msg = MessageChain.Builder()
.addText("此指令可以借助一个种子来帮助查找最适合史莱姆农场的位置")
@@ -300,7 +301,7 @@ class MCSkinCommand : BaseCommand() {
return zoom.toByteArray().encodeToBase64()
}
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
if (args.isEmpty()) {
message.reply("发送`/skin <uuid/游戏名称>`即可查询他的皮肤~ (仅限Java版)")
return
@@ -333,7 +334,7 @@ class MCPingCommand : BaseCommand() {
return this.replace(Regex("§."), "")
}
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
if (args.isEmpty()) {
val msg = MessageChain.Builder()
.addText("使用方法: /mcping <host>:[port] [java|be]")
@@ -460,7 +461,7 @@ class MCLoginCommand : BaseCommand() {
return response.token
}
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
if (args.isEmpty()) {
message.reply("这个命令可以获取你的MC登录Token发送 `/mclogin login`进行操作吧")
return
@@ -501,7 +502,7 @@ class MCLoginCommand : BaseCommand() {
}
}
override suspend fun executePrivate(listener: OneBotListener, message: PrivateMessage, args: List<String>) {
override suspend fun executePrivate(message: PrivateMessage, args: List<String>) {
val token = getAccessTokenById(message.sender.userId)
if (token == null) {
message.reply("你还没登录呢!")
@@ -523,11 +524,11 @@ class MCLoginCommand : BaseCommand() {
class RCONCommand : BaseCommand() {
override val commandNames = listOf("/rcon", "/r")
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
message.reply("请在私聊中使用此命令")
}
override suspend fun executePrivate(listener: OneBotListener, message: PrivateMessage, args: List<String>) {
override suspend fun executePrivate(message: PrivateMessage, args: List<String>) {
if (args.isEmpty()) {
val msg = MessageChain.Builder()
.addText("这条指令用于在群内操作mc服务器")
@@ -550,7 +551,7 @@ class RCONCommand : BaseCommand() {
return
}
val messages = mutableListOf<MessageChain>()
.also { it.add(listOf("所有配置如下").asMessageChain()) }
.also { it.add(MessageChain.Builder().addText("所有配置如下").build()) }
allRcons.forEach {
val msg = MessageChain.Builder()
.addText("名称: ${it.name}")
@@ -561,7 +562,7 @@ class RCONCommand : BaseCommand() {
.build()
messages.add(msg)
}
message.reply(messages.asNode(configManager.selfId))
message.reply(messages.toNode(configManager.selfId))
}
"add" -> {
@@ -593,9 +594,9 @@ class RCONCommand : BaseCommand() {
try {
val result = rconManager.executeCommand(message.sender.userId, name, command)
val messages = mutableListOf<MessageChain>()
.also { it.add(listOf("执行结果如下").asMessageChain()) }
.also { it.add(listOf(result).asMessageChain()) }
.asNode(configManager.selfId)
.also { it.add(MessageChain.Builder().addText("执行结果如下").build()) }
.also { it.add(MessageChain.Builder().addText(result).build()) }
.toNode(configManager.selfId)
message.reply(messages)
} catch (_: AuthFailedException) {
message.reply("执行失败, 密码不正确")
@@ -617,7 +618,7 @@ class MCBotCommand : BaseCommand() {
return response.players.max to response.players.online
}
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
val clients = mutableListOf<MCClient>()
val action = args.first()
when (action) {
@@ -0,0 +1,126 @@
/*
* Copyright © 2025 RTAkland
* Author: RTAkland
* Date: 2025/1/15
*/
package cn.rtast.fancybot.commands.misc
import cn.rtast.fancybot.annotations.CommandDescription
import cn.rtast.fancybot.util.misc.Resources
import cn.rtast.fancybot.util.misc.drawCenteredText
import cn.rtast.fancybot.util.misc.toByteArray
import cn.rtast.fancybot.util.str.encodeToBase64
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.segment.Image
import cn.rtast.rob.util.BaseCommand
import java.awt.Color
import java.awt.Font
import java.awt.RenderingHints
import javax.imageio.ImageIO
@CommandDescription("那我问你")
class NWWNCommand : BaseCommand() {
override val commandNames = listOf("nwwn", "那我问你")
private val originNWWNImage = Resources.loadFromResourcesAsBytes("misc/nwwn.png")
private val font = Font("SimSun", Font.BOLD, 55)
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
try {
val keyword = args.joinToString(" ")
val img = ImageIO.read(originNWWNImage!!.inputStream())
val g2d = img.createGraphics()
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
g2d.color = Color.BLACK
g2d.font = font
g2d.drawString(keyword, 290, 70)
g2d.dispose()
val imgBase64 = img.toByteArray().encodeToBase64()
val msg = Image(imgBase64, true)
message.reply(msg)
} catch (e: Exception) {
message.reply("生成失败: ${e.message}")
}
}
}
@CommandDescription("太几把搞笑了")
class TJBGXLCommand: BaseCommand() {
override val commandNames = listOf("太几把搞笑了", "tjbgxl", "jb")
private val originImage = Resources.loadFromResourcesAsBytes("misc/tjbgxl.png")
private val font = Font("SimSun", Font.BOLD, 45)
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
try {
val keyword = args.joinToString(" ")
val img = ImageIO.read(originImage!!.inputStream())
val g2d = img.createGraphics()
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
g2d.color = Color.BLACK
g2d.font = font
g2d.drawCenteredText(keyword, 380, 620)
g2d.dispose()
val imgBase64 = img.toByteArray().encodeToBase64()
val msg = Image(imgBase64, true)
message.reply(msg)
} catch (e: Exception) {
message.reply("生成失败: ${e.message}")
}
}
}
@CommandDescription("香奈美语句生成")
class XNMCommand: BaseCommand() {
override val commandNames = listOf("xnm", "香奈美")
private val font = Font("SimSun", Font.BOLD, 55)
private val originImage = Resources.loadFromResourcesAsBytes("misc/xnm.png")
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
try {
val keyword = args.first()
val keyword2 = args.last()
val img = ImageIO.read(originImage!!.inputStream())
val g2d = img.createGraphics()
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
g2d.color = Color.BLACK
g2d.font = font
g2d.drawCenteredText(keyword, 510, 55)
g2d.drawCenteredText(keyword2, 510, 140)
g2d.dispose()
val imgBase64 = img.toByteArray().encodeToBase64()
val msg = Image(imgBase64, true)
message.reply(msg)
} catch (e: Exception) {
message.reply("生成失败: ${e.message}")
}
}
}
@CommandDescription("设静")
class SJCommand: BaseCommand() {
override val commandNames = listOf("sj")
private val font = Font("SimSun", Font.BOLD, 20)
private val originImage = Resources.loadFromResourcesAsBytes("misc/sj.png")
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
try {
val keyword = args.joinToString(" ")
val img = ImageIO.read(originImage!!.inputStream())
val g2d = img.createGraphics()
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
g2d.color = Color.BLACK
g2d.font = font
g2d.drawCenteredText(keyword, 126, 210)
g2d.dispose()
val imgBase64 = img.toByteArray().encodeToBase64()
val msg = Image(imgBase64, true)
message.reply(msg)
} catch (e: Exception) {
message.reply("生成失败: ${e.message}")
}
}
}
@@ -19,7 +19,6 @@ import cn.rtast.fancybot.util.file.insertActionRecord
import cn.rtast.fancybot.util.str.toJson
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("Pastebin!")
class PastebinCommand : BaseCommand() {
@@ -32,11 +31,11 @@ class PastebinCommand : BaseCommand() {
"$API_RTAST_URL/api/pastebin", pastebinPayload.toJson(),
params = mapOf("key" to configManager.apiRtastKey)
)
return "$PBI_API_URL/-/${response.id}"
return "https://api.rtast.cn/-/${response.id}"
}
}
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
if (args.isEmpty()) {
message.reply("使用`/pb <内容>`或者回复一个消息`/pb`可以快速创建一个pastebin")
return
@@ -15,9 +15,8 @@ import cn.rtast.fancybot.util.misc.toByteArray
import cn.rtast.fancybot.util.str.encodeToBase64
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.enums.ArrayMessageType
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
import com.google.zxing.BarcodeFormat
import com.google.zxing.BinaryBitmap
import com.google.zxing.EncodeHintType
@@ -40,7 +39,7 @@ class GenerateQRCodeCommand : BaseCommand() {
return MatrixToImageWriter.toBufferedImage(bitMatrix).toByteArray().encodeToBase64()
}
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
if (args.isEmpty()) {
message.reply("发送`/qr <内容>`即可生成一张二维码的图片")
return
@@ -85,7 +84,7 @@ class ScanQRCodeCommand : BaseCommand() {
}
}
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
if (message.sender() !in waitingList) {
waitingList.add(message.sender())
message.reply("继续发送一张二维码图片")
@@ -10,22 +10,21 @@ package cn.rtast.fancybot.commands.misc
import cn.rtast.fancybot.annotations.CommandDescription
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.enums.ArrayMessageType
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("RUA!")
class RUACommand : BaseCommand() {
override val commandNames = listOf("/rua", "rua")
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
if (args.isEmpty()) {
val msg = MessageChain.Builder()
.addAt(message.sender.userId)
.addText("使用rua @xxxx")
.addText("即可rua某人啦~")
.build()
listener.sendGroupMessage(message.groupId, msg)
message.reply(msg)
return
}
try {
@@ -38,13 +37,13 @@ class RUACommand : BaseCommand() {
.addText(" ")
.addText("rua了你~")
.build()
listener.sendGroupMessage(message.groupId, msg)
message.reply(msg)
} catch (_: NullPointerException) {
val msg = MessageChain.Builder()
.addAt(message.sender.userId)
.addText("要@才有用哦~")
.build()
listener.sendGroupMessage(message.groupId, msg)
message.reply(msg)
}
}
}
@@ -13,9 +13,8 @@ import cn.rtast.fancybot.entity.music.TopSong
import cn.rtast.fancybot.util.Http
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.enums.MusicShareType
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("获取随机热榜音乐(网易云)")
class RandomMusicCommand : BaseCommand() {
@@ -23,11 +22,11 @@ class RandomMusicCommand : BaseCommand() {
private val ncmApiUrl = "${configManager.ncmAPI}/top/song"
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
val id = Http.get<TopSong>(ncmApiUrl).data.random().privilege.id
val msg = MessageChain.Builder()
.addMusicShare(MusicShareType.Netease, id.toString())
.build()
listener.sendGroupMessage(message.groupId, msg)
message.reply(msg)
}
}
@@ -10,25 +10,19 @@ package cn.rtast.fancybot.commands.misc
import cn.rtast.fancybot.annotations.CommandDescription
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.enums.QQFace
import cn.rtast.rob.onebot.OneBotAction
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("让你的消息得到回应(reaction)!")
class ReactionCommand : BaseCommand() {
override val commandNames = listOf("reaction", "回应")
companion object {
suspend fun reaction(listener: OneBotListener, message: GroupMessage, messageId: Long, limit: Int = 30) {
(0..limit - 1).forEach {
listener.reaction(
message.groupId,
messageId,
QQFace.entries.random().id.toString()
)
}
suspend fun reaction(action: OneBotAction, groupId: Long, messageId: Long, limit: Int = 30) {
(0..limit - 1).forEach { action.reaction(groupId, messageId, QQFace.entries.random().id.toString()) }
}
}
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) =
reaction(listener, message, message.messageId)
override suspend fun executeGroup(message: GroupMessage, args: List<String>) =
reaction(message.action, message.groupId, message.messageId)
}
@@ -11,9 +11,8 @@ import cn.rtast.fancybot.annotations.CommandDescription
import cn.rtast.fancybot.enums.CountryList
import cn.rtast.fancybot.util.misc.randomBooleanWithProbability
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("人生重开模拟器")
class RemakeCommand : BaseCommand() {
@@ -30,7 +29,7 @@ class RemakeCommand : BaseCommand() {
"鸽子", "鼠鼠", "化石", "狗狗"
)
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
val isSuccess = randomBooleanWithProbability(0.7)
val msg = MessageChain.Builder().addReply(message.messageId)
if (isSuccess) {
@@ -40,6 +39,6 @@ class RemakeCommand : BaseCommand() {
msg.addText("重开成功! 你转生在${country.chineseName}$location, 是一个$role")
} else
msg.addText("转生失败~")
listener.sendGroupMessage(message.groupId, msg.build())
message.reply(msg.build())
}
}
@@ -1,14 +0,0 @@
/*
* Copyright © 2024 RTAkland
* Author: RTAkland
* Date: 2024/10/15
*/
package cn.rtast.fancybot.commands.misc
import cn.rtast.fancybot.annotations.CommandDescription
@CommandDescription("复读鸡")
object RepeatCommand {
}
@@ -9,20 +9,18 @@ package cn.rtast.fancybot.commands.misc
import cn.rtast.fancybot.annotations.CommandDescription
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("资料卡点赞")
class SendLikeCommand : BaseCommand() {
override val commandNames = listOf("赞我")
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
listener.sendLike(message.sender.userId, 10)
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
message.action.sendLike(message.sender.userId, 10)
val msg = MessageChain.Builder()
.addReply(message.messageId)
.addText("👍了你十下~~😁")
.build()
listener.sendGroupMessage(message.groupId, msg)
message.reply(msg)
}
}
@@ -13,7 +13,6 @@ import cn.rtast.fancybot.enums.CommandAction
import cn.rtast.fancybot.util.file.insertActionRecord
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.OneBotListener
import org.simplejavamail.api.mailer.config.TransportStrategy
import org.simplejavamail.email.EmailBuilder
import org.simplejavamail.mailer.MailerBuilder
@@ -43,7 +42,7 @@ class SendMailCommand : BaseCommand() {
this.mailer.sendMail(email)
}
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
if (args.isEmpty()) {
message.reply("发送`/mail <收件人地址>`即可发送测试邮件~")
return
@@ -16,7 +16,6 @@ import cn.rtast.fancybot.util.Http
import cn.rtast.fancybot.util.str.toJson
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("生成短链接")
class ShortLinkCommand : BaseCommand() {
@@ -34,7 +33,7 @@ class ShortLinkCommand : BaseCommand() {
}
}
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
if (args.isEmpty()) {
message.reply("发送`/s <url>`来生成短链接`不要放入一些奇怪的链接哦~")
return
@@ -12,9 +12,9 @@ import cn.rtast.fancybot.entity.tts.TTSResponse
import cn.rtast.fancybot.util.Http
import cn.rtast.fancybot.util.str.proxy
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.enums.AIRecordCharacter
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
import okhttp3.FormBody
@CommandDescription("将文字转换成语音(TTS)!")
@@ -23,7 +23,7 @@ class TTSCommand : BaseCommand() {
private val ttsApiUrl = "https://ttsmp3.com/makemp3_new.php"
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
if (args.isEmpty()) {
message.reply("发送`/tts <文字>`就可以生成语音啦~")
return
@@ -38,6 +38,17 @@ class TTSCommand : BaseCommand() {
val msg = MessageChain.Builder()
.addRecord(response.url.proxy)
.build()
listener.sendGroupMessage(message.groupId, msg)
message.reply(msg)
}
}
class AITTSCommand : BaseCommand() {
override val commandNames = listOf("/aitts")
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
val content = args.joinToString(" ").trim()
val character = if (args.size == 1) AIRecordCharacter.XiaoXin
else AIRecordCharacter.forName(args.last()) ?: AIRecordCharacter.XiaoXin
message.action.sendGroupAIRecord(message.groupId, character, content)
}
}
@@ -9,16 +9,15 @@ package cn.rtast.fancybot.commands.misc
import cn.rtast.fancybot.annotations.CommandDescription
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
@Deprecated("已迁移到兑换列表中")
@CommandDescription("获得十张色图!")
class TenSetuCommand : BaseCommand() {
override val commandNames = listOf("十张色图")
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
val msg = MessageChain.Builder()
.addText("指令已经迁移到兑换列表中")
.addNewLine()
@@ -10,7 +10,6 @@ package cn.rtast.fancybot.commands.misc
import cn.rtast.fancybot.annotations.CommandDescription
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.OneBotListener
import kotlin.random.Random
@CommandDescription("今天吃什么")
@@ -25,7 +24,7 @@ class TodayEatCommand : BaseCommand() {
"酸辣粉", "煲仔饭", "", ""
)
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
if (KFCCommand.isThursday() && Random.nextBoolean()) {
message.reply("今天是疯! 狂! 星! 期! 四!, 所以吃肯德基!")
return
@@ -38,7 +37,7 @@ class TodayEatCommand : BaseCommand() {
class TodayDontEatCommand : BaseCommand() {
override val commandNames = listOf("今天不吃什么")
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
message.reply("你吃个结巴, 是吧")
}
}
@@ -54,7 +53,7 @@ class TodayDrinkCommand : BaseCommand() {
"气泡水", "奶盖茶", "冰可乐", "草莓汁", "芒果汁", "蓝莓汁", "热奶茶", "蜂蜜柚子茶"
)
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
message.reply("今天喝${drinkList.random()}吧~")
}
}
@@ -63,7 +62,28 @@ class TodayDrinkCommand : BaseCommand() {
class TodayDontDrinkCommand : BaseCommand() {
override val commandNames = listOf("今天不喝什么")
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
message.reply("你喝个结巴, 是吧")
}
}
@CommandDescription("今天抽什么")
class TodaySmokeCommand : BaseCommand() {
override val commandNames = listOf("今天抽什么")
private val smokeList = listOf(
"黑利", "蓝利", "白利", "普皖", "金皖",
"宽窄", "煊赫门", "骆驼", "百乐(红酒)",
"手卷烟", "烟斗", "万宝路", "白沙3代",
"白沙2代", "中华", "南京-大观园", "金钗",
"银钗", "玉溪", "芒果", "南京-雨花石",
"金圣", "南京95", "红塔山", "轿子",
"钻石荷花", "黄金叶(天叶)", "芙蓉王",
"黄鹤楼", "红河", "长白山", "长丰",
"中南海(蓝莓爆珠)", "云烟", "真龙", "红利"
)
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
message.reply("今天抽${smokeList.random()}吧~")
}
}
@@ -13,7 +13,6 @@ import cn.rtast.fancybot.util.str.encodeToBase64
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.enums.ArrayMessageType
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("将人类的语言翻译成尊嘟假嘟语还能将尊嘟假嘟语翻译成人类的语言!")
class ZDJDCommand : BaseCommand() {
@@ -78,7 +77,7 @@ class ZDJDCommand : BaseCommand() {
}
}
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
val text = if (message.message.any { it.type == ArrayMessageType.image }) {
message.message.find { it.type == ArrayMessageType.image }!!.data.file!!
} else args.joinToString(" ")
@@ -10,9 +10,8 @@ package cn.rtast.fancybot.commands.misc
import cn.rtast.fancybot.annotations.CommandDescription
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.entity.PrivateMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
val users = mutableMapOf<Long, Long>()
@@ -20,7 +19,7 @@ val users = mutableMapOf<Long, Long>()
class ZiBiCommand : BaseCommand() {
override val commandNames = listOf("/自闭", "自闭")
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
try {
users.remove(message.sender.userId)
val duration = if (args.isEmpty()) 1 else args.first().toInt()
@@ -47,7 +46,7 @@ class ZiBiCommand : BaseCommand() {
class UnsetZiBiCommand : BaseCommand() {
override val commandNames = listOf("我想开了")
override suspend fun executePrivate(listener: OneBotListener, message: PrivateMessage, args: List<String>) {
override suspend fun executePrivate(message: PrivateMessage, args: List<String>) {
if (!users.any { it.key == message.sender.userId }) {
val msg = MessageChain.Builder()
.addText("你没有在自闭列表中~")
@@ -55,7 +54,7 @@ class UnsetZiBiCommand : BaseCommand() {
message.reply(msg)
return
}
listener.setGroupBan(users.getValue(message.sender.userId), message.sender.userId, 0)
message.action.setGroupBan(users.getValue(message.sender.userId), message.sender.userId, 0)
val msg = MessageChain.Builder()
.addText("祝你天天开心不要自闭~~")
.build()
@@ -10,16 +10,15 @@ package cn.rtast.fancybot.commands.niuzi
import cn.rtast.fancybot.annotations.CommandDescription
import cn.rtast.fancybot.niuziManager
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("查询自己牛子的长度")
class MyNiuziCommand : BaseCommand() {
override val commandNames = listOf("我的牛子", "mp")
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
val niuzi = niuziManager.getUser(message.sender.userId)
if (niuzi == null) {
message.reply("你还没有牛子呢, 发送`牛子签到`来领取一根专属于你的牛子吧~")
@@ -37,6 +36,6 @@ class MyNiuziCommand : BaseCommand() {
else -> "牛子也太长啦把天捅穿啦!!!!!!"
}
msg.addText(niuziString)
listener.sendGroupMessage(message.groupId, msg.build())
message.reply(msg.build())
}
}
@@ -14,9 +14,8 @@ import cn.rtast.fancybot.niuziManager
import cn.rtast.fancybot.util.misc.getUserName
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.enums.ArrayMessageType
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
private suspend fun noAccount(message: GroupMessage) {
message.reply("你还没有银行账户呢, 发送`创建账户`来创建一个账户吧~")
@@ -28,7 +27,7 @@ private const val INTEREST_RATE = 0.0054
class NiuziBankCommand : BaseCommand() {
override val commandNames = listOf("牛子银行")
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
val niuziCommands = commands.filter {
it::class.simpleName?.startsWith("Niuzi")!! && !it::class.simpleName?.lowercase()?.contains("redeem")!!
}.joinToString("\n") { it.commandNames.joinToString(",") { join -> "`$join`" } }
@@ -49,7 +48,7 @@ class NiuziBankCommand : BaseCommand() {
class BankBalanceCommand : BaseCommand() {
override val commandNames = listOf("余额查询")
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
val balanceData = niuziBankManager.getUser(message.sender.userId)
if (balanceData == null) {
noAccount(message)
@@ -63,12 +62,12 @@ class BankBalanceCommand : BaseCommand() {
class CreateBankAccountCommand : BaseCommand() {
override val commandNames = listOf("创建账户")
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
if (niuziBankManager.getUser(message.sender.userId) != null) {
message.reply("你已经有账户了!")
return
}
val userInfo = listener.getGroupMemberInfo(message.groupId, message.sender.userId)
val userInfo = message.action.getGroupMemberInfo(message.groupId, message.sender.userId)
niuziBankManager.createBlankAccount(message.sender.userId, userInfo.card ?: userInfo.nickname)
message.reply("成功创建了一个账户!")
}
@@ -78,7 +77,7 @@ class CreateBankAccountCommand : BaseCommand() {
class BankTransferCommand : BaseCommand() {
override val commandNames = listOf("银行转账")
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
val currentUserBalance = niuziBankManager.getUser(message.sender.userId)
if (currentUserBalance == null) {
noAccount(message)
@@ -94,7 +93,7 @@ class BankTransferCommand : BaseCommand() {
message.reply("你的牛子长度不够转账!")
return
}
val username = listener.getUserName(message.groupId, message.sender.userId)
val username = message.action.getUserName(message.groupId, message.sender.userId)
val result = niuziBankManager.transfer(message.sender.userId, target, amount, username)
message.reply("转账成功! 你在银行内剩余的牛子长度为: ${result?.balance}")
}
@@ -104,7 +103,7 @@ class BankTransferCommand : BaseCommand() {
class WithdrawCommand : BaseCommand() {
override val commandNames = listOf("取牛子")
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
val amount = args.last().toDouble()
val currentBalance = niuziBankManager.getUser(message.sender.userId)
val niuzi = niuziManager.getUser(message.sender.userId)
@@ -124,7 +123,7 @@ class WithdrawCommand : BaseCommand() {
message.reply("取出的长度必须大于0!")
return
}
val username = listener.getUserName(message.groupId, message.sender.userId)
val username = message.action.getUserName(message.groupId, message.sender.userId)
val result = niuziBankManager.withdraw(message.sender.userId, amount, username)
niuziManager.updateLength(message.sender.userId, amount + amount * INTEREST_RATE)
message.reply("取牛子成功, 你现在还剩${result.balance}cm的牛子在银行内")
@@ -135,7 +134,7 @@ class WithdrawCommand : BaseCommand() {
class DepositCommand : BaseCommand() {
override val commandNames = listOf("存牛子")
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
val currentBalance = niuziBankManager.getUser(message.sender.userId)
val niuzi = niuziManager.getUser(message.sender.userId)
val amount = args.last().toDouble()
@@ -155,7 +154,7 @@ class DepositCommand : BaseCommand() {
message.reply("你身上的牛子不够用啦, 没办法存进银行! >>> ${niuzi.length}")
return
}
val username = listener.getUserName(message.groupId, message.sender.userId)
val username = message.action.getUserName(message.groupId, message.sender.userId)
val self = niuziManager.updateLength(message.sender.userId, -amount)
val result = niuziBankManager.deposit(message.sender.userId, amount, username)
message.reply("存入成功你身上的牛子还有${self?.length}cm 银行账户内还有: ${result.balance}cm")
@@ -11,15 +11,14 @@ import cn.rtast.fancybot.annotations.CommandDescription
import cn.rtast.fancybot.niuziManager
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.enums.ArrayMessageType
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("来一起激情击剑吧!")
class NiuziJiJianCommand : BaseCommand() {
override val commandNames = listOf("击剑", "jj")
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
if (args.isEmpty()) {
message.reply("发送`击剑 @xxx`即可对某人进行击剑")
return
@@ -34,7 +33,7 @@ class NiuziJiJianCommand : BaseCommand() {
.addNewLine()
.addText("所以你不能和他们击剑~")
.build()
listener.sendGroupMessage(message.groupId, msg)
message.reply(msg)
return
}
if (message.sender.userId == targetId) {
@@ -69,7 +68,7 @@ class NiuziJiJianCommand : BaseCommand() {
.addNewLine()
.addText("对方的牛子增加了${result.second}cm~")
.build()
listener.sendGroupMessage(message.groupId, msg)
message.reply(msg)
}
}
}
@@ -8,36 +8,37 @@
package cn.rtast.fancybot.commands.niuzi
import cn.rtast.fancybot.annotations.CommandDescription
import cn.rtast.fancybot.configManager
import cn.rtast.fancybot.niuziBankManager
import cn.rtast.fancybot.niuziManager
import cn.rtast.fancybot.util.misc.getUserName
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.enums.ArrayMessageType
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("在群内设置某个成员的牛子银行余额或者现金牛子长度")
class NiuziManagerCommand : BaseCommand() {
override val commandNames = listOf("管理牛子")
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
if (args.isEmpty()) {
message.reply("此命令可以管理成员的牛子或者银行账户")
return
}
println(args)
if (message.sender.isAdmin || message.sender.isOwner) {
val target = message.message.find { it.type == ArrayMessageType.at }!!.data.qq!!.toLong()
val method = args[1]
val amount = args.last().toDouble()
val method = args[0]
val amount = args[1].toDouble()
when (method) {
"set", "s", "设置" -> {
val type = args[2]
when (type) {
"yh", "银行" -> {
val before = niuziBankManager.getUser(target)
niuziBankManager.deposit(target, amount, listener.getUserName(message.groupId, target))
niuziBankManager.deposit(
target, amount, message.action.getUserName(message.groupId, target)
)
val after = niuziBankManager.getUser(target)
val msg = MessageChain.Builder()
.addText("设置成功! 金额: $amount")
@@ -12,13 +12,12 @@ import cn.rtast.fancybot.niuziManager
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.enums.ArrayMessageType
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("查询别人的牛子长度")
class NiuziQueryCommand : BaseCommand() {
override val commandNames = listOf("牛子查询")
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
if (args.isEmpty()) {
message.reply("输入`牛子查询 @某人`即可查询他的牛子长度")
return
@@ -11,15 +11,14 @@ import cn.rtast.fancybot.annotations.CommandDescription
import cn.rtast.fancybot.niuziBankManager
import cn.rtast.fancybot.niuziManager
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("查询所有人的牛子的排行榜")
class NiuziRankCommand : BaseCommand() {
override val commandNames = listOf("牛子排行榜", "牛子排行")
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
val allNiuzi = niuziManager.getAllNiuzi().sortedBy { it.length }.reversed()
val msg = MessageChain.Builder().addText("牛子长度排行榜如下").addNewLine()
allNiuzi.forEach {
@@ -33,7 +32,7 @@ class NiuziRankCommand : BaseCommand() {
class NiuziBankRankCommand : BaseCommand() {
override val commandNames = listOf("牛子富豪榜", "富豪榜")
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
val allNiuziBankAccounts = niuziBankManager.getAllAccount()
.sortedBy { it.balance }.reversed()
val msg = MessageChain.Builder().addText("牛子银行富豪榜排行如下").addNewLine()
@@ -11,15 +11,14 @@ import cn.rtast.fancybot.annotations.CommandDescription
import cn.rtast.fancybot.itemManager
import cn.rtast.fancybot.niuziManager
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("使用牛子长度兑换物品")
class NiuziRedeemCommand : BaseCommand() {
override val commandNames = listOf("/rdm")
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
if (args.isEmpty()) {
val msg = MessageChain.Builder()
.addText("发送 /rdm <物品名称> 即可兑换哦!")
@@ -64,7 +63,7 @@ class NiuziRedeemCommand : BaseCommand() {
return
}
val afterStatus = niuziManager.redeemItem(message.sender.userId, selectedItemPrice)?.length!!
val action = selectedItem.redeemInGroup(listener, message, afterStatus)
val action = selectedItem.redeemInGroup(message, afterStatus)
val msg = MessageChain.Builder()
.addText("兑换成功! 你花费了${selectedItemPrice}cm来兑换奖品, 还剩${afterStatus}cm")
.addNewLine()
@@ -11,20 +11,19 @@ import cn.rtast.fancybot.annotations.CommandDescription
import cn.rtast.fancybot.niuziManager
import cn.rtast.fancybot.util.misc.getUserName
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("牛子签到~")
class NiuziSignCommand : BaseCommand() {
override val commandNames = listOf("牛子签到", "签到")
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
if (niuziManager.isSigned(message.sender.userId)) {
message.reply("你今天已经对你的牛子使用了签到啦,明天再来吧~")
return
}
val username = listener.getUserName(message.groupId, message.sender.userId)
val username = message.action.getUserName(message.groupId, message.sender.userId)
val afterStatus = niuziManager.sign(message.sender.userId, username)
val msg = MessageChain.Builder()
.addReply(message.messageId)
@@ -32,6 +31,6 @@ class NiuziSignCommand : BaseCommand() {
.addNewLine()
.addText("你的牛子增加了${afterStatus.first}cm~ 总长度为: ${afterStatus.second?.length}")
.build()
listener.sendGroupMessage(message.groupId, msg)
message.reply(msg)
}
}
@@ -12,13 +12,12 @@ import cn.rtast.fancybot.niuziManager
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.enums.ArrayMessageType
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("将自己的牛子长度转账给别人")
class NiuziTransferCommand : BaseCommand() {
override val commandNames = listOf("牛子转账", "zz")
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
if (args.isEmpty()) {
message.reply("发送`牛子转账 @某人 <长度>` 即可把自己的牛子长度转账给TA")
return
@@ -18,10 +18,8 @@ import cn.rtast.fancybot.util.str.encodeToBase64
import cn.rtast.rob.entity.GetMessage
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.enums.ArrayMessageType
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
import cn.rtast.rob.util.ob.asMessageChain
import com.madgag.gif.fmsware.GifDecoder
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@@ -99,7 +97,7 @@ class AsciiArtCommand : BaseCommand() {
try {
decoder.read(gifStream)
if (decoder.frameCount == 0) {
val bufferedImage = withContext(Dispatchers.IO) { ImageIO.read(URI(url).toURL()) }
val bufferedImage = withContext(Dispatchers.IO) { ImageIO.read(gifStream) }
val imageBytes = bufferedImage.convertToAscii()
.saveAsciiArtToImage(bufferedImage.width, bufferedImage.height)
.toByteArray()
@@ -132,10 +130,10 @@ class AsciiArtCommand : BaseCommand() {
return msg
}
} catch (_: OutOfMemoryError) {
return listOf("GIF处理失败: 内存溢出").asMessageChain()
return MessageChain.Builder().addText("GIF处理失败: 内存溢出").build()
logger.info("GIF处理失败: 内存溢出")
} catch (e: Exception) {
return listOf("处理GIF失败: ${e.message}").asMessageChain()
return MessageChain.Builder().addText("处理GIF失败: ${e.message}").build()
logger.info("gif处理失败: ${e.message}")
}
}
@@ -157,7 +155,7 @@ class AsciiArtCommand : BaseCommand() {
return getImageUrlFromUnified(toUnifiedMessage(groupMessage))
}
fun getImageUrl(getMessageData: GetMessage.Data): String {
fun getImageUrl(getMessageData: GetMessage.Message): String {
return getImageUrlFromUnified(toUnifiedMessage(getMessageData))
}
@@ -171,14 +169,14 @@ class AsciiArtCommand : BaseCommand() {
return groupMessage.message.map { UnifiedMessage(it.type, it.data.file, it.data.url) }
}
private fun toUnifiedMessage(getMessageData: GetMessage.Data): List<UnifiedMessage> {
private fun toUnifiedMessage(getMessageData: GetMessage.Message): List<UnifiedMessage> {
return getMessageData.message.map { UnifiedMessage(it.type, it.data.file, it.data.url) }
}
private data class UnifiedMessage(val type: ArrayMessageType, val file: String?, val url: String?)
}
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
if (message.sender.userId !in waitingList) {
message.reply("请继续发送一张图片, 如果输入错误则取消本次操作, 如果GIF帧数过多可能会需要很长时间(也可能处理失败)")
waitingList.add(message.sender.userId)
@@ -20,9 +20,9 @@ import cn.rtast.fancybot.util.str.formatNumber
import cn.rtast.fancybot.util.str.fromJson
import cn.rtast.fancybot.util.str.setTruncate
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.entity.text
import cn.rtast.rob.enums.ArrayMessageType
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
import cn.rtast.rob.onebot.MessageChain
import okhttp3.OkHttpClient
import okhttp3.Request
import java.awt.Color
@@ -184,7 +184,8 @@ object BiliVideoParseCommand {
return String(bytes)
}
suspend fun parse(listener: OneBotListener, message: GroupMessage) {
suspend fun parse(message: GroupMessage) {
if (!message.text.contains("bilibili.com") && !message.text.contains("b23.tv")) return
try {
val bvid = if (bvRegex.containsMatchIn(message.rawMessage)) {
message.rawMessage.extractBv()
@@ -229,11 +230,10 @@ object BiliVideoParseCommand {
share, like, favorite, fans, viewCount
)
val msg = MessageChain.Builder()
.addReply(message.messageId)
.addImage(image, true)
.addText(shortUrl)
.build()
listener.sendGroupMessage(message.groupId, msg)
message.reply(msg)
} catch (_: Exception) {
}
}
@@ -276,7 +276,7 @@ object BiliUserParseCommand {
return image.toByteArray().encodeToBase64()
}
suspend fun parse(listener: OneBotListener, message: GroupMessage) {
suspend fun parse(message: GroupMessage) {
val match = idRegex.find(message.rawMessage)
if (match != null) {
val userId = match.groupValues[1]
@@ -285,7 +285,7 @@ object BiliUserParseCommand {
val msg = MessageChain.Builder()
.addImage(userCardImage, true)
.build()
listener.sendGroupMessage(message.groupId, msg)
message.reply(msg)
}
}
}
@@ -19,7 +19,7 @@ import cn.rtast.fancybot.util.str.encodeToBase64
import cn.rtast.fancybot.util.str.formatNumber
import cn.rtast.fancybot.util.str.proxy
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.onebot.MessageChain
import okhttp3.OkHttpClient
import okhttp3.Request
import java.awt.Color
@@ -18,7 +18,7 @@ import cn.rtast.fancybot.util.str.encodeToBase64
import cn.rtast.fancybot.util.str.formatNumberEnglish
import cn.rtast.fancybot.util.str.setTruncate
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.onebot.MessageChain
import java.awt.Color
import java.awt.Font
import java.awt.RenderingHints
@@ -12,12 +12,12 @@ import cn.rtast.fancybot.configManager
import cn.rtast.rob.entity.GetMessage
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.enums.ArrayMessageType
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.asNode
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.onebot.toNode
object ImageURLCommand {
fun getImageUrl(message: GetMessage.Data): List<String> {
fun getImageUrl(message: GetMessage.Message): List<String> {
try {
val images = mutableListOf<String>()
message.message.forEach {
@@ -30,7 +30,7 @@ object ImageURLCommand {
}
}
suspend fun callback(groupMessage: GroupMessage, message: GetMessage.Data) {
suspend fun callback(groupMessage: GroupMessage, message: GetMessage.Message) {
val images = getImageUrl(message)
if (images.isEmpty()) {
groupMessage.reply("这个消息里没有图片呢!")
@@ -51,7 +51,7 @@ object ImageURLCommand {
.build()
messages.add(msg)
}
groupMessage.reply(messages.asNode(configManager.selfId))
groupMessage.reply(messages.toNode(configManager.selfId))
}
}
}
@@ -13,9 +13,8 @@ import cn.rtast.fancybot.util.str.encodeToBase64
import cn.rtast.rob.entity.GetMessage
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.enums.ArrayMessageType
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
import com.madgag.gif.fmsware.GifDecoder
import java.net.URI
@@ -35,7 +34,7 @@ class ReverseGIFCommand : BaseCommand() {
return gifBytes.encodeToBase64()
}
suspend fun reverse(message: GroupMessage, getMsg: GetMessage.Data) {
suspend fun reverse(message: GroupMessage, getMsg: GetMessage.Message) {
val imageObject = getMsg.message.find { it.type == ArrayMessageType.image }
if (imageObject == null) {
message.reply("这个消息中没有图片呢")
@@ -63,7 +62,7 @@ class ReverseGIFCommand : BaseCommand() {
}
}
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
if (message.sender.userId !in waitingList) {
message.reply("发送一张动图来继续操作")
waitingList.add(message.sender.userId)
@@ -17,7 +17,7 @@ import cn.rtast.fancybot.util.str.encodeToBase64
import cn.rtast.fancybot.util.str.formatNumber
import cn.rtast.fancybot.util.str.proxy
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.onebot.MessageChain
import java.awt.Color
import java.awt.Font
import java.awt.RenderingHints
@@ -15,12 +15,12 @@ import cn.rtast.fancybot.util.misc.ImageBed
import cn.rtast.fancybot.util.misc.toURL
import cn.rtast.rob.entity.GetMessage
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.asNode
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.onebot.toNode
import okio.IOException
object ImageBedCommand {
suspend fun execute(getMsg: GetMessage.Data, message: GroupMessage) {
suspend fun execute(getMsg: GetMessage.Message, message: GroupMessage) {
val imagesUrl = ImageURLCommand.getImageUrl(getMsg)
if (imagesUrl.isEmpty()) {
message.reply("这个消息里没有图片呢!")
@@ -49,7 +49,7 @@ object ImageBedCommand {
.build()
messages.add(msg)
}
message.reply(messages.asNode(configManager.selfId))
message.reply(messages.toNode(configManager.selfId))
}
} catch (_: IOException) {
message.reply("上传失败: 图片已过期")
@@ -0,0 +1,31 @@
/*
* Copyright © 2024 RTAkland
* Author: RTAkland
* Date: 2024/10/31
*/
package cn.rtast.fancybot.commands.reply
import cn.rtast.fancybot.util.misc.invertColor
import cn.rtast.fancybot.util.misc.toBufferedImage
import cn.rtast.fancybot.util.misc.toByteArray
import cn.rtast.fancybot.util.misc.toURL
import cn.rtast.fancybot.util.str.encodeToBase64
import cn.rtast.rob.entity.GetMessage
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.entity.images
import cn.rtast.rob.onebot.MessageChain
object InvertImageCommand {
suspend fun invert(message: GroupMessage, getMsg: GetMessage.Message) {
val msg = MessageChain.Builder()
getMsg.images.forEach {
val img = it.file.toURL().readBytes().toBufferedImage()
.invertColor().toByteArray().encodeToBase64()
msg.addImage(img, true)
}
message.reply(msg.build())
}
}
@@ -0,0 +1,33 @@
/*
* Copyright © 2024 RTAkland
* Author: RTAkland
* Date: 2024/10/31
*/
package cn.rtast.fancybot.commands.reply
import cn.rtast.fancybot.util.misc.randomColor
import cn.rtast.fancybot.util.misc.toBufferedImage
import cn.rtast.fancybot.util.misc.toByteArray
import cn.rtast.fancybot.util.misc.toURL
import cn.rtast.fancybot.util.str.encodeToBase64
import cn.rtast.rob.entity.GetMessage
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.entity.images
import cn.rtast.rob.onebot.MessageChain
object RandomRGBCommand {
suspend fun random(message: GroupMessage, getMsg: GetMessage.Message) {
val msg = MessageChain.Builder()
getMsg.images.forEach {
msg.addImage(
it.file.toURL().readBytes().toBufferedImage()
.randomColor().toByteArray().encodeToBase64(),
true
)
}
message.reply(msg.build())
}
}
@@ -0,0 +1,37 @@
/*
* Copyright © 2024 RTAkland
* Author: RTAkland
* Date: 2024/10/27
*/
package cn.rtast.fancybot.commands.reply
import cn.rtast.fancybot.commands.misc.ShortLinkCommand.Companion.makeShortLink
import cn.rtast.fancybot.commands.parse.AsciiArtCommand
import cn.rtast.fancybot.util.misc.ImageBed
import cn.rtast.fancybot.util.misc.makeGif
import cn.rtast.fancybot.util.misc.toURL
import cn.rtast.fancybot.util.str.encodeToBase64
import cn.rtast.rob.entity.GetMessage
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import com.madgag.gif.fmsware.GifDecoder
object SpeedUpGIFCommand {
suspend fun speedUp(message: GroupMessage, getMsg: GetMessage.Message, multiply: Float) {
val gifUrl = AsciiArtCommand.getImageUrl(getMsg)
val gifStream = gifUrl.toURL().openStream()
val decoder = GifDecoder()
decoder.read(gifStream)
val frames = (0 until decoder.frameCount).map { decoder.getFrame(it) }
val gifBase64 = decoder.makeGif(frames, multiply)
val imgBedUrl = ImageBed.upload(gifBase64)
val shortLink = imgBedUrl.makeShortLink()
val msg = MessageChain.Builder()
.addImage(gifBase64.encodeToBase64(), true)
.addText(shortLink)
.build()
message.reply(msg)
}
}
@@ -29,7 +29,7 @@ object MinecraftAccessTokenTable : Table("mc_access_token") {
data class MCAccessTokenEntity(
val token: String,
val userId: Long,
val timestamp: Long
val timestamp: Long,
)
suspend fun insertNewAccessToken(accessToken: String, id: Long) {
@@ -24,5 +24,5 @@ data class NiuziBankAccount(
val balance: Double,
val interestRate: Double,
val timestamp: Long,
val nickname: String
val nickname: String,
)
@@ -24,6 +24,6 @@ data class RCONEntity(
val port: Int,
val userId: Long,
val name: String,
val password: String
val password: String,
)
@@ -7,13 +7,11 @@
package cn.rtast.fancybot.entity
import cn.rtast.fancybot.enums.DatabaseType
import cn.rtast.fancybot.enums.ImageBedType
import cn.rtast.fancybot.enums.ImageType
import cn.rtast.fancybot.enums.WSType
data class Config(
val database: Database,
val ncmAPI: String,
val wsType: WSType,
val wsAddress: String,
@@ -51,13 +49,7 @@ data class Config(
val apiRtastKey: String,
val azureAppClientId: String,
val youtubeDataApiKey: String,
) {
data class Database(
val type: DatabaseType,
val host: String,
val port: Int,
val user: String,
val password: String,
val database: String,
)
}
val naiLongApiUrl: String,
val osuClientSecret: String,
val osuClientId: Int
)
@@ -13,5 +13,5 @@ data class Hitokoto(
val uuid: String,
@SerializedName("hitokoto")
val sentence: String,
val from: String
val from: String,
)
@@ -8,7 +8,7 @@
package cn.rtast.fancybot.entity.apispace
data class IdiomExplainResponse(
val data: List<Data>
val data: List<Data>,
) {
data class Data(
val name: String,
@@ -10,7 +10,7 @@ package cn.rtast.fancybot.entity.bgm
import com.google.gson.annotations.SerializedName
data class BGMSearch(
val list: List<Result>
val list: List<Result>,
) {
data class Result(
val url: String,
@@ -21,6 +21,6 @@ data class BGMSearch(
)
data class Images(
val large: String
val large: String,
)
}
@@ -15,7 +15,7 @@ data class CardShare(
data class Meta(
@SerializedName("detail_1")
val detail: Detail?,
val news: News?
val news: News?,
)
data class Detail(
@@ -26,6 +26,6 @@ data class CardShare(
data class News(
val tag: String,
val jumpUrl: String
val jumpUrl: String,
)
}
@@ -8,9 +8,9 @@
package cn.rtast.fancybot.entity.bili
data class ShortUrl(
val data: Data
val data: Data,
) {
data class Data(
val content: String
val content: String,
)
}
@@ -10,7 +10,7 @@ package cn.rtast.fancybot.entity.bili
import com.google.gson.annotations.SerializedName
data class UserInfo(
val data: Data
val data: Data,
) {
data class Data(
val card: Card,
@@ -22,7 +22,7 @@ data class UserInfo(
val fans: Int,
val sign: String,
@SerializedName("level_info")
val levelInfo: LevelInfo
val levelInfo: LevelInfo,
)
data class LevelInfo(
@@ -8,9 +8,9 @@
package cn.rtast.fancybot.entity.bili
data class UserStat(
val data: Data
val data: Data,
) {
data class Data(
val follower: Int
val follower: Int,
)
}
@@ -8,7 +8,7 @@
package cn.rtast.fancybot.entity.bili
data class VideoStat(
val data: Data
val data: Data,
) {
data class Data(
val aid: Long,
@@ -8,9 +8,9 @@
package cn.rtast.fancybot.entity.bili
data class ViewCount(
val data: Data
val data: Data,
) {
data class Data(
val total: String
val total: String,
)
}
@@ -4,5 +4,5 @@ data class BullShit(
val after: List<String>,
val before: List<String>,
val bosh: List<String>,
val famous: List<String>
val famous: List<String>,
)
@@ -13,7 +13,7 @@ data class Cigarette(
@SerializedName("totalnum")
val totalCount: Int,
@SerializedName("productlist")
val productList: List<Product>
val productList: List<Product>,
) {
data class Product(
@SerializedName("productname")
@@ -26,11 +26,11 @@ data class Cigarette(
@SerializedName("packprice")
val packPrice: Float,
@SerializedName("barprice")
val barPrice: Float
val barPrice: Float,
)
data class CigaretteType(
@SerializedName("typename")
val typeName: String
val typeName: String,
)
}
@@ -8,10 +8,10 @@
package cn.rtast.fancybot.entity.compiler
data class GLOTPayload(
val files: List<File>
val files: List<File>,
) {
data class File(
val content: String,
val name: String = "main"
val name: String = "main",
)
}
@@ -10,11 +10,11 @@ package cn.rtast.fancybot.entity.compiler
data class KCSPayload(
val files: List<File>,
val args: String = "",
val confType: String = "java"
val confType: String = "java",
) {
data class File(
val text: String,
val name: String = "File.kt",
val publicId: String = ""
val publicId: String = "",
)
}
@@ -13,10 +13,10 @@ data class KCSResponse(
val errors: Errors,
val exception: Any,
val jvmByteCode: Any,
val text: String
val text: String,
) {
data class Errors(
@SerializedName("File.kt")
val file: List<Any>
val file: List<Any>,
)
}
@@ -24,5 +24,5 @@ data class PricePayload(
@SerializedName("Version")
val version: String = "2018-08-08",
@SerializedName("Action")
val action: String = "BatchCheckDomain"
val action: String = "BatchCheckDomain",
)
Loaded 100 of 160 files, more files were not shown because too many files have changed in this diff. Show more