8 Commits

Author SHA1 Message Date
a084d39b02 Update version to v1.6.1 2023-06-04 20:05:50 +08:00
6c19c09c00 Fix deserialization formatting error (#185) 2023-06-04 20:05:32 +08:00
c6e0b51ea6 Fix deserialization formatting error 2023-06-03 00:27:34 +08:00
bcb88740f1 Upgrade to 1.6.0 2023-06-03 00:11:12 +08:00
290c4fbf8c DON'T LOCK PLAYER! 2023-05-21 21:41:37 +08:00
564f4d1e56 Fix CI branch 2023-05-21 21:14:41 +08:00
66fb25aa9b Add url to enable log 2023-05-21 21:04:02 +08:00
c3c2ed08a7 Update player command response handler 2023-05-21 20:51:12 +08:00
8 changed files with 68 additions and 30 deletions

View File

@@ -5,7 +5,7 @@ on:
paths:
- "**.java"
branches:
- "main"
- "master"
pull_request:
paths:
- "**.java"

View File

@@ -4,7 +4,7 @@ plugins {
}
group 'com.github.jie65535.opencommand'
version '1.5.2'
version '1.6.1'
sourceCompatibility = 17
targetCompatibility = 17

View File

@@ -24,24 +24,52 @@ import emu.grasscutter.game.player.Player;
import emu.grasscutter.server.event.game.ReceiveCommandFeedbackEvent;
import emu.grasscutter.server.event.player.PlayerJoinEvent;
import emu.grasscutter.server.event.player.PlayerQuitEvent;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import java.util.ArrayList;
public final class EventListeners {
private static StringBuilder consoleMessageHandler;
private static final Int2ObjectMap<StringBuilder> playerMessageHandlers = new Int2ObjectOpenHashMap<>();
public static void setConsoleMessageHandler(StringBuilder handler) {
consoleMessageHandler = handler;
}
/**
* 获取新的玩家消息处理类
* 获取时将创建或清空消息处理器并返回实例,**在执行命令前获取!**
* @param uid 玩家uid
* @return 新的玩家消息处理类
*/
public static StringBuilder getPlayerMessageHandler(int uid) {
var handler = playerMessageHandlers.get(uid);
if (handler == null) {
handler = new StringBuilder();
playerMessageHandlers.put(uid, handler);
}
return handler;
}
/**
* 命令执行反馈事件处理
*/
public static void onCommandResponse(ReceiveCommandFeedbackEvent event) {
if (consoleMessageHandler != null && event.getPlayer() == null) {
if (!consoleMessageHandler.isEmpty()) {
StringBuilder handler;
if (event.getPlayer() == null) {
handler = consoleMessageHandler;
} else {
handler = playerMessageHandlers.get(event.getPlayer().getUid());
}
if (handler != null) {
if (!handler.isEmpty()) {
// New line
consoleMessageHandler.append(System.lineSeparator());
handler.append(System.lineSeparator());
}
consoleMessageHandler.append(event.getMessage());
handler.append(event.getMessage());
}
}
@@ -60,6 +88,10 @@ public final class EventListeners {
SocketClient.sendPacket(playerList);
}
/**
* 仅游戏模式下玩家离开事件处理方法
* 用于更新玩家列表
*/
public static void onPlayerQuit(PlayerQuitEvent playerQuitEvent) {
PlayerList playerList = new PlayerList();
playerList.player = Grasscutter.getGameServer().getPlayers().size();
@@ -73,4 +105,15 @@ public final class EventListeners {
playerList.playerList = playerNames;
SocketClient.sendPacket(playerList);
}
/**
* 玩家离开事件处理 2
* 用于清理内存
*/
public static void onPlayerQuit2(PlayerQuitEvent playerQuitEvent) {
var uid = playerQuitEvent.getPlayer().getUid();
if (playerMessageHandlers.containsKey(uid)) {
playerMessageHandlers.remove(uid);
}
}
}

View File

@@ -24,7 +24,6 @@ import com.github.jie65535.opencommand.socket.SocketData;
import emu.grasscutter.command.CommandMap;
import emu.grasscutter.server.http.Router;
import emu.grasscutter.utils.Crypto;
import emu.grasscutter.utils.MessageHandler;
import emu.grasscutter.utils.Utils;
import io.javalin.Javalin;
import io.javalin.http.Context;
@@ -46,7 +45,6 @@ public final class OpenCommandHandler implements Router {
private static final Map<String, Integer> codes = new HashMap<>();
private static final Int2ObjectMap<Date> codeExpireTime = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<MessageHandler> playerMessageHandlers = new Int2ObjectOpenHashMap<>();
public static void handle(Context context) {
var plugin = OpenCommandPlugin.getInstance();
@@ -60,7 +58,7 @@ public final class OpenCommandHandler implements Router {
var req = context.bodyAsClass(JsonRequest.class);
if (req.action.equals("sendCode")) {
int playerId = (int) req.data;
int playerId = (int)Double.parseDouble(req.data.toString());
var player = plugin.getServer().getPlayerByUid(playerId);
if (player == null) {
context.json(new JsonResponse(404, "Player Not Found."));
@@ -155,23 +153,16 @@ public final class OpenCommandHandler implements Router {
return;
}
// Player MessageHandler do not support concurrency
var handler = playerMessageHandlers.get(player.getUid());
if (handler == null) {
handler = new MessageHandler();
playerMessageHandlers.put(player.getUid(), handler);
}
var handler = EventListeners.getPlayerMessageHandler(player.getUid());
//noinspection SynchronizationOnLocalVariableOrMethodParameter
synchronized (handler) {
try {
handler.setMessage("");
player.setMessageHandler(handler);
handler.setLength(0);
CommandMap.getInstance().invoke(player, player, command);
context.json(new JsonResponse(handler.getMessage()));
context.json(new JsonResponse(handler.toString()));
} catch (Exception e) {
plugin.getLogger().warn("Run command failed.", e);
context.json(new JsonResponse(500, "error", e.getLocalizedMessage()));
} finally {
player.setMessageHandler(null);
}
}
return;

View File

@@ -61,7 +61,7 @@ public final class OpenCommandOnlyHttpHandler implements Router {
var req = context.bodyAsClass(JsonRequest.class);
if (req.action.equals("sendCode")) {
int playerId = (int) req.data;
int playerId = (int)Double.parseDouble(req.data.toString());
var player = SocketData.getPlayer(playerId);
if (player == null) {
context.json(new JsonResponse(404, "Player Not Found."));

View File

@@ -59,10 +59,16 @@ public final class OpenCommandPlugin extends Plugin {
@Override
public void onEnable() {
// 监听命令执行反馈
new EventHandler<>(ReceiveCommandFeedbackEvent.class)
.priority(HandlerPriority.HIGH)
.listener(EventListeners::onCommandResponse)
.register(this);
// 监听玩家离开事件
new EventHandler<>(PlayerQuitEvent.class)
.priority(HandlerPriority.NORMAL)
.listener(EventListeners::onPlayerQuit2)
.register(this);
if (runMode == Grasscutter.ServerRunMode.GAME_ONLY) {
// 仅运行游戏服务器时注册玩家加入和离开事件
new EventHandler<>(PlayerJoinEvent.class)
@@ -78,7 +84,7 @@ public final class OpenCommandPlugin extends Plugin {
} else {
getHandle().addRouter(OpenCommandHandler.class);
}
getLogger().info("[OpenCommand] Enabled");
getLogger().info("[OpenCommand] Enabled. https://github.com/jie65535/gc-opencommand-plugin");
}
@Override

View File

@@ -26,7 +26,6 @@ import com.github.jie65535.opencommand.socket.packet.player.PlayerList;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.command.CommandMap;
import emu.grasscutter.utils.JsonUtils;
import emu.grasscutter.utils.MessageHandler;
import org.slf4j.Logger;
import java.io.IOException;
@@ -161,18 +160,16 @@ public class SocketClient {
return;
}
// Player MessageHandler do not support concurrency
var handler = EventListeners.getPlayerMessageHandler(playerData.getUid());
//noinspection SynchronizationOnLocalVariableOrMethodParameter
synchronized (playerData) {
synchronized (handler) {
try {
var resultCollector = new MessageHandler();
playerData.setMessageHandler(resultCollector);
handler.setLength(0);
CommandMap.getInstance().invoke(playerData, playerData, command);
sendPacket(new HttpPacket(200, resultCollector.getMessage()), packet.packetID);
sendPacket(new HttpPacket(200, handler.toString()), packet.packetID);
} catch (Exception e) {
OpenCommandPlugin.getInstance().getLogger().warn("[OpenCommand] Run command failed.", e);
sendPacket(new HttpPacket(500, "error", e.getLocalizedMessage()), packet.packetID);
} finally {
playerData.setMessageHandler(null);
}
}
}

View File

@@ -1,7 +1,8 @@
{
"name": "opencommand-plugin",
"description": "Open command interface for third-party clients",
"version": "dev-1.5.2",
"version": "1.6.1",
"mainClass": "com.github.jie65535.opencommand.OpenCommandPlugin",
"authors": ["jie65535", "方块君"]
"authors": ["jie65535", "方块君"],
"api": 2
}