Skip to content

Commit 950313e

Browse files
author
bb-dev
committed
feat: add Java custom payload bridge sender
1 parent f30f652 commit 950313e

3 files changed

Lines changed: 62 additions & 2 deletions

File tree

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package org.itxtech.synapseapi.java;
2+
3+
import org.itxtech.synapseapi.SynapsePlayer;
4+
import org.itxtech.synapseapi.multiprotocol.protocol11810.protocol.ScriptMessagePacket11810;
5+
6+
import java.util.Objects;
7+
import java.util.Optional;
8+
9+
/**
10+
* Java 客户端自定义载荷的双向桥接入口。
11+
*/
12+
public final class JavaCustomPayloadBridge {
13+
14+
private JavaCustomPayloadBridge() {
15+
}
16+
17+
public static boolean send(final SynapsePlayer player, final String channel, final byte[] payload) {
18+
Objects.requireNonNull(player, "player");
19+
if (!player.isOnline() || !player.isJavaClient()) {
20+
return false;
21+
}
22+
final Optional<String> encoded = JavaCustomPayloadEnvelope.encode(channel, payload);
23+
if (encoded.isEmpty()) {
24+
return false;
25+
}
26+
final ScriptMessagePacket11810 packet = new ScriptMessagePacket11810();
27+
packet.messageId = JavaCustomPayloadEnvelope.SCRIPT_MESSAGE_ID;
28+
packet.value = encoded.get();
29+
return player.dataPacket(packet);
30+
}
31+
}

src/main/java/org/itxtech/synapseapi/java/JavaCustomPayloadEnvelope.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,17 @@
77
import java.util.Arrays;
88
import java.util.Base64;
99
import java.util.Optional;
10+
import java.util.regex.Pattern;
1011

1112
/**
12-
* ViaBedrock 输出的受限 Java 自定义载荷信封解码器。
13-
* 与商业功能解耦,插件收到通用事件后自行决定是否处理频道。
13+
* ViaBedrock 双向 Java 自定义载荷桥的 ScriptMessage 信封编解码器。
1414
*/
1515
public final class JavaCustomPayloadEnvelope {
1616

1717
public static final String SCRIPT_MESSAGE_ID = "easecation:java_custom_payload_v1";
1818
public static final int MAX_CHANNEL_BYTES = 128;
1919
public static final int MAX_PAYLOAD_BYTES = 8 * 1024;
20+
private static final Pattern CHANNEL_PATTERN = Pattern.compile("[a-z0-9_.-]+:[a-z0-9/._-]+");
2021

2122
private JavaCustomPayloadEnvelope() {
2223
}
@@ -52,6 +53,21 @@ public static Optional<Payload> decode(final String messageId, final String enco
5253
}
5354
}
5455

56+
public static Optional<String> encode(final String channel, final byte[] payload) {
57+
if (channel == null || payload == null || !CHANNEL_PATTERN.matcher(channel).matches()) {
58+
return Optional.empty();
59+
}
60+
final byte[] channelBytes = channel.getBytes(StandardCharsets.UTF_8);
61+
if (channelBytes.length == 0 || channelBytes.length > MAX_CHANNEL_BYTES || payload.length > MAX_PAYLOAD_BYTES) {
62+
return Optional.empty();
63+
}
64+
final byte[] envelope = new byte[1 + channelBytes.length + payload.length];
65+
envelope[0] = (byte) channelBytes.length;
66+
System.arraycopy(channelBytes, 0, envelope, 1, channelBytes.length);
67+
System.arraycopy(payload, 0, envelope, 1 + channelBytes.length, payload.length);
68+
return Optional.of(Base64.getUrlEncoder().withoutPadding().encodeToString(envelope));
69+
}
70+
5571
private static boolean isUnpaddedBase64Url(String value) {
5672
if (value == null || value.isEmpty()) {
5773
return false;

src/test/java/org/itxtech/synapseapi/java/JavaCustomPayloadEnvelopeTest.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,19 @@ void decodesOnlyTheFixedBridgeEnvelopeAndDefensivelyCopiesPayload() {
3232
assertFalse(JavaCustomPayloadEnvelope.decode("other:message", "AA").isPresent());
3333
}
3434

35+
@Test
36+
void encodesTheSameEnvelopeThatTheDecoderAccepts() {
37+
byte[] payload = new byte[]{2, 1, 0, -1};
38+
39+
String encoded = JavaCustomPayloadEnvelope.encode("easecation:launcher_commerce", payload).orElseThrow();
40+
JavaCustomPayloadEnvelope.Payload decoded = JavaCustomPayloadEnvelope.decode(
41+
JavaCustomPayloadEnvelope.SCRIPT_MESSAGE_ID, encoded).orElseThrow();
42+
43+
assertEquals("easecation:launcher_commerce", decoded.channel());
44+
assertArrayEquals(payload, decoded.payload());
45+
assertTrue(JavaCustomPayloadEnvelope.encode("invalid channel", payload).isEmpty());
46+
}
47+
3548
@Test
3649
void rejectsMalformedOrOverLimitEnvelopes() {
3750
byte[] malformedUtf8 = new byte[]{1, -1};

0 commit comments

Comments
 (0)