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 { repositories {
mavenCentral() mavenCentral()
mavenLocal() mavenLocal()
maven("https://jitpack.io")
maven("https://repo.opencollab.dev/main/") maven("https://repo.opencollab.dev/main/")
maven("https://oss.sonatype.org/content/repositories/snapshots") maven("https://oss.sonatype.org/content/repositories/snapshots")
maven("https://repo.rtast.cn/api/v4/projects/33/packages/maven") maven("https://repo.maven.rtast.cn/releases/")
maven("https://repo.rtast.cn/api/v4/projects/19/packages/maven") maven("https://libraries.minecraft.net")
maven("https://repo.rtast.cn/api/v4/projects/3/packages/maven")
} }
tasks.compileKotlin { tasks.compileKotlin {
@@ -32,16 +30,13 @@ tasks.compileJava {
targetCompatibility = "17" targetCompatibility = "17"
} }
dependencies { dependencies {
implementation(libs.ronebot) implementation(libs.ronebot)
implementation(libs.okhttp) implementation(libs.okhttp)
implementation(libs.exposed.core) implementation(libs.exposed.core)
implementation(libs.exposed.jdbc) implementation(libs.exposed.jdbc)
implementation(libs.exposed.dao) implementation(libs.exposed.dao)
implementation(libs.sqlite.jdbc) implementation(libs.h2.jdbc)
implementation(libs.mysql.jdbc)
implementation(libs.postgressql.jdbc)
implementation(libs.motd.pinger) implementation(libs.motd.pinger)
implementation(libs.animated.gif.lib) implementation(libs.animated.gif.lib)
implementation(libs.simple.java.mail) implementation(libs.simple.java.mail)
@@ -49,8 +44,6 @@ dependencies {
implementation(libs.nashorn.core) implementation(libs.nashorn.core)
implementation(libs.zxing.core) implementation(libs.zxing.core)
implementation(libs.zxing.javase) implementation(libs.zxing.javase)
implementation(libs.logback.classic)
implementation(libs.slf4j.api)
implementation(libs.aws.s3.sdk) implementation(libs.aws.s3.sdk)
implementation(libs.rconlib) implementation(libs.rconlib)
implementation(libs.mcprotocollib) implementation(libs.mcprotocollib)
+5
View File
@@ -1,2 +1,7 @@
kotlin.code.style=official kotlin.code.style=official
fancyBotVersion=1.0.0 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] [versions]
kotlinVersion = "2.0.20" kotlinVersion = "2.0.20"
ronebotVersion = "1.14.1" ronebotVersion = "2.7.4"
shadowVersion = "8.3.0" shadowVersion = "8.3.0"
okhttpVersion = "5.0.0-alpha.14" okhttpVersion = "5.0.0-alpha.14"
exposedVersion = "0.53.0" exposedVersion = "0.53.0"
sqliteJDBCVersion = "3.46.1.0"
motdPingerVersion = "1.1.4" motdPingerVersion = "1.1.4"
animatedGifLibVersion = "1.4" animatedGifLibVersion = "1.4"
simpleJavaMailVersion = "8.12.2" simpleJavaMailVersion = "8.12.2"
jsoupVersion = "1.18.1" jsoupVersion = "1.18.1"
nashornVersion = "15.4" nashornVersion = "15.4"
zxingVersion = "3.5.3" zxingVersion = "3.5.3"
logbackClassicVersion = "1.5.8"
slf4jVersion = "2.0.16"
awsS3SDKVersion = "2.28.18" awsS3SDKVersion = "2.28.18"
rconLibVersion = "1.1.0" rconLibVersion = "1.1.1"
mysqlConnectorVersion = "9.1.0"
postgresqlVersion = "42.7.4"
mcprotolobVersion = "1.21-SNAPSHOT" mcprotolobVersion = "1.21-SNAPSHOT"
h2Version = "2.3.232"
[libraries] [libraries]
ronebot = { group = "cn.rtast", name = "ROneBot", version.ref = "ronebotVersion" } ronebot = { group = "cn.rtast.rob", name = "ronebot-onebot-v11", version.ref = "ronebotVersion" }
motd-pinger = { group = "cn.rtast", name = "MotdPinger", version.ref = "motdPingerVersion" } motd-pinger = { group = "cn.rtast", name = "motd-pinger", version.ref = "motdPingerVersion" }
okhttp = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okhttpVersion" } okhttp = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okhttpVersion" }
exposed-core = { group = "org.jetbrains.exposed", name = "exposed-core", version.ref = "exposedVersion" } 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-jdbc = { group = "org.jetbrains.exposed", name = "exposed-jdbc", version.ref = "exposedVersion" }
exposed-dao = { group = "org.jetbrains.exposed", name = "exposed-dao", 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" } 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" } simple-java-mail = { group = "org.simplejavamail", name = "simple-java-mail", version.ref = "simpleJavaMailVersion" }
jsoup = { group = "org.jsoup", name = "jsoup", version.ref = "jsoupVersion" } jsoup = { group = "org.jsoup", name = "jsoup", version.ref = "jsoupVersion" }
nashorn-core = { group = "org.openjdk.nashorn", name = "nashorn-core", version.ref = "nashornVersion" } nashorn-core = { group = "org.openjdk.nashorn", name = "nashorn-core", version.ref = "nashornVersion" }
zxing-core = { group = "com.google.zxing", name = "core", version.ref = "zxingVersion" } zxing-core = { group = "com.google.zxing", name = "core", version.ref = "zxingVersion" }
zxing-javase = { group = "com.google.zxing", name = "javase", 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" } 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" } mcprotocollib = { group = "org.geysermc.mcprotocollib", name = "protocol", version.ref = "mcprotolobVersion" }
h2-jdbc = { group = "com.h2database", name = "h2", version.ref = "h2Version" }
[bundles] [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 distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists 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 zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
Vendored
+31 -13
View File
@@ -15,6 +15,8 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
# #
# SPDX-License-Identifier: Apache-2.0
#
############################################################################## ##############################################################################
# #
@@ -55,7 +57,7 @@
# Darwin, MinGW, and NonStop. # Darwin, MinGW, and NonStop.
# #
# (3) This script is generated from the Groovy template # (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. # within the Gradle project.
# #
# You can find Gradle at https://github.com/gradle/gradle/. # You can find Gradle at https://github.com/gradle/gradle/.
@@ -80,13 +82,12 @@ do
esac esac
done done
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit # This is normally unused
# shellcheck disable=SC2034
APP_NAME="Gradle"
APP_BASE_NAME=${0##*/} APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' ' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum MAX_FD=maximum
@@ -133,22 +134,29 @@ location of your Java installation."
fi fi
else else
JAVACMD=java 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 Please set the JAVA_HOME variable in your environment to match the
location of your Java installation." location of your Java installation."
fi
fi fi
# Increase the maximum file descriptors if we can. # Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #( case $MAX_FD in #(
max*) 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 ) || MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit" warn "Could not query maximum file descriptor limit"
esac esac
case $MAX_FD in #( case $MAX_FD in #(
'' | soft) :;; #( '' | 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" || ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD" warn "Could not set maximum file descriptor limit to $MAX_FD"
esac esac
@@ -193,11 +201,15 @@ if "$cygwin" || "$msys" ; then
done done
fi fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
# shell script including quotes and variable substitutions, so put them in DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded. # 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 -- \ set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \ "-Dorg.gradle.appname=$APP_BASE_NAME" \
@@ -205,6 +217,12 @@ set -- \
org.gradle.wrapper.GradleWrapperMain \ 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. # Use "xargs" to parse quoted args.
# #
# With -n1 it outputs one arg per line, with the quotes and backslashes removed. # 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 See the License for the specific language governing permissions and
@rem limitations under the License. @rem limitations under the License.
@rem @rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%" == "" @echo off @if "%DEBUG%"=="" @echo off
@rem ########################################################################## @rem ##########################################################################
@rem @rem
@rem Gradle startup script for Windows @rem Gradle startup script for Windows
@@ -25,7 +27,8 @@
if "%OS%"=="Windows_NT" setlocal if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0 set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=. if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0 set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME% set APP_HOME=%DIRNAME%
@@ -40,13 +43,13 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1 %JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute if %ERRORLEVEL% equ 0 goto execute
echo. echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. echo location of your Java installation. 1>&2
goto fail goto fail
@@ -56,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute if exist "%JAVA_EXE%" goto execute
echo. echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. echo location of your Java installation. 1>&2
goto fail goto fail
@@ -75,13 +78,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
:end :end
@rem End local scope for the variables with windows NT shell @rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd if %ERRORLEVEL% equ 0 goto mainEnd
:fail :fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code! rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 set EXIT_CODE=%ERRORLEVEL%
exit /b 1 if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd :mainEnd
if "%OS%"=="Windows_NT" endlocal if "%OS%"=="Windows_NT" endlocal
+12 -35
View File
@@ -8,35 +8,22 @@
package cn.rtast.fancybot package cn.rtast.fancybot
import cn.rtast.fancybot.commands.AboutCommand import cn.rtast.fancybot.commands.*
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.lookup.* import cn.rtast.fancybot.commands.lookup.*
import cn.rtast.fancybot.commands.misc.* 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.*
import cn.rtast.fancybot.commands.niuzi.NiuziRedeemCommand
import cn.rtast.fancybot.commands.parse.AsciiArtCommand import cn.rtast.fancybot.commands.parse.AsciiArtCommand
import cn.rtast.fancybot.commands.parse.ReverseGIFCommand import cn.rtast.fancybot.commands.parse.ReverseGIFCommand
import cn.rtast.fancybot.entity.Config import cn.rtast.fancybot.entity.Config
import cn.rtast.fancybot.enums.DatabaseType
import cn.rtast.fancybot.enums.ImageBedType import cn.rtast.fancybot.enums.ImageBedType
import cn.rtast.fancybot.enums.ImageType import cn.rtast.fancybot.enums.ImageType
import cn.rtast.fancybot.enums.WSType import cn.rtast.fancybot.enums.WSType
import cn.rtast.fancybot.items.* import cn.rtast.fancybot.items.*
import cn.rtast.fancybot.util.file.BlackListManager import cn.rtast.fancybot.util.file.*
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.item.ItemManager import cn.rtast.fancybot.util.item.ItemManager
import cn.rtast.rob.ROneBotFactory
import com.google.gson.Gson import com.google.gson.Gson
import com.google.gson.GsonBuilder import com.google.gson.GsonBuilder
import java.io.File
import java.time.Instant import java.time.Instant
val gson: Gson = GsonBuilder() val gson: Gson = GsonBuilder()
@@ -45,19 +32,12 @@ val gson: Gson = GsonBuilder()
.create() .create()
const val ROOT_PATH = "./data" const val ROOT_PATH = "./data"
val ROOT_PATH_ = File(ROOT_PATH).apply { mkdirs() }
const val ASSETS_BASE_URL = "https://static.rtast.cn" const val ASSETS_BASE_URL = "https://static.rtast.cn"
const val API_RTAST_URL = "https://api.rtast.cn" const val API_RTAST_URL = "https://api.rtast.cn"
const val PBI_API_URL = "https://pbi.us.kg" const val PBI_API_URL = "https://pbi.us.kg"
val DEFAULT_CONFIG = Config( val DEFAULT_CONFIG = Config(
database = Config.Database(
DatabaseType.SQLite,
"127.0.0.1",
3306,
"root",
"114514",
"fancybot"
),
ncmAPI = "https://ncm.rtast.cn", ncmAPI = "https://ncm.rtast.cn",
wsAddress = "ws://127.0.0.1", wsAddress = "ws://127.0.0.1",
wsType = WSType.Client, wsType = WSType.Client,
@@ -94,7 +74,10 @@ val DEFAULT_CONFIG = Config(
apiSpaceKey = "114514", apiSpaceKey = "114514",
apiRtastKey = "114514", apiRtastKey = "114514",
azureAppClientId = "114514", azureAppClientId = "114514",
youtubeDataApiKey = "114514" youtubeDataApiKey = "114514",
naiLongApiUrl = "http://127.0.0.1:5000/nailong",
osuClientId = 111,
osuClientSecret = "222"
) )
val configManager = ConfigManager() val configManager = ConfigManager()
@@ -112,19 +95,11 @@ val items = listOf(
TenSetuItem(), TenSetuR18Item() TenSetuItem(), TenSetuR18Item()
) )
val tasks = mapOf(
10000000L to suspend {
configManager.admins.forEach {
ROneBotFactory.action.sendLike(it, 1)
}
}
)
val commands = listOf( val commands = listOf(
EchoCommand(), JrrpCommand(), NiuziRedeemCommand(), HitokotoCommand(), EchoCommand(), JrrpCommand(), NiuziRedeemCommand(), HitokotoCommand(),
KFCCommand(), GenerateQRCodeCommand(), AntiRevokeCommand(), MCPingCommand(), KFCCommand(), GenerateQRCodeCommand(), AntiRevokeCommand(), MCPingCommand(),
WeatherCommand(), CigaretteCommand(), RemakeCommand(), PixivCommand(), WeatherCommand(), CigaretteCommand(), RemakeCommand(), PixivCommand(),
RUACommand(), NslookupCommand(), CompilerCommand(), AICommand(), RUACommand(), CompilerCommand(), AICommand(),
GithubUserCommand(), AboutCommand(), MusicPlayUrlCommand(), DomainPriceCommand(), GithubUserCommand(), AboutCommand(), MusicPlayUrlCommand(), DomainPriceCommand(),
SendMailCommand(), ZiBiCommand(), UnsetZiBiCommand(), WikipediaCommand(), SendMailCommand(), ZiBiCommand(), UnsetZiBiCommand(), WikipediaCommand(),
AsciiArtCommand(), StatusCommand(), JueCommand(), ShortLinkCommand(), AsciiArtCommand(), StatusCommand(), JueCommand(), ShortLinkCommand(),
@@ -140,5 +115,7 @@ val commands = listOf(
MinecraftWikiCommand(), GaoKaoDaysRemainCommand(), IdiomExplainCommand(), NiuziManagerCommand(), MinecraftWikiCommand(), GaoKaoDaysRemainCommand(), IdiomExplainCommand(), NiuziManagerCommand(),
TodayEatCommand(), TodayDrinkCommand(), MCLoginCommand(), RCONCommand(), TodayEatCommand(), TodayDrinkCommand(), MCLoginCommand(), RCONCommand(),
GravatarCommand(), PastebinCommand(), ShuffleEchoCommand(), TodayDontEatCommand(), 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 package cn.rtast.fancybot
import cn.rtast.fancybot.commands.misc.JueCommand
import cn.rtast.fancybot.commands.misc.PastebinCommand import cn.rtast.fancybot.commands.misc.PastebinCommand
import cn.rtast.fancybot.commands.misc.ReactionCommand import cn.rtast.fancybot.commands.misc.ReactionCommand
import cn.rtast.fancybot.commands.misc.ScanQRCodeCommand import cn.rtast.fancybot.commands.misc.ScanQRCodeCommand
import cn.rtast.fancybot.commands.misc.ShortLinkCommand.Companion.makeShortLink import cn.rtast.fancybot.commands.misc.ShortLinkCommand.Companion.makeShortLink
import cn.rtast.fancybot.commands.parse.* import cn.rtast.fancybot.commands.parse.*
import cn.rtast.fancybot.commands.reply.ImageBedCommand 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.enums.WSType
import cn.rtast.fancybot.util.* import cn.rtast.fancybot.util.Logger
import cn.rtast.fancybot.util.misc.convertToDate import cn.rtast.fancybot.util.initDatabase
import cn.rtast.fancybot.util.misc.initBackgroundTasks import cn.rtast.fancybot.util.misc.*
import cn.rtast.fancybot.util.misc.initCommand import cn.rtast.fancybot.util.str.encodeToBase64
import cn.rtast.fancybot.util.misc.initFilesDir
import cn.rtast.fancybot.util.misc.initItems
import cn.rtast.fancybot.util.misc.initSetuIndex
import cn.rtast.rob.ROneBotFactory import cn.rtast.rob.ROneBotFactory
import cn.rtast.rob.entity.* 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.FileEvent
import cn.rtast.rob.entity.lagrange.PokeEvent import cn.rtast.rob.entity.lagrange.PokeEvent
import cn.rtast.rob.enums.ArrayMessageType import cn.rtast.rob.enums.ArrayMessageType
import cn.rtast.rob.enums.QQFace import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.ob.MessageChain import cn.rtast.rob.onebot.OneBotAction
import cn.rtast.rob.util.ob.OneBotListener 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.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.ByteArrayOutputStream
import java.io.File import java.io.File
import java.net.URI import java.net.URI
import java.util.zip.ZipEntry
import java.util.zip.ZipOutputStream
import javax.imageio.ImageIO
class FancyBot : OneBotListener { class FancyBot : OneBotListener {
private val logger = Logger.getLogger<FancyBot>() private val logger = Logger.getLogger<FancyBot>()
private val coroutineScope = CoroutineScope(Dispatchers.IO) private val coroutineScope = CoroutineScope(Dispatchers.IO)
override suspend fun onWebsocketOpenEvent() { override suspend fun onWebsocketOpenEvent(action: OneBotAction) {
this.sendPrivateMessage(configManager.noticeUser, "FancyBot启动完成~") action.sendPrivateMessage(configManager.noticeUser, "FancyBot启动完成~")
} }
override suspend fun onGroupMessage(message: GroupMessage, json: String) { override suspend fun onGroupMessage(message: GroupMessage, json: String) {
@@ -53,72 +66,138 @@ class FancyBot : OneBotListener {
logger.info("$sender($senderId: $groupId >>> $messageId): $msg") logger.info("$sender($senderId: $groupId >>> $messageId): $msg")
logger.trace("$sender($senderId: $groupId >>> $messageId: $json") logger.trace("$sender($senderId: $groupId >>> $messageId: $json")
if (message.message.any { it.type == ArrayMessageType.face && it.data.id.toString() == "419" }) { // if (message.message.any { it.type == ArrayMessageType.face && it.data.id.toString() == "419" }) {
message.reply("你发牛魔的火车呢, 我直接就是打断") // message.reply("你发牛魔的火车呢, 我直接就是打断")
} // }
if (message.rawMessage.contains("原神")) { // if (message.text.contains("原神")) {
(0..10).forEach { _ -> // (0..10).forEach { _ -> message.reaction(QQFace.entries.random()) }
message.reaction(QQFace.entries.random()) // message.reply("你原神牛魔呢")
} // delay(1500L)
message.reply("你原神牛魔呢") // message.reply("但是话又说回来.....启动!!")
} // }
GitHubParseCommand.parse(message) GitHubParseCommand.parse(message)
ReverseGIFCommand.callback(message) ReverseGIFCommand.callback(message)
AsciiArtCommand.callback(message) AsciiArtCommand.callback(message)
ScanQRCodeCommand.callback(message) ScanQRCodeCommand.callback(message)
BiliVideoParseCommand.parse(this, message) BiliVideoParseCommand.parse(message)
BiliUserParseCommand.parse(this, message) BiliUserParseCommand.parse(message)
DouyinVideoParseCommand.parse(message) DouyinVideoParseCommand.parse(message)
YoutubeVideoParseCommand.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) val calculateResult = CalculateCommand.parse(message.rawMessage)
calculateResult?.let { message.reply(calculateResult) } 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 }) { 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 replyId = message.message.find { it.type == ArrayMessageType.reply }!!.data.id!!
val getMsg = this.getMessage(replyId.toString().toLong()) val getMsg = message.action.getMessage(replyId.toString().toLong())
val plainTextContent = getMsg.message val plainTextContent = getMsg.text
.filter { it.type == ArrayMessageType.text } when (command) {
.joinToString { it.data.text!! } "/倒放", "/df" -> ReverseGIFCommand.reverse(message, getMsg)
if (command.contains("倒放") || command.contains("/df")) { "/图来", "/图链" -> ImageURLCommand.callback(message, getMsg)
// 使用回复消息的方式对一个gif倒放 "/图床" -> ImageBedCommand.execute(getMsg, message)
ReverseGIFCommand.reverse(message, getMsg) "/reaction" -> ReactionCommand.reaction(message.action, message.groupId, getMsg.messageId)
} "/sl", "/short" -> message.reply(plainTextContent.trim().makeShortLink())
if (command.contains("/sl") || command.contains("/short")) { "/rc", "/随机颜色" -> RandomRGBCommand.random(message, getMsg)
// 使用回复消息的方式快速对一个url消息创建一个短链接 "/颜色反转", "/iv" -> InvertImageCommand.invert(message, getMsg)
message.reply(plainTextContent.trim().makeShortLink()) "/ascii", "/asc" -> {
}
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 url = AsciiArtCommand.getImageUrl(getMsg) val url = AsciiArtCommand.getImageUrl(getMsg)
val image = AsciiArtCommand.generateAsciiArt(url) val image = AsciiArtCommand.generateAsciiArt(url)
message.reply(image) message.reply(image)
} }
if (command.contains("图来") || command.contains("图链")) {
// 获取一个或多个图片的链接, 并且生成一个或多个短链接 "/pb", "/pastebin" -> {
ImageURLCommand.callback(message, getMsg) 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 { 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 { message.message.forEach {
if (it.type == ArrayMessageType.image) { if (it.type == ArrayMessageType.image) {
val filename = it.data.file!!.split("=").last() + ".png" val filename = it.data.file!!.split("=").last() + ".png"
@@ -139,14 +218,14 @@ class FancyBot : OneBotListener {
.addNewLine() .addNewLine()
.addText("使用/revoke ${message.messageId} 来获取被撤回的消息") .addText("使用/revoke ${message.messageId} 来获取被撤回的消息")
.build() .build()
this.sendGroupMessage(message.groupId, msg) message.action.sendGroupMessage(message.groupId, msg)
} }
override suspend fun onWebsocketErrorEvent(ex: Exception) { override suspend fun onWebsocketErrorEvent(event: ErrorEvent) {
ex.printStackTrace() event.exception.printStackTrace()
} }
override suspend fun onAddFriendRequest(event: AddFriendRequest) { override suspend fun onAddFriendRequest(event: AddFriendRequestEvent) {
event.approve() event.approve()
} }
@@ -154,32 +233,45 @@ class FancyBot : OneBotListener {
event.saveTo("$ROOT_PATH/caches/") 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() val msg = MessageChain.Builder()
.addText("有人坐飞船离开了本星系~") .addText("有人坐飞船离开了本星系~(主动退出)")
.addNewLine() .addNewLine()
.addText("QQ: $userId | 操作者: ${if (operator == 0L) "主动退出" else operator}") .addText("QQ: $nickname(${event.userId})")
.addNewLine() .addNewLine()
.addText("下次再见吧~~~") .addText("下次再见吧~~~")
.build() .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) { override suspend fun onGroupPoke(event: PokeEvent) {
if (event.targetId == configManager.selfId) { if (event.targetId == configManager.selfId) {
val msg = MessageChain.Builder() val msg = MessageChain.Builder()
.addAt(event.userId) .addAt(event.userId)
.addText("${event.action.first()}牛魔呢") .addText("${event.pokeAction.first()}牛魔呢")
.build() .build()
this.sendGroupMessage(event.groupId!!, msg) event.action.sendGroupMessage(event.groupId!!, msg)
} }
} }
override suspend fun onBeKicked(groupId: Long, operator: Long, time: Long) { override suspend fun onBeKicked(event: BeKickEvent) {
blackListManager.insertGroup(groupId, operator, time) blackListManager.insertGroup(event.groupId, event.operator, event.time)
this.sendPrivateMessage( event.action.sendPrivateMessage(
configManager.noticeUser, configManager.noticeUser,
"被: ${groupId}踢出! 操作人: $operator 时间: ${time.convertToDate()} 已将其拉入黑名单!" "被: ${event.groupId}踢出! 操作人: ${event.operator} 时间: ${event.time.convertToDate()} 已将其拉入黑名单!"
) )
} }
} }
@@ -188,19 +280,15 @@ suspend fun main() {
val fancyBot = FancyBot() val fancyBot = FancyBot()
val workType = configManager.wsType val workType = configManager.wsType
val accessToken = configManager.accessToken val accessToken = configManager.accessToken
val rob = if (workType == WSType.Client) { val instance = when (workType) {
val address = configManager.wsAddress WSType.Client -> ROneBotFactory.createClient(configManager.wsAddress, accessToken, fancyBot)
ROneBotFactory.createClient(address, accessToken, fancyBot) WSType.Server -> ROneBotFactory.createServer(configManager.wsPort, accessToken, fancyBot)
.also { it.addListeningGroups(*configManager.listeningGroups.toLongArray()) }
} else {
val port = configManager.wsPort
ROneBotFactory.createServer(port, accessToken, fancyBot)
.also { it.addListeningGroups(*configManager.listeningGroups.toLongArray()) }
} }
instance.addListeningGroups(*configManager.listeningGroups.toLongArray())
initDatabase() initDatabase()
initFilesDir() initFilesDir()
initCommand(rob) initCommand()
initSetuIndex() initSetuIndex()
initItems() initItems()
initBackgroundTasks(rob) initBackgroundTasks(instance)
} }
@@ -9,15 +9,14 @@ package cn.rtast.fancybot.commands
import cn.rtast.fancybot.annotations.CommandDescription import cn.rtast.fancybot.annotations.CommandDescription
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("关于") @CommandDescription("关于")
class AboutCommand : BaseCommand() { class AboutCommand : BaseCommand() {
override val commandNames = listOf("/about", "/关于") 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() val msg = MessageChain.Builder()
.addText("Bot名称: FancyBot") .addText("Bot名称: FancyBot")
.addNewLine() .addNewLine()
@@ -8,20 +8,18 @@
package cn.rtast.fancybot.commands package cn.rtast.fancybot.commands
import cn.rtast.fancybot.annotations.CommandDescription import cn.rtast.fancybot.annotations.CommandDescription
import cn.rtast.fancybot.configManager
import cn.rtast.fancybot.enums.CommandAction import cn.rtast.fancybot.enums.CommandAction
import cn.rtast.fancybot.util.file.insertActionRecord import cn.rtast.fancybot.util.file.insertActionRecord
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.util.BaseCommand import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("Echo") @CommandDescription("Echo")
class EchoCommand : BaseCommand() { class EchoCommand : BaseCommand() {
override val commandNames = listOf("/echo") 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) { if (message.sender.isAdmin || message.sender.isOwner) {
listener.sendGroupMessage(message.groupId, args.joinToString(" ")) message.reply(args.joinToString(" "))
insertActionRecord(CommandAction.Echo, message.sender.userId) insertActionRecord(CommandAction.Echo, message.sender.userId)
} else { } else {
message.reply("你不许用echo") message.reply("你不许用echo")
@@ -33,11 +31,11 @@ class EchoCommand : BaseCommand() {
class ShuffleEchoCommand : BaseCommand() { class ShuffleEchoCommand : BaseCommand() {
override val commandNames = listOf("/secho", "/se") 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) { if (message.sender.isAdmin || message.sender.isOwner) {
message.reply(message.rawMessage.toList().shuffled().joinToString("")) message.reply(message.rawMessage.toList().shuffled().joinToString(""))
insertActionRecord(CommandAction.Echo, message.sender.userId) insertActionRecord(CommandAction.Echo, message.sender.userId)
} else{ } else {
message.reply("你不许用echo") message.reply("你不许用echo")
} }
} }
@@ -11,10 +11,9 @@ import cn.rtast.fancybot.annotations.CommandDescription
import cn.rtast.fancybot.commands import cn.rtast.fancybot.commands
import cn.rtast.fancybot.configManager import cn.rtast.fancybot.configManager
import cn.rtast.rob.entity.GroupMessage 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.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.findAnnotation
import kotlin.reflect.full.hasAnnotation import kotlin.reflect.full.hasAnnotation
@@ -22,7 +21,7 @@ import kotlin.reflect.full.hasAnnotation
class HelpCommand : BaseCommand() { class HelpCommand : BaseCommand() {
override val commandNames = listOf("/help", "/帮助") 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()) { if (args.isEmpty()) {
val node = NodeMessageChain.Builder() val node = NodeMessageChain.Builder()
val msg = MessageChain.Builder() val msg = MessageChain.Builder()
@@ -34,6 +33,10 @@ class HelpCommand : BaseCommand() {
msg.addText("[$commandName] [$description] 命令: $commandNames").addNewLine() msg.addText("[$commandName] [$description] 命令: $commandNames").addNewLine()
} }
msg.addText("共计${commands.size}条命令") msg.addText("共计${commands.size}条命令")
node.addMessageChain(
MessageChain.Builder().addText("你可以使用`/help <指令>`来获取这个指令的帮助信息").build(),
configManager.selfId
)
node.addMessageChain(msg.build(), configManager.selfId) node.addMessageChain(msg.build(), configManager.selfId)
message.reply(node.build()) message.reply(node.build())
} else { } else {
@@ -12,16 +12,15 @@ import cn.rtast.fancybot.annotations.CommandDescription
import cn.rtast.fancybot.enums.CommandAction import cn.rtast.fancybot.enums.CommandAction
import cn.rtast.fancybot.util.file.insertActionRecord import cn.rtast.fancybot.util.file.insertActionRecord
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
import java.time.Instant import java.time.Instant
@CommandDescription("状态") @CommandDescription("状态")
class StatusCommand : BaseCommand() { class StatusCommand : BaseCommand() {
override val commandNames = listOf("/status") 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 runtime = Runtime.getRuntime()
val maxMemory = runtime.maxMemory() / (1024 * 1024) val maxMemory = runtime.maxMemory() / (1024 * 1024)
val allocatedMemory = runtime.totalMemory() / (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.annotations.CommandDescription
import cn.rtast.fancybot.util.str.encodeToBase64 import cn.rtast.fancybot.util.str.encodeToBase64
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
import java.net.URI import java.net.URI
@CommandDescription("给我打钱!") @CommandDescription("给我打钱!")
class SupportMeCommand : BaseCommand() { class SupportMeCommand : BaseCommand() {
override val commandNames = listOf("打钱", "给我打钱", "给满子打钱") override val commandNames = listOf("打钱", "给我打钱", "给满子打钱")
override suspend fun executeGroup( override suspend fun executeGroup(message: GroupMessage, args: List<String>, matchedCommand: String) {
listener: OneBotListener,
message: GroupMessage,
args: List<String>,
matchedCommand: String
) {
if (matchedCommand == "给满子打钱") { if (matchedCommand == "给满子打钱") {
message.reply("你打牛魔呢?") message.reply("你打牛魔呢?")
return return
@@ -18,10 +18,9 @@ import cn.rtast.fancybot.util.Http
import cn.rtast.fancybot.util.file.insertActionRecord import cn.rtast.fancybot.util.file.insertActionRecord
import cn.rtast.fancybot.util.str.toJson import cn.rtast.fancybot.util.str.toJson
import cn.rtast.rob.entity.GroupMessage 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.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)") @CommandDescription("问AI(GPT)")
class AICommand : BaseCommand() { class AICommand : BaseCommand() {
@@ -29,7 +28,7 @@ class AICommand : BaseCommand() {
private val openAIModel = configManager.openAIModel 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()) { if (args.isEmpty()) {
val msg = MessageChain.Builder() val msg = MessageChain.Builder()
.addText("发送`/ai [模型] <问题>`即可询问AI哦~") .addText("发送`/ai [模型] <问题>`即可询问AI哦~")
@@ -69,7 +68,7 @@ class AICommand : BaseCommand() {
.addText(response.choices.first().message.content) .addText(response.choices.first().message.content)
.build() .build()
nodeMsg.addMessageChain(msg, configManager.selfId) 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") insertActionRecord(CommandAction.AI, message.sender.userId, "$content-$model-GPT")
} }
} }
@@ -81,7 +80,7 @@ class LlamaCommand : BaseCommand() {
private val llamaURL = configManager.llamaUrl private val llamaURL = configManager.llamaUrl
private val llamaModel = configManager.llamaModel 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()) { if (args.isEmpty()) {
message.reply("发送`/llama <问题>`即可使用llama模型来回复") message.reply("发送`/llama <问题>`即可使用llama模型来回复")
return return
@@ -96,7 +95,7 @@ class LlamaCommand : BaseCommand() {
.addText(response.message.content) .addText(response.message.content)
.build() .build()
nodeMsg.addMessageChain(msg, configManager.selfId) 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") 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.Http
import cn.rtast.fancybot.util.str.encodeToBase64 import cn.rtast.fancybot.util.str.encodeToBase64
import cn.rtast.rob.entity.GroupMessage 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.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.OkHttpClient
import okhttp3.Request 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()) { if (args.isEmpty()) {
message.reply("发送`/dm <关键词>`即可搜索番剧啦~") message.reply("发送`/dm <关键词>`即可搜索番剧啦~")
return return
@@ -58,7 +57,7 @@ class AnimeSearchCommand : BaseCommand() {
} }
val footerNode = MessageChain.Builder().addText("数据来源: Bangumi").build() val footerNode = MessageChain.Builder().addText("数据来源: Bangumi").build()
nodeMsg.addMessageChain(footerNode, configManager.selfId) nodeMsg.addMessageChain(footerNode, configManager.selfId)
listener.sendGroupForwardMsg(message.groupId, nodeMsg.build()) message.action.sendGroupForwardMsg(message.groupId, nodeMsg.build())
} catch (_: Exception) { } catch (_: Exception) {
message.reply("没有搜索到结果呢~") message.reply("没有搜索到结果呢~")
} }
@@ -13,10 +13,9 @@ import cn.rtast.fancybot.entity.cigarette.Cigarette
import cn.rtast.fancybot.util.Http import cn.rtast.fancybot.util.Http
import cn.rtast.fancybot.util.str.encodeToBase64 import cn.rtast.fancybot.util.str.encodeToBase64
import cn.rtast.rob.entity.GroupMessage 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.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 import java.net.URI
@CommandDescription("查询香烟价格") @CommandDescription("查询香烟价格")
@@ -25,7 +24,7 @@ class CigaretteCommand : BaseCommand() {
private val apiUrl = "https://www.yanyue.cn/api/rc/product/yanlist" 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()) { if (args.isEmpty()) {
val msg = MessageChain.Builder() val msg = MessageChain.Builder()
.addText("发送/tobacco <名称> [数量] 来搜索结果哦~") .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.encodeToBase64
import cn.rtast.fancybot.util.str.toJson import cn.rtast.fancybot.util.str.toJson
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand 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.Color
import java.awt.Font import java.awt.Font
import java.awt.image.BufferedImage import java.awt.image.BufferedImage
@@ -61,7 +60,7 @@ class DomainPriceCommand : BaseCommand() {
domain: String, domain: String,
available: Boolean, available: Boolean,
premium: Boolean, premium: Boolean,
domainPrice: Pair<Int, Int> domainPrice: Pair<Int, Int>,
): String { ): String {
val canvas = this.createCommonCanvas() val canvas = this.createCommonCanvas()
val g2d = canvas.createGraphics() 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()) { if (args.isEmpty()) {
val msg = MessageChain.Builder() val msg = MessageChain.Builder()
.addText("发送`/domain <域名>`即可查询对应的注册和续费价格~") .addText("发送`/domain <域名>`即可查询对应的注册和续费价格~")
@@ -14,9 +14,8 @@ import cn.rtast.fancybot.entity.github.LatestCommit
import cn.rtast.fancybot.util.Http import cn.rtast.fancybot.util.Http
import cn.rtast.fancybot.util.str.fromArrayJson import cn.rtast.fancybot.util.str.fromArrayJson
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("查询Github上的仓库的最新一次的提交信息") @CommandDescription("查询Github上的仓库的最新一次的提交信息")
class GithubLatestCommitCommand : BaseCommand() { class GithubLatestCommitCommand : BaseCommand() {
@@ -24,7 +23,7 @@ class GithubLatestCommitCommand : BaseCommand() {
private val userInfoUrl = "https://api.github.com/repos" 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()) { if (args.isEmpty()) {
message.reply("发送`.commit <用户名/仓库名>`即可查询仓库最新一次的提交信息") 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.misc.toByteArray
import cn.rtast.fancybot.util.str.encodeToBase64 import cn.rtast.fancybot.util.str.encodeToBase64
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand 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.Color
import java.awt.Font import java.awt.Font
import java.awt.image.BufferedImage import java.awt.image.BufferedImage
@@ -67,7 +66,7 @@ class GithubUserCommand : BaseCommand() {
return canvas.toByteArray().encodeToBase64() 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()) { if (args.isEmpty()) {
val msg = MessageChain.Builder().addText("发送`gh <用户名>`即可查询用户的信息~").build() val msg = MessageChain.Builder().addText("发送`gh <用户名>`即可查询用户的信息~").build()
message.reply(msg) 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.encodeToBase64
import cn.rtast.fancybot.util.str.getMD5 import cn.rtast.fancybot.util.str.getMD5
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("查询用户的Gravatar头像") @CommandDescription("查询用户的Gravatar头像")
class GravatarCommand : BaseCommand() { class GravatarCommand : BaseCommand() {
@@ -24,7 +23,7 @@ class GravatarCommand : BaseCommand() {
private const val GRAVATAR_URL = "https://gravatar.rtast.cn/avatar" 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() val emailMD5 = if (args.first().trim().lowercase().contains("@")) args.first().trim().lowercase().getMD5()
else args.first().trim().lowercase() else args.first().trim().lowercase()
val avatarImage = "$GRAVATAR_URL/$emailMD5?size=256".toURL().readBytes().encodeToBase64() 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.entity.apispace.IdiomExplainResponse
import cn.rtast.fancybot.util.Http import cn.rtast.fancybot.util.Http
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("解释一个成语") @CommandDescription("解释一个成语")
class IdiomExplainCommand : BaseCommand() { class IdiomExplainCommand : BaseCommand() {
@@ -22,7 +21,7 @@ class IdiomExplainCommand : BaseCommand() {
private val apiSpaceUrl = "https://eolink.o.apispace.com/cyudac/api/v1/idioms/SearchIdiomsByPinyin/search" 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()) { if (args.isEmpty()) {
message.reply("发送`成语解释 <成语>`就能解释这个成语的意思了") message.reply("发送`成语解释 <成语>`就能解释这个成语的意思了")
return return
@@ -16,9 +16,8 @@ import cn.rtast.fancybot.entity.music.qq.QQMSearch
import cn.rtast.fancybot.util.Http import cn.rtast.fancybot.util.Http
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.enums.MusicShareType import cn.rtast.rob.enums.MusicShareType
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
import java.time.Instant import java.time.Instant
@CommandDescription("网易云音乐点歌") @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()) { if (args.isEmpty()) {
message.reply("发送`/点歌` <关键词> 来搜索音乐~") message.reply("发送`/点歌` <关键词> 来搜索音乐~")
return return
@@ -63,7 +62,7 @@ class MusicCommand : BaseCommand() {
val msg = MessageChain.Builder() val msg = MessageChain.Builder()
.addMusicShare(MusicShareType.Netease, finalResult.id.toString()) .addMusicShare(MusicShareType.Netease, finalResult.id.toString())
.build() .build()
listener.sendGroupMessage(message.groupId, msg) message.reply(msg)
} catch (_: Exception) { } catch (_: Exception) {
message.reply("输入有误请重新搜索本次搜索结果已清除") 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") { if (args.last() == "legacy" || args.last() == "l" || args.last() in "0".."4") {
this.legacyMusicCommand(listener, message, args) this.legacyMusicCommand(message, args)
return return
} }
if (args.isEmpty()) { if (args.isEmpty()) {
@@ -105,7 +104,7 @@ class MusicCommand : BaseCommand() {
.addNewLine() .addNewLine()
.addText("发送`点歌 <歌名> [l|legacy]`即可使用旧版点歌系统") .addText("发送`点歌 <歌名> [l|legacy]`即可使用旧版点歌系统")
.build() .build()
listener.sendGroupMessage(message.groupId, msg) message.reply(msg)
return return
} }
@@ -114,7 +113,7 @@ class MusicCommand : BaseCommand() {
val msg = MessageChain.Builder() val msg = MessageChain.Builder()
.addMusicShare(MusicShareType.Netease, result.toString()) .addMusicShare(MusicShareType.Netease, result.toString())
.build() .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 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 url = if (args.last() == "id" || args.last() == "i") {
val id = args.first() val id = args.first()
this.getPlayUrl(id) this.getPlayUrl(id)
@@ -141,7 +140,7 @@ class MusicPlayUrlCommand : BaseCommand() {
.addReply(message.messageId) .addReply(message.messageId)
.addText(url) .addText(url)
.build() .build()
listener.sendGroupMessage(message.groupId, msg) message.reply(msg)
} }
} }
@@ -151,7 +150,7 @@ class QQMusicCommand : BaseCommand() {
private val qqMusicApiUrl = configManager.qqMusicApiUrl 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()) { if (args.isEmpty()) {
message.reply("发送`/qm <关键词>`即可搜索qq音乐的音乐哦") message.reply("发送`/qm <关键词>`即可搜索qq音乐的音乐哦")
return return
@@ -162,6 +161,6 @@ class QQMusicCommand : BaseCommand() {
mapOf("key" to keyword) mapOf("key" to keyword)
).response.data.song.list.first().songId ).response.data.song.list.first().songId
val msg = MessageChain.Builder().addMusicShare(MusicShareType.QQ, response.toString()).build() 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.Http
import cn.rtast.fancybot.util.str.encodeToBase64 import cn.rtast.fancybot.util.str.encodeToBase64
import cn.rtast.rob.entity.GroupMessage 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.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 import java.net.URI
@CommandDescription("获取Pixiv上的图片") @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 pixivRankingURL = "https://proxy.rtast.cn/https/www.pixiv.net/ranking.php?format=json&mode=daily&p=1"
private val imageProxyURL = "https://pixiv.re" 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()) { if (args.isEmpty()) {
val msg = MessageChain.Builder() val msg = MessageChain.Builder()
.addText("发送`/pixiv <id> | rank` 来进行操作哦~") .addText("发送`/pixiv <id> | rank` 来进行操作哦~")
@@ -10,10 +10,9 @@ package cn.rtast.fancybot.commands.lookup
import cn.rtast.fancybot.annotations.CommandDescription import cn.rtast.fancybot.annotations.CommandDescription
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.enums.ArrayMessageType 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.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 { 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() { class ShotSelfCommand : BaseCommand() {
override val commandNames = listOf("骂我") override val commandNames = listOf("骂我")
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) { override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
listener.sendGroupForwardMsg(message.groupId, generateNodeMessage(message.sender.userId.toString())) message.action.sendGroupForwardMsg(message.groupId, generateNodeMessage(message.sender.userId.toString()))
} }
} }
@@ -38,14 +37,16 @@ class ShotSelfCommand : BaseCommand() {
class ShotOtherCommand : BaseCommand() { class ShotOtherCommand : BaseCommand() {
override val commandNames = listOf("") 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()) { 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 return
} }
var times = if (args.size == 1) 10 else if (args.last() == "") 10 else args.last().toInt() var times = if (args.size == 1) 10 else if (args.last() == "") 10 else args.last().toInt()
if (times >= 200) times = 10 if (times >= 200) times = 10
val target = message.message.find { it.type == ArrayMessageType.at }?.data!! 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.fromArrayJson
import cn.rtast.fancybot.util.str.proxy import cn.rtast.fancybot.util.str.proxy
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("随机猫猫图") @CommandDescription("随机猫猫图")
class TheCatCommand : BaseCommand() { class TheCatCommand : BaseCommand() {
@@ -25,7 +24,7 @@ class TheCatCommand : BaseCommand() {
private val theCatApiUrl = "https://api.thecatapi.com/v1/images/search" 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) val imageBase64 = Http.get(theCatApiUrl)
.fromArrayJson<List<Cat>>().first().url .fromArrayJson<List<Cat>>().first().url
.proxy.toURL().readBytes().encodeToBase64() .proxy.toURL().readBytes().encodeToBase64()
@@ -12,10 +12,9 @@ import cn.rtast.fancybot.configManager
import cn.rtast.fancybot.entity.tianxing.HistoryOfToday import cn.rtast.fancybot.entity.tianxing.HistoryOfToday
import cn.rtast.fancybot.util.Http import cn.rtast.fancybot.util.Http
import cn.rtast.rob.entity.GroupMessage 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.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.LocalDateTime
import java.time.ZoneId import java.time.ZoneId
import java.time.format.DateTimeFormatter import java.time.format.DateTimeFormatter
@@ -27,7 +26,7 @@ class TheHistoryOfTodayCommand : BaseCommand() {
private val tianXingApiUrl = "https://apis.tianapi.com/lishi/index" private val tianXingApiUrl = "https://apis.tianapi.com/lishi/index"
private val tianXingApiKey = configManager.tianXingApiKey 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 currentDateTime = LocalDateTime.now(ZoneId.of("Asia/Shanghai"))
val formatter = DateTimeFormatter.ofPattern("MMdd") val formatter = DateTimeFormatter.ofPattern("MMdd")
val currentDate = currentDateTime.format(formatter) val currentDate = currentDateTime.format(formatter)
@@ -47,6 +46,6 @@ class TheHistoryOfTodayCommand : BaseCommand() {
.build() .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.misc.toByteArray
import cn.rtast.fancybot.util.str.encodeToBase64 import cn.rtast.fancybot.util.str.encodeToBase64
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand 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.Color
import java.awt.Font import java.awt.Font
import java.awt.image.BufferedImage import java.awt.image.BufferedImage
@@ -58,13 +57,13 @@ class WeatherCommand : BaseCommand() {
return emptyImage.toByteArray().encodeToBase64() 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()) { if (args.isEmpty()) {
val msg = MessageChain.Builder() val msg = MessageChain.Builder()
.addAt(message.sender.userId) .addAt(message.sender.userId)
.addText("发送/weather <地区名>即可查看实时天气哦~") .addText("发送/weather <地区名>即可查看实时天气哦~")
.build() .build()
listener.sendGroupMessage(message.groupId, msg) message.reply(msg)
return return
} }
try { try {
@@ -81,13 +80,13 @@ class WeatherCommand : BaseCommand() {
.addReply(message.messageId) .addReply(message.messageId)
.addImage(this.createWeatherCard(weather, lookupLocation), true) .addImage(this.createWeatherCard(weather, lookupLocation), true)
.build() .build()
listener.sendGroupMessage(message.groupId, msg) message.reply(msg)
} catch (_: NullPointerException) { } catch (_: NullPointerException) {
val msg = MessageChain.Builder() val msg = MessageChain.Builder()
.addAt(message.sender.userId) .addAt(message.sender.userId)
.addText("没有查询到该城市的天气信息哦~") .addText("没有查询到该城市的天气信息哦~")
.build() .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.Http
import cn.rtast.fancybot.util.file.insertActionRecord import cn.rtast.fancybot.util.file.insertActionRecord
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
import org.jsoup.Jsoup import org.jsoup.Jsoup
@CommandDescription("查询wiki百科") @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()) { if (args.isEmpty()) {
val msg = MessageChain.Builder() val msg = MessageChain.Builder()
.addText("发送`/wiki <关键字>`即可查询出最匹配的wiki页面~") .addText("发送`/wiki <关键字>`即可查询出最匹配的wiki页面~")
@@ -14,21 +14,20 @@ import cn.rtast.rob.entity.ArrayMessage
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.enums.ArrayMessageType import cn.rtast.rob.enums.ArrayMessageType
import cn.rtast.rob.util.BaseCommand import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("防撤回(获取消息)") @CommandDescription("防撤回(获取消息)")
class AntiRevokeCommand : BaseCommand() { class AntiRevokeCommand : BaseCommand() {
override val commandNames = listOf("/revoke", "/rv") 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) { if (message.sender.isAdmin || message.sender.isOwner) {
val messageId = args.first().toLong() val messageId = args.first().toLong()
val getMsg = listener.getMessage(messageId) val getMsg = message.action.getMessage(messageId)
val msgList = mutableListOf<ArrayMessage>() val msgList = mutableListOf<ArrayMessage>()
msgList.add(ArrayMessage(ArrayMessageType.at, ArrayMessage.Data(qq = message.sender.userId.toString()))) msgList.add(ArrayMessage(ArrayMessageType.at, ArrayMessage.Data(qq = message.sender.userId.toString())))
msgList.add(ArrayMessage(ArrayMessageType.text, ArrayMessage.Data(text = "\n被撤回的消息如下: \n"))) msgList.add(ArrayMessage(ArrayMessageType.text, ArrayMessage.Data(text = "\n被撤回的消息如下: \n")))
msgList.addAll(getMsg.message) msgList.addAll(getMsg.message)
listener.sendGroupMessage(message.groupId, msgList) message.action.sendGroupMessage(message.groupId, msgList)
insertActionRecord(CommandAction.AntiRevoke, message.sender.userId, getMsg.messageId.toString()) insertActionRecord(CommandAction.AntiRevoke, message.sender.userId, getMsg.messageId.toString())
} else { } else {
message.reply("你不许用防撤回") 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.misc.Resources
import cn.rtast.fancybot.util.str.fromJson import cn.rtast.fancybot.util.str.fromJson
import cn.rtast.rob.entity.GroupMessage 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.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 import kotlin.random.Random
@CommandDescription("狗屁不通文章生成器") @CommandDescription("狗屁不通文章生成器")
@@ -47,7 +46,7 @@ class BullShitGenerateCommand : BaseCommand() {
return ".\n\n " 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 topic = args.joinToString(" ")
val nextFamousQuote = shuffleList(bullShitData.famous) val nextFamousQuote = shuffleList(bullShitData.famous)
val nextBosh = shuffleList(bullShitData.bosh) 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.file.insertActionRecord
import cn.rtast.fancybot.util.str.toJson import cn.rtast.fancybot.util.str.toJson
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("执行不同语言的代码") @CommandDescription("执行不同语言的代码")
class CompilerCommand : BaseCommand() { 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 kotlinCompilerServer = "https://api.kotlinlang.org/api/2.0.20/compiler/run"
private val glotCompilerServer = "https://glot.io/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()) { if (args.isEmpty()) {
message.reply("使用`/exec` <语言> <代码> 即可执行~") message.reply("使用`/exec` <语言> <代码> 即可执行~")
return return
@@ -63,7 +62,7 @@ class CompilerCommand : BaseCommand() {
.addNewLine() .addNewLine()
.addText(response.replace("<outStream>", "").replace("</outStream>", "")) .addText(response.replace("<outStream>", "").replace("</outStream>", ""))
.build() .build()
listener.sendGroupMessage(message.groupId, msg) message.reply(msg)
} catch (e: Exception) { } catch (e: Exception) {
message.reply("执行错误: ${e.message}") message.reply("执行错误: ${e.message}")
} finally { } finally {
@@ -10,7 +10,6 @@ package cn.rtast.fancybot.commands.misc
import cn.rtast.fancybot.annotations.CommandDescription import cn.rtast.fancybot.annotations.CommandDescription
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.util.BaseCommand import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.OneBotListener
import java.time.LocalDate import java.time.LocalDate
import java.time.temporal.ChronoUnit import java.time.temporal.ChronoUnit
@@ -18,7 +17,7 @@ import java.time.temporal.ChronoUnit
class GaoKaoDaysRemainCommand : BaseCommand() { class GaoKaoDaysRemainCommand : BaseCommand() {
override val commandNames = listOf("高考倒计时") 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 gaoKaoDate = LocalDate.of(LocalDate.now().year, 6, 7)
val currentDate = LocalDate.now() val currentDate = LocalDate.now()
val adjustedGaoKaoDate = if (currentDate.isAfter(gaoKaoDate)) gaoKaoDate.plusYears(1) else gaoKaoDate 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.misc.Resources
import cn.rtast.fancybot.util.str.encodeToBase64 import cn.rtast.fancybot.util.str.encodeToBase64
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("随机HTTP猫猫") @CommandDescription("随机HTTP猫猫")
class HTTPCatCommand : BaseCommand() { class HTTPCatCommand : BaseCommand() {
@@ -26,7 +25,7 @@ class HTTPCatCommand : BaseCommand() {
return Resources.loadFromResourcesAsBytes("httpcat/${code}.jpg")?.encodeToBase64() ?: notFoundCatBase64 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 statusCode = if (args.isEmpty()) HttpStatusCode.entries.random().code.toString() else args.first()
val image = loadHTTPCat(statusCode) val image = loadHTTPCat(statusCode)
val msg = MessageChain.Builder().addImage(image, true).build() 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.misc.Resources
import cn.rtast.fancybot.util.str.encodeToBase64 import cn.rtast.fancybot.util.str.encodeToBase64
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("随机HTTP狗狗") @CommandDescription("随机HTTP狗狗")
class HTTPDogCommand : BaseCommand() { class HTTPDogCommand : BaseCommand() {
@@ -26,7 +25,7 @@ class HTTPDogCommand : BaseCommand() {
return Resources.loadFromResourcesAsBytes("httpdog/${code}.jpg")?.encodeToBase64() ?: notFoundCatBase64 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 statusCode = if (args.isEmpty()) HttpStatusCode.entries.random().code.toString() else args.first()
val image = loadHTTPDog(statusCode) val image = loadHTTPDog(statusCode)
val msg = MessageChain.Builder().addImage(image, true).build() 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.entity.Hitokoto
import cn.rtast.fancybot.util.Http import cn.rtast.fancybot.util.Http
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("一言") @CommandDescription("一言")
class HitokotoCommand : BaseCommand() { class HitokotoCommand : BaseCommand() {
override val commandNames = listOf("/1") 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 response = Http.get<Hitokoto>("https://v1.hitokoto.cn/?c=b")
val msg = MessageChain.Builder() val msg = MessageChain.Builder()
.addText("${response.sentence}⌉ ---《${response.from}") .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.annotations.CommandDescription
import cn.rtast.fancybot.util.file.JrrpManager import cn.rtast.fancybot.util.file.JrrpManager
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("今日人品~") @CommandDescription("今日人品~")
class JrrpCommand : BaseCommand() { class JrrpCommand : BaseCommand() {
@@ -20,13 +19,13 @@ class JrrpCommand : BaseCommand() {
private val jrrpManager = JrrpManager() 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)) { if (jrrpManager.isJrrped(message.sender.userId)) {
val msg = MessageChain.Builder() val msg = MessageChain.Builder()
.addAt(message.sender.userId) .addAt(message.sender.userId)
.addText("你今天已经今日人品过啦, 明天再来吧~") .addText("你今天已经今日人品过啦, 明天再来吧~")
.build() .build()
listener.sendGroupMessage(message.groupId, msg) message.reply(msg)
return return
} }
val randomPoint = jrrpManager.jrrp(message.sender.userId) val randomPoint = jrrpManager.jrrp(message.sender.userId)
@@ -41,6 +40,6 @@ class JrrpCommand : BaseCommand() {
.addAt(message.sender.userId) .addAt(message.sender.userId)
.addText("$scoreDesc($randomPoint)") .addText("$scoreDesc($randomPoint)")
.build() .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.fancybot.util.str.encodeToBase64
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.enums.ArrayMessageType import cn.rtast.rob.enums.ArrayMessageType
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand 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 com.madgag.gif.fmsware.GifDecoder
import java.awt.image.BufferedImage import java.awt.image.BufferedImage
import java.net.URI import java.net.URI
@@ -26,12 +25,14 @@ import java.net.URI
class JueCommand : BaseCommand() { class JueCommand : BaseCommand() {
override val commandNames = listOf("") 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 { private fun createJueGIF(source: String, target: String): String {
val baseGIF = Resources.loadFromResources("misc/jue.gif") val baseGIF = Resources.loadFromResources("misc/jue.gif")
val sourceAvatar = URI(avatarUrl.replace("#{}", source)).toURL().readBytes().toBufferedImage() val sourceAvatar = URI(AVATAR_REPLACE_URL.replace("#{}", source)).toURL().readBytes().toBufferedImage()
val targetAvatar = URI(avatarUrl.replace("#{}", target)).toURL().readBytes().toBufferedImage() val targetAvatar = URI(AVATAR_REPLACE_URL.replace("#{}", target)).toURL().readBytes().toBufferedImage()
val decoder = GifDecoder() val decoder = GifDecoder()
decoder.read(baseGIF) decoder.read(baseGIF)
val frames = mutableListOf<BufferedImage>() val frames = mutableListOf<BufferedImage>()
@@ -57,11 +58,11 @@ class JueCommand : BaseCommand() {
return gif 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 target = message.message.find { it.type == ArrayMessageType.at }?.data?.qq.toString()
val source = message.sender.userId.toString() val source = message.sender.userId.toString()
val gif = this.createJueGIF(source, target) val gif = this.createJueGIF(source, target)
val msg = MessageChain.Builder().addImage(gif, true).build() 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.fancybot.util.Http
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.util.BaseCommand import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.OneBotListener
import java.time.DayOfWeek import java.time.DayOfWeek
import java.time.Instant import java.time.Instant
import java.time.LocalDateTime 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()) { if (!isThursday()) {
message.reply("很可惜今天并不是星期四~") message.reply("很可惜今天并不是星期四~")
return 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.rcon.exceptions.AuthFailedException
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.entity.PrivateMessage 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.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 okhttp3.FormBody
import java.awt.AlphaComposite import java.awt.AlphaComposite
import java.awt.Color import java.awt.Color
import java.awt.image.BufferedImage import java.awt.image.BufferedImage
import java.net.InetAddress
import java.net.SocketException import java.net.SocketException
import java.net.URI import java.net.URI
import java.util.concurrent.Executors import java.util.concurrent.Executors
@@ -71,7 +71,7 @@ class MCVersionCommand : BaseCommand() {
private val javaEditionAPI = "https://launchermeta.mojang.com/mc/game/version_manifest.json" 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 mcVersion = Http.get<MCVersion>(javaEditionAPI)
val msg = MessageChain.Builder() val msg = MessageChain.Builder()
.addText("最新正式版: ${mcVersion.latest.release}") .addText("最新正式版: ${mcVersion.latest.release}")
@@ -93,13 +93,13 @@ class MinecraftWikiCommand : BaseCommand() {
private val baseApiUrl = "https://zh.minecraft.wiki/rest.php/v1" private val baseApiUrl = "https://zh.minecraft.wiki/rest.php/v1"
private val logger = Logger.getLogger<MinecraftWikiCommand>() 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() val action = args.first()
when (action) { when (action) {
"s", "搜索" -> { "s", "搜索" -> {
val searchKeyword = args.drop(1).joinToString(" ").trim() val searchKeyword = args.drop(1).joinToString(" ").trim()
val messages = mutableListOf<MessageChain>() val messages = mutableListOf<MessageChain>()
val headerMessage = listOf("结果如下:").asMessageChain() val headerMessage = MessageChain.Builder().addText("结果如下:").build()
messages.add(headerMessage) messages.add(headerMessage)
Http.get<MCWikiSearchResponse>( Http.get<MCWikiSearchResponse>(
"$baseApiUrl/search/title", "$baseApiUrl/search/title",
@@ -118,7 +118,7 @@ class MinecraftWikiCommand : BaseCommand() {
.addText("https://zh.minecraft.wiki/w/${it.title.uriEncode}") .addText("https://zh.minecraft.wiki/w/${it.title.uriEncode}")
messages.add(msg.build()) messages.add(msg.build())
} }
message.reply(messages.asNode(configManager.selfId)) message.reply(messages.toNode(configManager.selfId))
} }
else -> { else -> {
@@ -134,18 +134,19 @@ class MinecraftWikiCommand : BaseCommand() {
response = Http.get<MCWikiPageResponse>(response.redirectTarget) response = Http.get<MCWikiPageResponse>(response.redirectTarget)
} }
val messages = mutableListOf<MessageChain>() val messages = mutableListOf<MessageChain>()
val headerMsg = listOf("标题${response.title}的内容如下").asMessageChain() val headerMsg = MessageChain.Builder().addText("标题${response.title}的内容如下").build()
val footerMsg = listOf( val footerMsg = listOf(
"数据来源: https://zh.minecraft.wiki", Text("数据来源: https://zh.minecraft.wiki"),
"协议: ${response.license.title}(${response.license.url})" NewLine(),
).asMessageChain(true) Text("协议: ${response.license.title}(${response.license.url})")
).toMessageChain()
val bodyMsg = MessageChain.Builder() val bodyMsg = MessageChain.Builder()
.addText(response.source.convertToHTML().extractPlainTextFromHtml()) .addText(response.source.convertToHTML().extractPlainTextFromHtml())
.build() .build()
messages.add(headerMsg) messages.add(headerMsg)
messages.add(bodyMsg) messages.add(bodyMsg)
messages.add(footerMsg) 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( private fun findMaxSlimeChunks(
worldSeed: Long, worldSeed: Long,
searchRange: Int, searchRange: Int,
chunkSize: Int chunkSize: Int,
): Pair<Pair<Pair<Int, Int>, Pair<Int, Int>>, Int> { ): Pair<Pair<Pair<Int, Int>, Pair<Int, Int>>, Int> {
var maxCount = 0 var maxCount = 0
var bestStartLocation = Pair(0, 0) var bestStartLocation = Pair(0, 0)
@@ -222,7 +223,7 @@ class SlimeChunkHelperCommand : BaseCommand() {
return image.toByteArray().encodeToBase64() 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()) { if (args.isEmpty()) {
val msg = MessageChain.Builder() val msg = MessageChain.Builder()
.addText("此指令可以借助一个种子来帮助查找最适合史莱姆农场的位置") .addText("此指令可以借助一个种子来帮助查找最适合史莱姆农场的位置")
@@ -300,7 +301,7 @@ class MCSkinCommand : BaseCommand() {
return zoom.toByteArray().encodeToBase64() 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()) { if (args.isEmpty()) {
message.reply("发送`/skin <uuid/游戏名称>`即可查询他的皮肤~ (仅限Java版)") message.reply("发送`/skin <uuid/游戏名称>`即可查询他的皮肤~ (仅限Java版)")
return return
@@ -333,7 +334,7 @@ class MCPingCommand : BaseCommand() {
return this.replace(Regex("§."), "") 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()) { if (args.isEmpty()) {
val msg = MessageChain.Builder() val msg = MessageChain.Builder()
.addText("使用方法: /mcping <host>:[port] [java|be]") .addText("使用方法: /mcping <host>:[port] [java|be]")
@@ -460,7 +461,7 @@ class MCLoginCommand : BaseCommand() {
return response.token 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()) { if (args.isEmpty()) {
message.reply("这个命令可以获取你的MC登录Token发送 `/mclogin login`进行操作吧") message.reply("这个命令可以获取你的MC登录Token发送 `/mclogin login`进行操作吧")
return 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) val token = getAccessTokenById(message.sender.userId)
if (token == null) { if (token == null) {
message.reply("你还没登录呢!") message.reply("你还没登录呢!")
@@ -523,11 +524,11 @@ class MCLoginCommand : BaseCommand() {
class RCONCommand : BaseCommand() { class RCONCommand : BaseCommand() {
override val commandNames = listOf("/rcon", "/r") 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("请在私聊中使用此命令") 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()) { if (args.isEmpty()) {
val msg = MessageChain.Builder() val msg = MessageChain.Builder()
.addText("这条指令用于在群内操作mc服务器") .addText("这条指令用于在群内操作mc服务器")
@@ -550,7 +551,7 @@ class RCONCommand : BaseCommand() {
return return
} }
val messages = mutableListOf<MessageChain>() val messages = mutableListOf<MessageChain>()
.also { it.add(listOf("所有配置如下").asMessageChain()) } .also { it.add(MessageChain.Builder().addText("所有配置如下").build()) }
allRcons.forEach { allRcons.forEach {
val msg = MessageChain.Builder() val msg = MessageChain.Builder()
.addText("名称: ${it.name}") .addText("名称: ${it.name}")
@@ -561,7 +562,7 @@ class RCONCommand : BaseCommand() {
.build() .build()
messages.add(msg) messages.add(msg)
} }
message.reply(messages.asNode(configManager.selfId)) message.reply(messages.toNode(configManager.selfId))
} }
"add" -> { "add" -> {
@@ -593,9 +594,9 @@ class RCONCommand : BaseCommand() {
try { try {
val result = rconManager.executeCommand(message.sender.userId, name, command) val result = rconManager.executeCommand(message.sender.userId, name, command)
val messages = mutableListOf<MessageChain>() val messages = mutableListOf<MessageChain>()
.also { it.add(listOf("执行结果如下").asMessageChain()) } .also { it.add(MessageChain.Builder().addText("执行结果如下").build()) }
.also { it.add(listOf(result).asMessageChain()) } .also { it.add(MessageChain.Builder().addText(result).build()) }
.asNode(configManager.selfId) .toNode(configManager.selfId)
message.reply(messages) message.reply(messages)
} catch (_: AuthFailedException) { } catch (_: AuthFailedException) {
message.reply("执行失败, 密码不正确") message.reply("执行失败, 密码不正确")
@@ -617,7 +618,7 @@ class MCBotCommand : BaseCommand() {
return response.players.max to response.players.online 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 clients = mutableListOf<MCClient>()
val action = args.first() val action = args.first()
when (action) { 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.fancybot.util.str.toJson
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.util.BaseCommand import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("Pastebin!") @CommandDescription("Pastebin!")
class PastebinCommand : BaseCommand() { class PastebinCommand : BaseCommand() {
@@ -32,11 +31,11 @@ class PastebinCommand : BaseCommand() {
"$API_RTAST_URL/api/pastebin", pastebinPayload.toJson(), "$API_RTAST_URL/api/pastebin", pastebinPayload.toJson(),
params = mapOf("key" to configManager.apiRtastKey) 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()) { if (args.isEmpty()) {
message.reply("使用`/pb <内容>`或者回复一个消息`/pb`可以快速创建一个pastebin") message.reply("使用`/pb <内容>`或者回复一个消息`/pb`可以快速创建一个pastebin")
return return
@@ -15,9 +15,8 @@ import cn.rtast.fancybot.util.misc.toByteArray
import cn.rtast.fancybot.util.str.encodeToBase64 import cn.rtast.fancybot.util.str.encodeToBase64
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.enums.ArrayMessageType import cn.rtast.rob.enums.ArrayMessageType
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand 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.BarcodeFormat
import com.google.zxing.BinaryBitmap import com.google.zxing.BinaryBitmap
import com.google.zxing.EncodeHintType import com.google.zxing.EncodeHintType
@@ -40,7 +39,7 @@ class GenerateQRCodeCommand : BaseCommand() {
return MatrixToImageWriter.toBufferedImage(bitMatrix).toByteArray().encodeToBase64() 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()) { if (args.isEmpty()) {
message.reply("发送`/qr <内容>`即可生成一张二维码的图片") message.reply("发送`/qr <内容>`即可生成一张二维码的图片")
return 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) { if (message.sender() !in waitingList) {
waitingList.add(message.sender()) waitingList.add(message.sender())
message.reply("继续发送一张二维码图片") message.reply("继续发送一张二维码图片")
@@ -10,22 +10,21 @@ package cn.rtast.fancybot.commands.misc
import cn.rtast.fancybot.annotations.CommandDescription import cn.rtast.fancybot.annotations.CommandDescription
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.enums.ArrayMessageType import cn.rtast.rob.enums.ArrayMessageType
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("RUA!") @CommandDescription("RUA!")
class RUACommand : BaseCommand() { class RUACommand : BaseCommand() {
override val commandNames = listOf("/rua", "rua") 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()) { if (args.isEmpty()) {
val msg = MessageChain.Builder() val msg = MessageChain.Builder()
.addAt(message.sender.userId) .addAt(message.sender.userId)
.addText("使用rua @xxxx") .addText("使用rua @xxxx")
.addText("即可rua某人啦~") .addText("即可rua某人啦~")
.build() .build()
listener.sendGroupMessage(message.groupId, msg) message.reply(msg)
return return
} }
try { try {
@@ -38,13 +37,13 @@ class RUACommand : BaseCommand() {
.addText(" ") .addText(" ")
.addText("rua了你~") .addText("rua了你~")
.build() .build()
listener.sendGroupMessage(message.groupId, msg) message.reply(msg)
} catch (_: NullPointerException) { } catch (_: NullPointerException) {
val msg = MessageChain.Builder() val msg = MessageChain.Builder()
.addAt(message.sender.userId) .addAt(message.sender.userId)
.addText("要@才有用哦~") .addText("要@才有用哦~")
.build() .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.fancybot.util.Http
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.enums.MusicShareType import cn.rtast.rob.enums.MusicShareType
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("获取随机热榜音乐(网易云)") @CommandDescription("获取随机热榜音乐(网易云)")
class RandomMusicCommand : BaseCommand() { class RandomMusicCommand : BaseCommand() {
@@ -23,11 +22,11 @@ class RandomMusicCommand : BaseCommand() {
private val ncmApiUrl = "${configManager.ncmAPI}/top/song" 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 id = Http.get<TopSong>(ncmApiUrl).data.random().privilege.id
val msg = MessageChain.Builder() val msg = MessageChain.Builder()
.addMusicShare(MusicShareType.Netease, id.toString()) .addMusicShare(MusicShareType.Netease, id.toString())
.build() .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.fancybot.annotations.CommandDescription
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.enums.QQFace import cn.rtast.rob.enums.QQFace
import cn.rtast.rob.onebot.OneBotAction
import cn.rtast.rob.util.BaseCommand import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("让你的消息得到回应(reaction)!") @CommandDescription("让你的消息得到回应(reaction)!")
class ReactionCommand : BaseCommand() { class ReactionCommand : BaseCommand() {
override val commandNames = listOf("reaction", "回应") override val commandNames = listOf("reaction", "回应")
companion object { companion object {
suspend fun reaction(listener: OneBotListener, message: GroupMessage, messageId: Long, limit: Int = 30) { suspend fun reaction(action: OneBotAction, groupId: Long, messageId: Long, limit: Int = 30) {
(0..limit - 1).forEach { (0..limit - 1).forEach { action.reaction(groupId, messageId, QQFace.entries.random().id.toString()) }
listener.reaction(
message.groupId,
messageId,
QQFace.entries.random().id.toString()
)
}
} }
} }
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) = override suspend fun executeGroup(message: GroupMessage, args: List<String>) =
reaction(listener, message, message.messageId) 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.enums.CountryList
import cn.rtast.fancybot.util.misc.randomBooleanWithProbability import cn.rtast.fancybot.util.misc.randomBooleanWithProbability
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("人生重开模拟器") @CommandDescription("人生重开模拟器")
class RemakeCommand : BaseCommand() { 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 isSuccess = randomBooleanWithProbability(0.7)
val msg = MessageChain.Builder().addReply(message.messageId) val msg = MessageChain.Builder().addReply(message.messageId)
if (isSuccess) { if (isSuccess) {
@@ -40,6 +39,6 @@ class RemakeCommand : BaseCommand() {
msg.addText("重开成功! 你转生在${country.chineseName}$location, 是一个$role") msg.addText("重开成功! 你转生在${country.chineseName}$location, 是一个$role")
} else } else
msg.addText("转生失败~") 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.fancybot.annotations.CommandDescription
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("资料卡点赞") @CommandDescription("资料卡点赞")
class SendLikeCommand : BaseCommand() { class SendLikeCommand : BaseCommand() {
override val commandNames = listOf("赞我") override val commandNames = listOf("赞我")
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) { override suspend fun executeGroup(message: GroupMessage, args: List<String>) {
listener.sendLike(message.sender.userId, 10) message.action.sendLike(message.sender.userId, 10)
val msg = MessageChain.Builder() val msg = MessageChain.Builder()
.addReply(message.messageId)
.addText("👍了你十下~~😁") .addText("👍了你十下~~😁")
.build() .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.fancybot.util.file.insertActionRecord
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.util.BaseCommand import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.OneBotListener
import org.simplejavamail.api.mailer.config.TransportStrategy import org.simplejavamail.api.mailer.config.TransportStrategy
import org.simplejavamail.email.EmailBuilder import org.simplejavamail.email.EmailBuilder
import org.simplejavamail.mailer.MailerBuilder import org.simplejavamail.mailer.MailerBuilder
@@ -43,7 +42,7 @@ class SendMailCommand : BaseCommand() {
this.mailer.sendMail(email) 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()) { if (args.isEmpty()) {
message.reply("发送`/mail <收件人地址>`即可发送测试邮件~") message.reply("发送`/mail <收件人地址>`即可发送测试邮件~")
return return
@@ -16,7 +16,6 @@ import cn.rtast.fancybot.util.Http
import cn.rtast.fancybot.util.str.toJson import cn.rtast.fancybot.util.str.toJson
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.util.BaseCommand import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("生成短链接") @CommandDescription("生成短链接")
class ShortLinkCommand : BaseCommand() { 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()) { if (args.isEmpty()) {
message.reply("发送`/s <url>`来生成短链接`不要放入一些奇怪的链接哦~") message.reply("发送`/s <url>`来生成短链接`不要放入一些奇怪的链接哦~")
return return
@@ -12,9 +12,9 @@ import cn.rtast.fancybot.entity.tts.TTSResponse
import cn.rtast.fancybot.util.Http import cn.rtast.fancybot.util.Http
import cn.rtast.fancybot.util.str.proxy import cn.rtast.fancybot.util.str.proxy
import cn.rtast.rob.entity.GroupMessage 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.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
import okhttp3.FormBody import okhttp3.FormBody
@CommandDescription("将文字转换成语音(TTS)!") @CommandDescription("将文字转换成语音(TTS)!")
@@ -23,7 +23,7 @@ class TTSCommand : BaseCommand() {
private val ttsApiUrl = "https://ttsmp3.com/makemp3_new.php" 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()) { if (args.isEmpty()) {
message.reply("发送`/tts <文字>`就可以生成语音啦~") message.reply("发送`/tts <文字>`就可以生成语音啦~")
return return
@@ -38,6 +38,17 @@ class TTSCommand : BaseCommand() {
val msg = MessageChain.Builder() val msg = MessageChain.Builder()
.addRecord(response.url.proxy) .addRecord(response.url.proxy)
.build() .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.fancybot.annotations.CommandDescription
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
@Deprecated("已迁移到兑换列表中") @Deprecated("已迁移到兑换列表中")
@CommandDescription("获得十张色图!") @CommandDescription("获得十张色图!")
class TenSetuCommand : BaseCommand() { class TenSetuCommand : BaseCommand() {
override val commandNames = listOf("十张色图") 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() val msg = MessageChain.Builder()
.addText("指令已经迁移到兑换列表中") .addText("指令已经迁移到兑换列表中")
.addNewLine() .addNewLine()
@@ -10,7 +10,6 @@ package cn.rtast.fancybot.commands.misc
import cn.rtast.fancybot.annotations.CommandDescription import cn.rtast.fancybot.annotations.CommandDescription
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.util.BaseCommand import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.OneBotListener
import kotlin.random.Random import kotlin.random.Random
@CommandDescription("今天吃什么") @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()) { if (KFCCommand.isThursday() && Random.nextBoolean()) {
message.reply("今天是疯! 狂! 星! 期! 四!, 所以吃肯德基!") message.reply("今天是疯! 狂! 星! 期! 四!, 所以吃肯德基!")
return return
@@ -38,7 +37,7 @@ class TodayEatCommand : BaseCommand() {
class TodayDontEatCommand : BaseCommand() { class TodayDontEatCommand : BaseCommand() {
override val commandNames = listOf("今天不吃什么") 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("你吃个结巴, 是吧") 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()}吧~") message.reply("今天喝${drinkList.random()}吧~")
} }
} }
@@ -63,7 +62,28 @@ class TodayDrinkCommand : BaseCommand() {
class TodayDontDrinkCommand : BaseCommand() { class TodayDontDrinkCommand : BaseCommand() {
override val commandNames = listOf("今天不喝什么") 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("你喝个结巴, 是吧") 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.entity.GroupMessage
import cn.rtast.rob.enums.ArrayMessageType import cn.rtast.rob.enums.ArrayMessageType
import cn.rtast.rob.util.BaseCommand import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("将人类的语言翻译成尊嘟假嘟语还能将尊嘟假嘟语翻译成人类的语言!") @CommandDescription("将人类的语言翻译成尊嘟假嘟语还能将尊嘟假嘟语翻译成人类的语言!")
class ZDJDCommand : BaseCommand() { 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 }) { val text = if (message.message.any { it.type == ArrayMessageType.image }) {
message.message.find { it.type == ArrayMessageType.image }!!.data.file!! message.message.find { it.type == ArrayMessageType.image }!!.data.file!!
} else args.joinToString(" ") } else args.joinToString(" ")
@@ -10,9 +10,8 @@ package cn.rtast.fancybot.commands.misc
import cn.rtast.fancybot.annotations.CommandDescription import cn.rtast.fancybot.annotations.CommandDescription
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.entity.PrivateMessage import cn.rtast.rob.entity.PrivateMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand 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>() val users = mutableMapOf<Long, Long>()
@@ -20,7 +19,7 @@ val users = mutableMapOf<Long, Long>()
class ZiBiCommand : BaseCommand() { class ZiBiCommand : BaseCommand() {
override val commandNames = listOf("/自闭", "自闭") 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 { try {
users.remove(message.sender.userId) users.remove(message.sender.userId)
val duration = if (args.isEmpty()) 1 else args.first().toInt() val duration = if (args.isEmpty()) 1 else args.first().toInt()
@@ -47,7 +46,7 @@ class ZiBiCommand : BaseCommand() {
class UnsetZiBiCommand : BaseCommand() { class UnsetZiBiCommand : BaseCommand() {
override val commandNames = listOf("我想开了") 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 }) { if (!users.any { it.key == message.sender.userId }) {
val msg = MessageChain.Builder() val msg = MessageChain.Builder()
.addText("你没有在自闭列表中~") .addText("你没有在自闭列表中~")
@@ -55,7 +54,7 @@ class UnsetZiBiCommand : BaseCommand() {
message.reply(msg) message.reply(msg)
return 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() val msg = MessageChain.Builder()
.addText("祝你天天开心不要自闭~~") .addText("祝你天天开心不要自闭~~")
.build() .build()
@@ -10,16 +10,15 @@ package cn.rtast.fancybot.commands.niuzi
import cn.rtast.fancybot.annotations.CommandDescription import cn.rtast.fancybot.annotations.CommandDescription
import cn.rtast.fancybot.niuziManager import cn.rtast.fancybot.niuziManager
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("查询自己牛子的长度") @CommandDescription("查询自己牛子的长度")
class MyNiuziCommand : BaseCommand() { class MyNiuziCommand : BaseCommand() {
override val commandNames = listOf("我的牛子", "mp") 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) val niuzi = niuziManager.getUser(message.sender.userId)
if (niuzi == null) { if (niuzi == null) {
message.reply("你还没有牛子呢, 发送`牛子签到`来领取一根专属于你的牛子吧~") message.reply("你还没有牛子呢, 发送`牛子签到`来领取一根专属于你的牛子吧~")
@@ -37,6 +36,6 @@ class MyNiuziCommand : BaseCommand() {
else -> "牛子也太长啦把天捅穿啦!!!!!!" else -> "牛子也太长啦把天捅穿啦!!!!!!"
} }
msg.addText(niuziString) 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.fancybot.util.misc.getUserName
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.enums.ArrayMessageType import cn.rtast.rob.enums.ArrayMessageType
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand 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) { private suspend fun noAccount(message: GroupMessage) {
message.reply("你还没有银行账户呢, 发送`创建账户`来创建一个账户吧~") message.reply("你还没有银行账户呢, 发送`创建账户`来创建一个账户吧~")
@@ -28,7 +27,7 @@ private const val INTEREST_RATE = 0.0054
class NiuziBankCommand : BaseCommand() { class NiuziBankCommand : BaseCommand() {
override val commandNames = listOf("牛子银行") 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 { val niuziCommands = commands.filter {
it::class.simpleName?.startsWith("Niuzi")!! && !it::class.simpleName?.lowercase()?.contains("redeem")!! it::class.simpleName?.startsWith("Niuzi")!! && !it::class.simpleName?.lowercase()?.contains("redeem")!!
}.joinToString("\n") { it.commandNames.joinToString(",") { join -> "`$join`" } } }.joinToString("\n") { it.commandNames.joinToString(",") { join -> "`$join`" } }
@@ -49,7 +48,7 @@ class NiuziBankCommand : BaseCommand() {
class BankBalanceCommand : BaseCommand() { class BankBalanceCommand : BaseCommand() {
override val commandNames = listOf("余额查询") 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) val balanceData = niuziBankManager.getUser(message.sender.userId)
if (balanceData == null) { if (balanceData == null) {
noAccount(message) noAccount(message)
@@ -63,12 +62,12 @@ class BankBalanceCommand : BaseCommand() {
class CreateBankAccountCommand : BaseCommand() { class CreateBankAccountCommand : BaseCommand() {
override val commandNames = listOf("创建账户") 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) { if (niuziBankManager.getUser(message.sender.userId) != null) {
message.reply("你已经有账户了!") message.reply("你已经有账户了!")
return 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) niuziBankManager.createBlankAccount(message.sender.userId, userInfo.card ?: userInfo.nickname)
message.reply("成功创建了一个账户!") message.reply("成功创建了一个账户!")
} }
@@ -78,7 +77,7 @@ class CreateBankAccountCommand : BaseCommand() {
class BankTransferCommand : BaseCommand() { class BankTransferCommand : BaseCommand() {
override val commandNames = listOf("银行转账") 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) val currentUserBalance = niuziBankManager.getUser(message.sender.userId)
if (currentUserBalance == null) { if (currentUserBalance == null) {
noAccount(message) noAccount(message)
@@ -94,7 +93,7 @@ class BankTransferCommand : BaseCommand() {
message.reply("你的牛子长度不够转账!") message.reply("你的牛子长度不够转账!")
return 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) val result = niuziBankManager.transfer(message.sender.userId, target, amount, username)
message.reply("转账成功! 你在银行内剩余的牛子长度为: ${result?.balance}") message.reply("转账成功! 你在银行内剩余的牛子长度为: ${result?.balance}")
} }
@@ -104,7 +103,7 @@ class BankTransferCommand : BaseCommand() {
class WithdrawCommand : BaseCommand() { class WithdrawCommand : BaseCommand() {
override val commandNames = listOf("取牛子") 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 amount = args.last().toDouble()
val currentBalance = niuziBankManager.getUser(message.sender.userId) val currentBalance = niuziBankManager.getUser(message.sender.userId)
val niuzi = niuziManager.getUser(message.sender.userId) val niuzi = niuziManager.getUser(message.sender.userId)
@@ -124,7 +123,7 @@ class WithdrawCommand : BaseCommand() {
message.reply("取出的长度必须大于0!") message.reply("取出的长度必须大于0!")
return 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) val result = niuziBankManager.withdraw(message.sender.userId, amount, username)
niuziManager.updateLength(message.sender.userId, amount + amount * INTEREST_RATE) niuziManager.updateLength(message.sender.userId, amount + amount * INTEREST_RATE)
message.reply("取牛子成功, 你现在还剩${result.balance}cm的牛子在银行内") message.reply("取牛子成功, 你现在还剩${result.balance}cm的牛子在银行内")
@@ -135,7 +134,7 @@ class WithdrawCommand : BaseCommand() {
class DepositCommand : BaseCommand() { class DepositCommand : BaseCommand() {
override val commandNames = listOf("存牛子") 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 currentBalance = niuziBankManager.getUser(message.sender.userId)
val niuzi = niuziManager.getUser(message.sender.userId) val niuzi = niuziManager.getUser(message.sender.userId)
val amount = args.last().toDouble() val amount = args.last().toDouble()
@@ -155,7 +154,7 @@ class DepositCommand : BaseCommand() {
message.reply("你身上的牛子不够用啦, 没办法存进银行! >>> ${niuzi.length}") message.reply("你身上的牛子不够用啦, 没办法存进银行! >>> ${niuzi.length}")
return 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 self = niuziManager.updateLength(message.sender.userId, -amount)
val result = niuziBankManager.deposit(message.sender.userId, amount, username) val result = niuziBankManager.deposit(message.sender.userId, amount, username)
message.reply("存入成功你身上的牛子还有${self?.length}cm 银行账户内还有: ${result.balance}cm") 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.fancybot.niuziManager
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.enums.ArrayMessageType import cn.rtast.rob.enums.ArrayMessageType
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("来一起激情击剑吧!") @CommandDescription("来一起激情击剑吧!")
class NiuziJiJianCommand : BaseCommand() { class NiuziJiJianCommand : BaseCommand() {
override val commandNames = listOf("击剑", "jj") 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()) { if (args.isEmpty()) {
message.reply("发送`击剑 @xxx`即可对某人进行击剑") message.reply("发送`击剑 @xxx`即可对某人进行击剑")
return return
@@ -34,7 +33,7 @@ class NiuziJiJianCommand : BaseCommand() {
.addNewLine() .addNewLine()
.addText("所以你不能和他们击剑~") .addText("所以你不能和他们击剑~")
.build() .build()
listener.sendGroupMessage(message.groupId, msg) message.reply(msg)
return return
} }
if (message.sender.userId == targetId) { if (message.sender.userId == targetId) {
@@ -69,7 +68,7 @@ class NiuziJiJianCommand : BaseCommand() {
.addNewLine() .addNewLine()
.addText("对方的牛子增加了${result.second}cm~") .addText("对方的牛子增加了${result.second}cm~")
.build() .build()
listener.sendGroupMessage(message.groupId, msg) message.reply(msg)
} }
} }
} }
@@ -8,36 +8,37 @@
package cn.rtast.fancybot.commands.niuzi package cn.rtast.fancybot.commands.niuzi
import cn.rtast.fancybot.annotations.CommandDescription import cn.rtast.fancybot.annotations.CommandDescription
import cn.rtast.fancybot.configManager
import cn.rtast.fancybot.niuziBankManager import cn.rtast.fancybot.niuziBankManager
import cn.rtast.fancybot.niuziManager import cn.rtast.fancybot.niuziManager
import cn.rtast.fancybot.util.misc.getUserName import cn.rtast.fancybot.util.misc.getUserName
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.enums.ArrayMessageType import cn.rtast.rob.enums.ArrayMessageType
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("在群内设置某个成员的牛子银行余额或者现金牛子长度") @CommandDescription("在群内设置某个成员的牛子银行余额或者现金牛子长度")
class NiuziManagerCommand : BaseCommand() { class NiuziManagerCommand : BaseCommand() {
override val commandNames = listOf("管理牛子") 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()) { if (args.isEmpty()) {
message.reply("此命令可以管理成员的牛子或者银行账户") message.reply("此命令可以管理成员的牛子或者银行账户")
return return
} }
println(args)
if (message.sender.isAdmin || message.sender.isOwner) { if (message.sender.isAdmin || message.sender.isOwner) {
val target = message.message.find { it.type == ArrayMessageType.at }!!.data.qq!!.toLong() val target = message.message.find { it.type == ArrayMessageType.at }!!.data.qq!!.toLong()
val method = args[1] val method = args[0]
val amount = args.last().toDouble() val amount = args[1].toDouble()
when (method) { when (method) {
"set", "s", "设置" -> { "set", "s", "设置" -> {
val type = args[2] val type = args[2]
when (type) { when (type) {
"yh", "银行" -> { "yh", "银行" -> {
val before = niuziBankManager.getUser(target) 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 after = niuziBankManager.getUser(target)
val msg = MessageChain.Builder() val msg = MessageChain.Builder()
.addText("设置成功! 金额: $amount") .addText("设置成功! 金额: $amount")
@@ -12,13 +12,12 @@ import cn.rtast.fancybot.niuziManager
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.enums.ArrayMessageType import cn.rtast.rob.enums.ArrayMessageType
import cn.rtast.rob.util.BaseCommand import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("查询别人的牛子长度") @CommandDescription("查询别人的牛子长度")
class NiuziQueryCommand : BaseCommand() { class NiuziQueryCommand : BaseCommand() {
override val commandNames = listOf("牛子查询") 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()) { if (args.isEmpty()) {
message.reply("输入`牛子查询 @某人`即可查询他的牛子长度") message.reply("输入`牛子查询 @某人`即可查询他的牛子长度")
return return
@@ -11,15 +11,14 @@ import cn.rtast.fancybot.annotations.CommandDescription
import cn.rtast.fancybot.niuziBankManager import cn.rtast.fancybot.niuziBankManager
import cn.rtast.fancybot.niuziManager import cn.rtast.fancybot.niuziManager
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("查询所有人的牛子的排行榜") @CommandDescription("查询所有人的牛子的排行榜")
class NiuziRankCommand : BaseCommand() { class NiuziRankCommand : BaseCommand() {
override val commandNames = listOf("牛子排行榜", "牛子排行") 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 allNiuzi = niuziManager.getAllNiuzi().sortedBy { it.length }.reversed()
val msg = MessageChain.Builder().addText("牛子长度排行榜如下").addNewLine() val msg = MessageChain.Builder().addText("牛子长度排行榜如下").addNewLine()
allNiuzi.forEach { allNiuzi.forEach {
@@ -33,7 +32,7 @@ class NiuziRankCommand : BaseCommand() {
class NiuziBankRankCommand : BaseCommand() { class NiuziBankRankCommand : BaseCommand() {
override val commandNames = listOf("牛子富豪榜", "富豪榜") 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() val allNiuziBankAccounts = niuziBankManager.getAllAccount()
.sortedBy { it.balance }.reversed() .sortedBy { it.balance }.reversed()
val msg = MessageChain.Builder().addText("牛子银行富豪榜排行如下").addNewLine() 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.itemManager
import cn.rtast.fancybot.niuziManager import cn.rtast.fancybot.niuziManager
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("使用牛子长度兑换物品") @CommandDescription("使用牛子长度兑换物品")
class NiuziRedeemCommand : BaseCommand() { class NiuziRedeemCommand : BaseCommand() {
override val commandNames = listOf("/rdm") 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()) { if (args.isEmpty()) {
val msg = MessageChain.Builder() val msg = MessageChain.Builder()
.addText("发送 /rdm <物品名称> 即可兑换哦!") .addText("发送 /rdm <物品名称> 即可兑换哦!")
@@ -64,7 +63,7 @@ class NiuziRedeemCommand : BaseCommand() {
return return
} }
val afterStatus = niuziManager.redeemItem(message.sender.userId, selectedItemPrice)?.length!! 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() val msg = MessageChain.Builder()
.addText("兑换成功! 你花费了${selectedItemPrice}cm来兑换奖品, 还剩${afterStatus}cm") .addText("兑换成功! 你花费了${selectedItemPrice}cm来兑换奖品, 还剩${afterStatus}cm")
.addNewLine() .addNewLine()
@@ -11,20 +11,19 @@ import cn.rtast.fancybot.annotations.CommandDescription
import cn.rtast.fancybot.niuziManager import cn.rtast.fancybot.niuziManager
import cn.rtast.fancybot.util.misc.getUserName import cn.rtast.fancybot.util.misc.getUserName
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("牛子签到~") @CommandDescription("牛子签到~")
class NiuziSignCommand : BaseCommand() { class NiuziSignCommand : BaseCommand() {
override val commandNames = listOf("牛子签到", "签到") 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)) { if (niuziManager.isSigned(message.sender.userId)) {
message.reply("你今天已经对你的牛子使用了签到啦,明天再来吧~") message.reply("你今天已经对你的牛子使用了签到啦,明天再来吧~")
return 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 afterStatus = niuziManager.sign(message.sender.userId, username)
val msg = MessageChain.Builder() val msg = MessageChain.Builder()
.addReply(message.messageId) .addReply(message.messageId)
@@ -32,6 +31,6 @@ class NiuziSignCommand : BaseCommand() {
.addNewLine() .addNewLine()
.addText("你的牛子增加了${afterStatus.first}cm~ 总长度为: ${afterStatus.second?.length}") .addText("你的牛子增加了${afterStatus.first}cm~ 总长度为: ${afterStatus.second?.length}")
.build() .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.entity.GroupMessage
import cn.rtast.rob.enums.ArrayMessageType import cn.rtast.rob.enums.ArrayMessageType
import cn.rtast.rob.util.BaseCommand import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.OneBotListener
@CommandDescription("将自己的牛子长度转账给别人") @CommandDescription("将自己的牛子长度转账给别人")
class NiuziTransferCommand : BaseCommand() { class NiuziTransferCommand : BaseCommand() {
override val commandNames = listOf("牛子转账", "zz") 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()) { if (args.isEmpty()) {
message.reply("发送`牛子转账 @某人 <长度>` 即可把自己的牛子长度转账给TA") message.reply("发送`牛子转账 @某人 <长度>` 即可把自己的牛子长度转账给TA")
return return
@@ -18,10 +18,8 @@ import cn.rtast.fancybot.util.str.encodeToBase64
import cn.rtast.rob.entity.GetMessage import cn.rtast.rob.entity.GetMessage
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.enums.ArrayMessageType import cn.rtast.rob.enums.ArrayMessageType
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand 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 com.madgag.gif.fmsware.GifDecoder
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@@ -99,7 +97,7 @@ class AsciiArtCommand : BaseCommand() {
try { try {
decoder.read(gifStream) decoder.read(gifStream)
if (decoder.frameCount == 0) { 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() val imageBytes = bufferedImage.convertToAscii()
.saveAsciiArtToImage(bufferedImage.width, bufferedImage.height) .saveAsciiArtToImage(bufferedImage.width, bufferedImage.height)
.toByteArray() .toByteArray()
@@ -132,10 +130,10 @@ class AsciiArtCommand : BaseCommand() {
return msg return msg
} }
} catch (_: OutOfMemoryError) { } catch (_: OutOfMemoryError) {
return listOf("GIF处理失败: 内存溢出").asMessageChain() return MessageChain.Builder().addText("GIF处理失败: 内存溢出").build()
logger.info("GIF处理失败: 内存溢出") logger.info("GIF处理失败: 内存溢出")
} catch (e: Exception) { } catch (e: Exception) {
return listOf("处理GIF失败: ${e.message}").asMessageChain() return MessageChain.Builder().addText("处理GIF失败: ${e.message}").build()
logger.info("gif处理失败: ${e.message}") logger.info("gif处理失败: ${e.message}")
} }
} }
@@ -157,7 +155,7 @@ class AsciiArtCommand : BaseCommand() {
return getImageUrlFromUnified(toUnifiedMessage(groupMessage)) return getImageUrlFromUnified(toUnifiedMessage(groupMessage))
} }
fun getImageUrl(getMessageData: GetMessage.Data): String { fun getImageUrl(getMessageData: GetMessage.Message): String {
return getImageUrlFromUnified(toUnifiedMessage(getMessageData)) return getImageUrlFromUnified(toUnifiedMessage(getMessageData))
} }
@@ -171,14 +169,14 @@ class AsciiArtCommand : BaseCommand() {
return groupMessage.message.map { UnifiedMessage(it.type, it.data.file, it.data.url) } 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) } 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?) 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) { if (message.sender.userId !in waitingList) {
message.reply("请继续发送一张图片, 如果输入错误则取消本次操作, 如果GIF帧数过多可能会需要很长时间(也可能处理失败)") message.reply("请继续发送一张图片, 如果输入错误则取消本次操作, 如果GIF帧数过多可能会需要很长时间(也可能处理失败)")
waitingList.add(message.sender.userId) 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.fromJson
import cn.rtast.fancybot.util.str.setTruncate import cn.rtast.fancybot.util.str.setTruncate
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.entity.text
import cn.rtast.rob.enums.ArrayMessageType import cn.rtast.rob.enums.ArrayMessageType
import cn.rtast.rob.util.ob.MessageChain import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.ob.OneBotListener
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import java.awt.Color import java.awt.Color
@@ -184,7 +184,8 @@ object BiliVideoParseCommand {
return String(bytes) 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 { try {
val bvid = if (bvRegex.containsMatchIn(message.rawMessage)) { val bvid = if (bvRegex.containsMatchIn(message.rawMessage)) {
message.rawMessage.extractBv() message.rawMessage.extractBv()
@@ -229,11 +230,10 @@ object BiliVideoParseCommand {
share, like, favorite, fans, viewCount share, like, favorite, fans, viewCount
) )
val msg = MessageChain.Builder() val msg = MessageChain.Builder()
.addReply(message.messageId)
.addImage(image, true) .addImage(image, true)
.addText(shortUrl) .addText(shortUrl)
.build() .build()
listener.sendGroupMessage(message.groupId, msg) message.reply(msg)
} catch (_: Exception) { } catch (_: Exception) {
} }
} }
@@ -276,7 +276,7 @@ object BiliUserParseCommand {
return image.toByteArray().encodeToBase64() return image.toByteArray().encodeToBase64()
} }
suspend fun parse(listener: OneBotListener, message: GroupMessage) { suspend fun parse(message: GroupMessage) {
val match = idRegex.find(message.rawMessage) val match = idRegex.find(message.rawMessage)
if (match != null) { if (match != null) {
val userId = match.groupValues[1] val userId = match.groupValues[1]
@@ -285,7 +285,7 @@ object BiliUserParseCommand {
val msg = MessageChain.Builder() val msg = MessageChain.Builder()
.addImage(userCardImage, true) .addImage(userCardImage, true)
.build() .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.formatNumber
import cn.rtast.fancybot.util.str.proxy import cn.rtast.fancybot.util.str.proxy
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.util.ob.MessageChain import cn.rtast.rob.onebot.MessageChain
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import java.awt.Color 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.formatNumberEnglish
import cn.rtast.fancybot.util.str.setTruncate import cn.rtast.fancybot.util.str.setTruncate
import cn.rtast.rob.entity.GroupMessage 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.Color
import java.awt.Font import java.awt.Font
import java.awt.RenderingHints import java.awt.RenderingHints
@@ -12,12 +12,12 @@ import cn.rtast.fancybot.configManager
import cn.rtast.rob.entity.GetMessage import cn.rtast.rob.entity.GetMessage
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.enums.ArrayMessageType import cn.rtast.rob.enums.ArrayMessageType
import cn.rtast.rob.util.ob.MessageChain import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.ob.asNode import cn.rtast.rob.onebot.toNode
object ImageURLCommand { object ImageURLCommand {
fun getImageUrl(message: GetMessage.Data): List<String> { fun getImageUrl(message: GetMessage.Message): List<String> {
try { try {
val images = mutableListOf<String>() val images = mutableListOf<String>()
message.message.forEach { 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) val images = getImageUrl(message)
if (images.isEmpty()) { if (images.isEmpty()) {
groupMessage.reply("这个消息里没有图片呢!") groupMessage.reply("这个消息里没有图片呢!")
@@ -51,7 +51,7 @@ object ImageURLCommand {
.build() .build()
messages.add(msg) 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.GetMessage
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.enums.ArrayMessageType import cn.rtast.rob.enums.ArrayMessageType
import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.BaseCommand 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 com.madgag.gif.fmsware.GifDecoder
import java.net.URI import java.net.URI
@@ -35,7 +34,7 @@ class ReverseGIFCommand : BaseCommand() {
return gifBytes.encodeToBase64() 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 } val imageObject = getMsg.message.find { it.type == ArrayMessageType.image }
if (imageObject == null) { if (imageObject == null) {
message.reply("这个消息中没有图片呢") 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) { if (message.sender.userId !in waitingList) {
message.reply("发送一张动图来继续操作") message.reply("发送一张动图来继续操作")
waitingList.add(message.sender.userId) 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.formatNumber
import cn.rtast.fancybot.util.str.proxy import cn.rtast.fancybot.util.str.proxy
import cn.rtast.rob.entity.GroupMessage 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.Color
import java.awt.Font import java.awt.Font
import java.awt.RenderingHints 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.fancybot.util.misc.toURL
import cn.rtast.rob.entity.GetMessage import cn.rtast.rob.entity.GetMessage
import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.util.ob.MessageChain import cn.rtast.rob.onebot.MessageChain
import cn.rtast.rob.util.ob.asNode import cn.rtast.rob.onebot.toNode
import okio.IOException import okio.IOException
object ImageBedCommand { object ImageBedCommand {
suspend fun execute(getMsg: GetMessage.Data, message: GroupMessage) { suspend fun execute(getMsg: GetMessage.Message, message: GroupMessage) {
val imagesUrl = ImageURLCommand.getImageUrl(getMsg) val imagesUrl = ImageURLCommand.getImageUrl(getMsg)
if (imagesUrl.isEmpty()) { if (imagesUrl.isEmpty()) {
message.reply("这个消息里没有图片呢!") message.reply("这个消息里没有图片呢!")
@@ -49,7 +49,7 @@ object ImageBedCommand {
.build() .build()
messages.add(msg) messages.add(msg)
} }
message.reply(messages.asNode(configManager.selfId)) message.reply(messages.toNode(configManager.selfId))
} }
} catch (_: IOException) { } catch (_: IOException) {
message.reply("上传失败: 图片已过期") 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( data class MCAccessTokenEntity(
val token: String, val token: String,
val userId: Long, val userId: Long,
val timestamp: Long val timestamp: Long,
) )
suspend fun insertNewAccessToken(accessToken: String, id: Long) { suspend fun insertNewAccessToken(accessToken: String, id: Long) {
@@ -24,5 +24,5 @@ data class NiuziBankAccount(
val balance: Double, val balance: Double,
val interestRate: Double, val interestRate: Double,
val timestamp: Long, val timestamp: Long,
val nickname: String val nickname: String,
) )
@@ -24,6 +24,6 @@ data class RCONEntity(
val port: Int, val port: Int,
val userId: Long, val userId: Long,
val name: String, val name: String,
val password: String val password: String,
) )
@@ -7,13 +7,11 @@
package cn.rtast.fancybot.entity package cn.rtast.fancybot.entity
import cn.rtast.fancybot.enums.DatabaseType
import cn.rtast.fancybot.enums.ImageBedType import cn.rtast.fancybot.enums.ImageBedType
import cn.rtast.fancybot.enums.ImageType import cn.rtast.fancybot.enums.ImageType
import cn.rtast.fancybot.enums.WSType import cn.rtast.fancybot.enums.WSType
data class Config( data class Config(
val database: Database,
val ncmAPI: String, val ncmAPI: String,
val wsType: WSType, val wsType: WSType,
val wsAddress: String, val wsAddress: String,
@@ -51,13 +49,7 @@ data class Config(
val apiRtastKey: String, val apiRtastKey: String,
val azureAppClientId: String, val azureAppClientId: String,
val youtubeDataApiKey: String, val youtubeDataApiKey: String,
) { val naiLongApiUrl: String,
data class Database( val osuClientSecret: String,
val type: DatabaseType, val osuClientId: Int
val host: String, )
val port: Int,
val user: String,
val password: String,
val database: String,
)
}
@@ -13,5 +13,5 @@ data class Hitokoto(
val uuid: String, val uuid: String,
@SerializedName("hitokoto") @SerializedName("hitokoto")
val sentence: String, val sentence: String,
val from: String val from: String,
) )
@@ -8,7 +8,7 @@
package cn.rtast.fancybot.entity.apispace package cn.rtast.fancybot.entity.apispace
data class IdiomExplainResponse( data class IdiomExplainResponse(
val data: List<Data> val data: List<Data>,
) { ) {
data class Data( data class Data(
val name: String, val name: String,
@@ -10,7 +10,7 @@ package cn.rtast.fancybot.entity.bgm
import com.google.gson.annotations.SerializedName import com.google.gson.annotations.SerializedName
data class BGMSearch( data class BGMSearch(
val list: List<Result> val list: List<Result>,
) { ) {
data class Result( data class Result(
val url: String, val url: String,
@@ -21,6 +21,6 @@ data class BGMSearch(
) )
data class Images( data class Images(
val large: String val large: String,
) )
} }
@@ -15,7 +15,7 @@ data class CardShare(
data class Meta( data class Meta(
@SerializedName("detail_1") @SerializedName("detail_1")
val detail: Detail?, val detail: Detail?,
val news: News? val news: News?,
) )
data class Detail( data class Detail(
@@ -26,6 +26,6 @@ data class CardShare(
data class News( data class News(
val tag: String, val tag: String,
val jumpUrl: String val jumpUrl: String,
) )
} }
@@ -8,9 +8,9 @@
package cn.rtast.fancybot.entity.bili package cn.rtast.fancybot.entity.bili
data class ShortUrl( data class ShortUrl(
val data: Data val data: Data,
) { ) {
data class 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 import com.google.gson.annotations.SerializedName
data class UserInfo( data class UserInfo(
val data: Data val data: Data,
) { ) {
data class Data( data class Data(
val card: Card, val card: Card,
@@ -22,7 +22,7 @@ data class UserInfo(
val fans: Int, val fans: Int,
val sign: String, val sign: String,
@SerializedName("level_info") @SerializedName("level_info")
val levelInfo: LevelInfo val levelInfo: LevelInfo,
) )
data class LevelInfo( data class LevelInfo(
@@ -8,9 +8,9 @@
package cn.rtast.fancybot.entity.bili package cn.rtast.fancybot.entity.bili
data class UserStat( data class UserStat(
val data: Data val data: Data,
) { ) {
data class Data( data class Data(
val follower: Int val follower: Int,
) )
} }
@@ -8,7 +8,7 @@
package cn.rtast.fancybot.entity.bili package cn.rtast.fancybot.entity.bili
data class VideoStat( data class VideoStat(
val data: Data val data: Data,
) { ) {
data class Data( data class Data(
val aid: Long, val aid: Long,
@@ -8,9 +8,9 @@
package cn.rtast.fancybot.entity.bili package cn.rtast.fancybot.entity.bili
data class ViewCount( data class ViewCount(
val data: Data val data: Data,
) { ) {
data class Data( data class Data(
val total: String val total: String,
) )
} }
@@ -4,5 +4,5 @@ data class BullShit(
val after: List<String>, val after: List<String>,
val before: List<String>, val before: List<String>,
val bosh: List<String>, val bosh: List<String>,
val famous: List<String> val famous: List<String>,
) )
@@ -13,7 +13,7 @@ data class Cigarette(
@SerializedName("totalnum") @SerializedName("totalnum")
val totalCount: Int, val totalCount: Int,
@SerializedName("productlist") @SerializedName("productlist")
val productList: List<Product> val productList: List<Product>,
) { ) {
data class Product( data class Product(
@SerializedName("productname") @SerializedName("productname")
@@ -26,11 +26,11 @@ data class Cigarette(
@SerializedName("packprice") @SerializedName("packprice")
val packPrice: Float, val packPrice: Float,
@SerializedName("barprice") @SerializedName("barprice")
val barPrice: Float val barPrice: Float,
) )
data class CigaretteType( data class CigaretteType(
@SerializedName("typename") @SerializedName("typename")
val typeName: String val typeName: String,
) )
} }
@@ -8,10 +8,10 @@
package cn.rtast.fancybot.entity.compiler package cn.rtast.fancybot.entity.compiler
data class GLOTPayload( data class GLOTPayload(
val files: List<File> val files: List<File>,
) { ) {
data class File( data class File(
val content: String, val content: String,
val name: String = "main" val name: String = "main",
) )
} }
@@ -10,11 +10,11 @@ package cn.rtast.fancybot.entity.compiler
data class KCSPayload( data class KCSPayload(
val files: List<File>, val files: List<File>,
val args: String = "", val args: String = "",
val confType: String = "java" val confType: String = "java",
) { ) {
data class File( data class File(
val text: String, val text: String,
val name: String = "File.kt", val name: String = "File.kt",
val publicId: String = "" val publicId: String = "",
) )
} }
@@ -13,10 +13,10 @@ data class KCSResponse(
val errors: Errors, val errors: Errors,
val exception: Any, val exception: Any,
val jvmByteCode: Any, val jvmByteCode: Any,
val text: String val text: String,
) { ) {
data class Errors( data class Errors(
@SerializedName("File.kt") @SerializedName("File.kt")
val file: List<Any> val file: List<Any>,
) )
} }
@@ -24,5 +24,5 @@ data class PricePayload(
@SerializedName("Version") @SerializedName("Version")
val version: String = "2018-08-08", val version: String = "2018-08-08",
@SerializedName("Action") @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