Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: MisakaTAT/Shiro
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v2.2.8
Choose a base ref
...
head repository: MisakaTAT/Shiro
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: main
Choose a head ref
Loading
Showing with 624 additions and 134 deletions.
  1. BIN .github/assets/logo.png
  2. +2 −2 README.md
  3. +14 −8 build.gradle.kts
  4. BIN gradle/wrapper/gradle-wrapper.jar
  5. +2 −1 gradle/wrapper/gradle-wrapper.properties
  6. +21 −13 gradlew
  7. +12 −10 gradlew.bat
  8. +1 −1 settings.gradle.kts
  9. +7 −0 src/main/java/com/mikuac/shiro/action/GoCQHTTPExtend.java
  10. +12 −0 src/main/java/com/mikuac/shiro/action/LagrangeExtend.java
  11. +11 −5 src/main/java/com/mikuac/shiro/adapter/WebSocketClientHandler.java
  12. +10 −5 src/main/java/com/mikuac/shiro/adapter/WebSocketServerHandler.java
  13. +9 −0 src/main/java/com/mikuac/shiro/annotation/GroupReactionNoticeHandler.java
  14. +9 −3 src/main/java/com/mikuac/shiro/boot/Shiro.java
  15. +2 −2 src/main/java/com/mikuac/shiro/common/utils/{ScanUtils.java → AnnotationScanner.java}
  16. +1 −1 src/main/java/com/mikuac/shiro/common/utils/ArrayMsgUtils.java
  17. +15 −5 src/main/java/com/mikuac/shiro/common/utils/ConnectionUtils.java
  18. +104 −0 src/main/java/com/mikuac/shiro/common/utils/FaceUtils.java
  19. +0 −39 src/main/java/com/mikuac/shiro/common/utils/NetUtils.java
  20. +19 −7 src/main/java/com/mikuac/shiro/common/utils/{SendUtils.java → PayloadSender.java}
  21. +50 −0 src/main/java/com/mikuac/shiro/common/utils/ReqUtils.java
  22. +32 −2 src/main/java/com/mikuac/shiro/common/utils/ShiroUtils.java
  23. +4 −0 src/main/java/com/mikuac/shiro/constant/ActionParams.java
  24. +4 −0 src/main/java/com/mikuac/shiro/constant/Connection.java
  25. +49 −0 src/main/java/com/mikuac/shiro/core/Bot.java
  26. +85 −9 src/main/java/com/mikuac/shiro/core/BotFactory.java
  27. +11 −0 src/main/java/com/mikuac/shiro/core/BotPlugin.java
  28. +20 −0 src/main/java/com/mikuac/shiro/dto/action/response/VersionInfoResp.java
  29. +58 −0 src/main/java/com/mikuac/shiro/dto/event/notice/GroupMessageReactionNoticeEvent.java
  30. +1 −1 src/main/java/com/mikuac/shiro/dto/event/notice/GroupMsgDeleteNoticeEvent.java
  31. +1 −1 src/main/java/com/mikuac/shiro/dto/event/notice/PrivateMsgDeleteNoticeEvent.java
  32. +9 −1 src/main/java/com/mikuac/shiro/enums/ActionPathEnum.java
  33. +5 −1 src/main/java/com/mikuac/shiro/enums/NoticeEventEnum.java
  34. +8 −9 src/main/java/com/mikuac/shiro/handler/ActionHandler.java
  35. +1 −0 src/main/java/com/mikuac/shiro/handler/EventHandler.java
  36. +16 −0 src/main/java/com/mikuac/shiro/handler/event/NoticeEvent.java
  37. +10 −0 src/main/java/com/mikuac/shiro/handler/injection/InjectionHandler.java
  38. +3 −3 src/main/java/com/mikuac/shiro/model/ArrayMsg.java
  39. +2 −2 src/test/java/com/mikuac/shiro/common/utils/{ScanUtilsTest.java → AnnotationScannerTest.java}
  40. +1 −1 src/test/java/com/mikuac/shiro/common/utils/CommonUtilsTest.java
  41. +3 −2 src/test/resources/application.yml
Binary file added .github/assets/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<p align="center">
<img src="https://mikuac.com/images/shiro.png" width="200" height="200" alt="Shiro">
<img src=".github/assets/logo.png" width="200" height="200" alt="Shiro">
</p>

<div align="center">
@@ -212,7 +212,7 @@ source product.

[JetBrains](https://www.jetbrains.com/?from=Shiro) offers free licenses to support open source projects.

[<img src="https://mikuac.com/images/jetbrains-variant-3.png" width="200"/>](https://www.jetbrains.com/?from=mirai)
[<img src="https://resources.jetbrains.com/storage/products/company/brand/logos/jetbrains.png" width="280"/>](https://www.jetbrains.com/?from=shiro)

# Stargazers over time

22 changes: 14 additions & 8 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
@file:Suppress("SpellCheckingInspection")

group = "com.mikuac"
version = "2.2.8"
version = "2.3.5"

plugins {
signing
`java-library`
`maven-publish`
id("io.freefair.lombok") version "8.6"
id("org.springframework.boot") version "3.3.0"
id("io.spring.dependency-management") version "1.1.5"
id("io.freefair.lombok") version "8.12.1"
id("org.springframework.boot") version "3.4.1"
id("io.spring.dependency-management") version "1.1.7"
}

java {
@@ -40,10 +40,10 @@ repositories {
}

dependencies {
api("com.alibaba.fastjson2:fastjson2:2.0.51")
api("com.alibaba.fastjson2:fastjson2:2.0.55")
api("org.springframework.boot:spring-boot-starter-websocket")
annotationProcessor("org.springframework.boot:spring-boot-configuration-processor")
testImplementation("org.junit.jupiter:junit-jupiter:5.10.2")
testImplementation("org.junit.jupiter:junit-jupiter:5.11.4")
testImplementation("org.springframework.boot:spring-boot-starter-test")
}

@@ -60,7 +60,7 @@ publishing {
description.set("基于OneBot协议的QQ机器人快速开发框架")
licenses {
license {
name.set("GNU General Public License v3.0")
name.set("GNU Affero General Public License v3.0")
url.set("https://github.com/MisakaTAT/Shiro/blob/main/LICENSE")
}
}
@@ -92,9 +92,15 @@ publishing {
}
}

gradle.taskGraph.whenReady {
tasks.withType<Sign>().configureEach {
enabled = !gradle.taskGraph.hasTask(":publishToMavenLocal")
}
}

signing {
val signingKey = System.getenv("GPG_PRIVATE_KEY")
val signingPassword = System.getenv("GPG_PASSPHRASE")
useInMemoryPgpKeys(signingKey, signingPassword)
sign(publishing.publications["maven"])
}
}
Binary file modified gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
3 changes: 2 additions & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
34 changes: 21 additions & 13 deletions gradlew
Original file line number Diff line number Diff line change
@@ -15,6 +15,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#

##############################################################################
#
@@ -55,7 +57,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
@@ -83,10 +85,9 @@ done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit

# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
' "$PWD" ) || exit

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
@@ -133,26 +134,29 @@ location of your Java installation."
fi
else
JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi

# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
@@ -197,11 +201,15 @@ if "$cygwin" || "$msys" ; then
done
fi

# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.

# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'

# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.

set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
22 changes: 12 additions & 10 deletions gradlew.bat
Original file line number Diff line number Diff line change
@@ -13,6 +13,8 @@
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem

@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@@ -43,11 +45,11 @@ set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute

echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2

goto fail

@@ -57,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe

if exist "%JAVA_EXE%" goto execute

echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2

goto fail

2 changes: 1 addition & 1 deletion settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
rootProject.name = "shiro"
rootProject.name = "shiro"
7 changes: 7 additions & 0 deletions src/main/java/com/mikuac/shiro/action/GoCQHTTPExtend.java
Original file line number Diff line number Diff line change
@@ -364,4 +364,11 @@ public interface GoCQHTTPExtend {
* @return result {@link ActionList} of {@link GroupMemberInfoResp}
*/
ActionList<GroupMemberInfoResp> getGroupMemberList(long groupId, boolean noCache);

/**
* 获取版本信息
*
* @return result {@link ActionList} of {@link VersionInfoResp}
*/
public ActionData<VersionInfoResp> getVersionInfo();
}
12 changes: 12 additions & 0 deletions src/main/java/com/mikuac/shiro/action/LagrangeExtend.java
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@

import com.mikuac.shiro.dto.action.common.ActionData;
import com.mikuac.shiro.dto.action.common.ActionList;
import com.mikuac.shiro.dto.action.common.ActionRaw;

import java.util.List;
import java.util.Map;
@@ -23,4 +24,15 @@ public interface LagrangeExtend {
*/
ActionData<String> sendForwardMsg(List<Map<String, Object>> msg);

/**
* 设置群消息表情回应
*
* @param groupId 群号
* @param msgId 消息 ID
* @param code 表情 ID
* @param isAdd 添加/取消 回应
* @return result {@link ActionRaw}
*/
ActionRaw setGroupReaction(long groupId, int msgId, String code, boolean isAdd);

}
16 changes: 11 additions & 5 deletions src/main/java/com/mikuac/shiro/adapter/WebSocketClientHandler.java
Original file line number Diff line number Diff line change
@@ -16,13 +16,15 @@
import com.mikuac.shiro.task.ShiroAsyncTask;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

/**
* Created on 2021/7/16.
@@ -40,11 +42,13 @@ public class WebSocketClientHandler extends TextWebSocketHandler {
private final ShiroAsyncTask shiroAsyncTask;
private final BotContainer botContainer;
private final WebSocketProperties wsProp;
private final ThreadPoolTaskExecutor shiroTaskExecutor;

@SuppressWarnings("squid:S107")
public WebSocketClientHandler(
EventHandler eventHandler, BotFactory botFactory, ActionHandler actionHandler,
ShiroAsyncTask shiroAsyncTask, BotContainer botContainer, CoreEvent coreEvent,
WebSocketProperties wsProp
WebSocketProperties wsProp, ThreadPoolTaskExecutor shiroTaskExecutor
) {
this.eventHandler = eventHandler;
this.botFactory = botFactory;
@@ -53,6 +57,7 @@ public WebSocketClientHandler(
this.botContainer = botContainer;
this.coreEvent = coreEvent;
this.wsProp = wsProp;
this.shiroTaskExecutor = shiroTaskExecutor;
}

@Override
@@ -72,7 +77,7 @@ public void afterConnectionEstablished(@NonNull WebSocketSession session) {
Bot bot = botFactory.createBot(xSelfId, session);
botContainer.robots.put(xSelfId, bot);
log.info("Account {} connected", xSelfId);
coreEvent.online(bot);
CompletableFuture.runAsync(() -> coreEvent.online(bot), shiroTaskExecutor);
} catch (IOException e) {
log.error("Failed close websocket session: {}", e.getMessage(), e);
}
@@ -83,7 +88,7 @@ public void afterConnectionClosed(@NonNull WebSocketSession session, @NonNull Cl
Map.Entry<Long, Bot> bot = botContainer.robots.entrySet().stream().findFirst().orElse(null);
if (bot != null) {
log.warn("Account {} disconnected", bot.getKey());
coreEvent.offline(bot.getKey());
CompletableFuture.runAsync(() -> coreEvent.offline(bot.getKey()), shiroTaskExecutor);
botContainer.robots.clear();
}
}
@@ -95,8 +100,9 @@ protected void handleTextMessage(@NonNull WebSocketSession session, @NonNull Tex
if (xSelfId == 0L) {
boolean valid = JSON.isValid(message.getPayload());
if (valid) {
String selfId = JSONObject.parseObject(message.getPayload()).getOrDefault("self_id", "").toString();
session.getAttributes().put("x-self-id", selfId);
String selfId = JSONObject.parseObject(message.getPayload()).getOrDefault(Connection.SELF_ID, "").toString();
session.getAttributes().put(Connection.X_SELF_ID, selfId);
xSelfId = ConnectionUtils.parseSelfId(session);
}
if (!botContainer.robots.containsKey(xSelfId)) {
afterConnectionEstablished(session);
15 changes: 10 additions & 5 deletions src/main/java/com/mikuac/shiro/adapter/WebSocketServerHandler.java
Original file line number Diff line number Diff line change
@@ -19,6 +19,7 @@
import com.mikuac.shiro.task.ShiroAsyncTask;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
@@ -27,6 +28,7 @@
import java.io.IOException;
import java.util.ConcurrentModificationException;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

@@ -48,12 +50,14 @@ public class WebSocketServerHandler extends TextWebSocketHandler {
private final WebSocketProperties wsProp;
private final ScheduledTask scheduledTask;
private final ShiroProperties shiroProps;
private final ThreadPoolTaskExecutor shiroTaskExecutor;

@SuppressWarnings("java:S107")
public WebSocketServerHandler(
EventHandler eventHandler, BotFactory botFactory, ActionHandler actionHandler,
ShiroAsyncTask shiroAsyncTask, BotContainer botContainer, CoreEvent coreEvent,
WebSocketProperties wsProp, ScheduledTask scheduledTask, ShiroProperties shiroProps
WebSocketProperties wsProp, ScheduledTask scheduledTask, ShiroProperties shiroProps,
ThreadPoolTaskExecutor shiroTaskExecutor
) {
this.eventHandler = eventHandler;
this.botFactory = botFactory;
@@ -64,6 +68,7 @@ public WebSocketServerHandler(
this.wsProp = wsProp;
this.shiroProps = shiroProps;
this.scheduledTask = scheduledTask;
this.shiroTaskExecutor = shiroTaskExecutor;
}

@Override
@@ -94,14 +99,14 @@ public void afterConnectionEstablished(@NonNull WebSocketSession session) {
sessionContext.clear();
session.close();
} else {
Bot bot = ConnectionUtils.handleFirstConnect(xSelfId, session, botFactory, coreEvent);
Bot bot = ConnectionUtils.handleFirstConnect(xSelfId, session, botFactory, coreEvent, shiroTaskExecutor);
botContainer.robots.put(xSelfId, bot);
}
return;
}
botContainer.robots.compute(xSelfId, (id, bot) -> {
if (Objects.isNull(bot)) {
bot = ConnectionUtils.handleFirstConnect(xSelfId, session, botFactory, coreEvent);
bot = ConnectionUtils.handleFirstConnect(xSelfId, session, botFactory, coreEvent, shiroTaskExecutor);
} else {
ConnectionUtils.handleReConnect(bot, xSelfId, session);
}
@@ -124,7 +129,7 @@ public void afterConnectionClosed(@NonNull WebSocketSession session, @NonNull Cl
sessionContext.clear();
botContainer.robots.remove(xSelfId);
log.warn("Account {} disconnected", xSelfId);
coreEvent.offline(xSelfId);
CompletableFuture.runAsync(() -> coreEvent.offline(xSelfId), shiroTaskExecutor);
return;
}
// after the session is disconnected, postpone deletion instead of immediate removal
@@ -133,7 +138,7 @@ public void afterConnectionClosed(@NonNull WebSocketSession session, @NonNull Cl
if (botContainer.robots.containsKey(xSelfId)) {
botContainer.robots.remove(xSelfId);
log.warn("Account {} disconnected", xSelfId);
coreEvent.offline(xSelfId);
CompletableFuture.runAsync(() -> coreEvent.offline(xSelfId), shiroTaskExecutor);
}
}, shiroProps.getWaitBotConnect(), TimeUnit.SECONDS);
sessionContext.put(Connection.SESSION_STATUS_KEY, SessionStatusEnum.OFFLINE);
Loading