forked from LeavesMC/Leaves
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add ChatImage Protocol and AsteorBar Protocol
- Loading branch information
1 parent
ebac668
commit 7035899
Showing
2 changed files
with
337 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,208 @@ | ||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | ||
From: CerealAxis <2741798712@qq.com> | ||
Date: Mon, 17 Jun 2024 21:38:25 +0800 | ||
Subject: [PATCH] Leaf-ChatImage-Protocol | ||
|
||
|
||
diff --git a/src/main/java/org/leavesmc/leaves/LeavesConfig.java b/src/main/java/org/leavesmc/leaves/LeavesConfig.java | ||
index f74e84d68b043de8c9180d58f7f60da7fb19beaf..25949297734351ef566d6769da4b76bc790cbd65 100644 | ||
--- a/src/main/java/org/leavesmc/leaves/LeavesConfig.java | ||
+++ b/src/main/java/org/leavesmc/leaves/LeavesConfig.java | ||
@@ -766,6 +766,9 @@ public final class LeavesConfig { | ||
@GlobalConfig(name = "leaves-carpet-support", category = "protocol") | ||
public static boolean leavesCarpetSupport = false; | ||
|
||
+ @GlobalConfig(name = "Chat-Image-support", category = "protocol") | ||
+ public static boolean chatimageSupport = false; | ||
+ | ||
// Leaves end - protocol | ||
|
||
// Leaves start - misc | ||
diff --git a/src/main/java/org/leavesmc/leaves/protocol/ChatImageProtocol.java b/src/main/java/org/leavesmc/leaves/protocol/ChatImageProtocol.java | ||
new file mode 100644 | ||
index 0000000000000000000000000000000000000000..93ecd42a3140ed23187b7475797a5a6f9dffce3c | ||
--- /dev/null | ||
+++ b/src/main/java/org/leavesmc/leaves/protocol/ChatImageProtocol.java | ||
@@ -0,0 +1,160 @@ | ||
+package org.leavesmc.leaves.protocol; | ||
+ | ||
+import com.google.common.collect.Lists; | ||
+import com.google.gson.Gson; | ||
+import net.minecraft.network.FriendlyByteBuf; | ||
+import net.minecraft.network.protocol.Packet; | ||
+import net.minecraft.network.protocol.common.custom.CustomPacketPayload; | ||
+import net.minecraft.resources.ResourceLocation; | ||
+import net.minecraft.server.level.ServerPlayer; | ||
+import org.jetbrains.annotations.Contract; | ||
+import org.jetbrains.annotations.NotNull; | ||
+import org.leavesmc.leaves.LeavesConfig; | ||
+import org.leavesmc.leaves.protocol.chatimage.ChatImageIndex; | ||
+import org.leavesmc.leaves.protocol.core.LeavesCustomPayload; | ||
+import org.leavesmc.leaves.protocol.core.LeavesProtocol; | ||
+import org.leavesmc.leaves.protocol.core.LeavesProtocolManager; | ||
+import org.leavesmc.leaves.protocol.core.ProtocolHandler; | ||
+ | ||
+import java.util.HashMap; | ||
+import java.util.List; | ||
+import java.util.Map; | ||
+import java.util.UUID; | ||
+ | ||
+@LeavesProtocol(namespace = "chatimage") | ||
+public class ChatImageProtocol { | ||
+ public static final String PROTOCOL_ID = "chatimage"; | ||
+ private static final Map<String, HashMap<Integer, String>> SERVER_BLOCK_CACHE = new HashMap<>(); | ||
+ private static final Map<String, Integer> FILE_COUNT_MAP = new HashMap<>(); | ||
+ private static final Map<String, List<String>> USER_CACHE_MAP = new HashMap<>(); | ||
+ public static int MAX_STRING = 532767; | ||
+ private static final Gson gson = new Gson(); | ||
+ | ||
+ public record FileInfoChannelPacket(String message) implements LeavesCustomPayload<LeavesProtocolManager.LeavesPayload> { | ||
+ private static final ResourceLocation FILE_INFO = ChatImageProtocol.id("file_info"); | ||
+ | ||
+ @New | ||
+ public FileInfoChannelPacket(ResourceLocation id, FriendlyByteBuf buffer) { | ||
+ this(buffer.readUtf(MAX_STRING)); | ||
+ } | ||
+ | ||
+ @Override | ||
+ public void write(final FriendlyByteBuf buffer) { | ||
+ buffer.writeUtf(message(), MAX_STRING); | ||
+ } | ||
+ | ||
+ @Override | ||
+ public @NotNull ResourceLocation id() { | ||
+ return FILE_INFO; | ||
+ } | ||
+ } | ||
+ | ||
+ public record DownloadFileChannelPacket(String message) implements LeavesCustomPayload<LeavesProtocolManager.LeavesPayload> { | ||
+ /** | ||
+ * 发送文件分块到客户端通道(Map) | ||
+ */ | ||
+ private static final ResourceLocation DOWNLOAD_FILE_CHANNEL = ChatImageProtocol.id("download_file_channel"); | ||
+ | ||
+ @New | ||
+ public DownloadFileChannelPacket(ResourceLocation id, FriendlyByteBuf buffer) { | ||
+ this(buffer.readUtf(MAX_STRING)); | ||
+ } | ||
+ | ||
+ @Override | ||
+ public void write(final FriendlyByteBuf buffer) { | ||
+ buffer.writeUtf(message(), MAX_STRING); | ||
+ } | ||
+ | ||
+ @Override | ||
+ public @NotNull ResourceLocation id() { | ||
+ return DOWNLOAD_FILE_CHANNEL; | ||
+ } | ||
+ | ||
+ } | ||
+ | ||
+ public record FileChannelPacket(String message) implements LeavesCustomPayload<LeavesProtocolManager.LeavesPayload> { | ||
+ /** | ||
+ * 客户端发送文件分块到服务器通道(Map) | ||
+ */ | ||
+ private static final ResourceLocation FILE_CHANNEL = ChatImageProtocol.id("file_channel"); | ||
+ | ||
+ @New | ||
+ public FileChannelPacket(ResourceLocation id, FriendlyByteBuf buffer) { | ||
+ this(buffer.readUtf(MAX_STRING)); | ||
+ } | ||
+ | ||
+ @Override | ||
+ public void write(final FriendlyByteBuf buffer) { | ||
+ buffer.writeUtf(message(), MAX_STRING); | ||
+ } | ||
+ | ||
+ @Override | ||
+ public @NotNull ResourceLocation id() { | ||
+ return FILE_CHANNEL; | ||
+ } | ||
+ | ||
+ } | ||
+ | ||
+ @ProtocolHandler.PayloadReceiver(payload = FileChannelPacket.class, payloadId = "file_channel") | ||
+ public static void serverFileChannelReceived(ServerPlayer player, String res) { | ||
+ if (!LeavesConfig.chatimageSupport) return; | ||
+ ChatImageIndex title = gson.fromJson(res, ChatImageIndex.class); | ||
+ HashMap<Integer, String> blocks = SERVER_BLOCK_CACHE.containsKey(title.url) ? SERVER_BLOCK_CACHE.get(title.url) : new HashMap<>(); | ||
+ blocks.put(title.index, res); | ||
+ SERVER_BLOCK_CACHE.put(title.url, blocks); | ||
+ FILE_COUNT_MAP.put(title.url, title.total); | ||
+ //System.out.println("[FileChannel->Server:" + title.index + "/" + title.total + "]" + title.url); | ||
+ if (title.total == blocks.size()) { | ||
+ if (USER_CACHE_MAP.containsKey(title.url)) { | ||
+ // 通知之前请求但是没图片的客户端 | ||
+ List<String> names = USER_CACHE_MAP.get(title.url); | ||
+ for (String uuid : names) { | ||
+ ServerPlayer serverPlayer = player.server.getPlayerList().getPlayer(UUID.fromString(uuid)); | ||
+ if (serverPlayer != null) { | ||
+ sendToPlayer(new FileInfoChannelPacket("true->" + title.url), serverPlayer); | ||
+ } | ||
+ //System.out.println("[echo to client(" + uuid + ")]" + title.url); | ||
+ } | ||
+ USER_CACHE_MAP.put(title.url, Lists.newArrayList()); | ||
+ } | ||
+ //System.out.println("[FileChannel->Server]" + title.url); | ||
+ } | ||
+ } | ||
+ | ||
+ @ProtocolHandler.PayloadReceiver(payload = FileInfoChannelPacket.class, payloadId = "file_info") | ||
+ public static void serverFileInfoChannelReceived(ServerPlayer player, String url) { | ||
+ if (!LeavesConfig.chatimageSupport) return; | ||
+ if (SERVER_BLOCK_CACHE.containsKey(url) && FILE_COUNT_MAP.containsKey(url)) { | ||
+ HashMap<Integer, String> list = SERVER_BLOCK_CACHE.get(url); | ||
+ Integer total = FILE_COUNT_MAP.get(url); | ||
+ if (total == list.size()) { | ||
+ // 服务器存在缓存图片,直接发送给客户端 | ||
+ for (Map.Entry<Integer, String> entry : list.entrySet()) { | ||
+ //System.out.println("[GetFileChannel->Client:" + entry.getKey() + "/" + (list.size() - 1) + "]" + url); | ||
+ sendToPlayer(new DownloadFileChannelPacket(entry.getValue()), player); | ||
+ } | ||
+ //System.out.println("[GetFileChannel->Client]" + url); | ||
+ return; | ||
+ } | ||
+ } | ||
+ //通知客户端无文件 | ||
+ sendToPlayer(new FileInfoChannelPacket("null->" + url), player); | ||
+ //System.out.println("[GetFileChannel]not found in server:" + url); | ||
+ // 记录uuid,后续有文件了推送 | ||
+ List<String> names = USER_CACHE_MAP.containsKey(url) ? USER_CACHE_MAP.get(url) : Lists.newArrayList(); | ||
+ names.add(player.getStringUUID()); | ||
+ USER_CACHE_MAP.put(url, names); | ||
+ //System.out.println("[GetFileChannel]记录uuid:" + player.getStringUUID()); | ||
+ //System.out.println("[not found in server]" + url); | ||
+ } | ||
+ | ||
+ @Contract("_ -> new") | ||
+ public static @NotNull ResourceLocation id(String path) { | ||
+ return new ResourceLocation(PROTOCOL_ID, path); | ||
+ } | ||
+ | ||
+ public static void sendToPlayer(CustomPacketPayload payload, ServerPlayer player) { | ||
+ player.connection.send((Packet<?>) payload); | ||
+ } | ||
+ | ||
+} | ||
diff --git a/src/main/java/org/leavesmc/leaves/protocol/chatimage/ChatImageIndex.java b/src/main/java/org/leavesmc/leaves/protocol/chatimage/ChatImageIndex.java | ||
new file mode 100644 | ||
index 0000000000000000000000000000000000000000..369917ae4b82b6c1d480a5ac5ebd00e0c55f1fb5 | ||
--- /dev/null | ||
+++ b/src/main/java/org/leavesmc/leaves/protocol/chatimage/ChatImageIndex.java | ||
@@ -0,0 +1,15 @@ | ||
+package org.leavesmc.leaves.protocol.chatimage; | ||
+ | ||
+public class ChatImageIndex { | ||
+ public int index; | ||
+ public int total; | ||
+ public String url; | ||
+ public String bytes; | ||
+ | ||
+ public ChatImageIndex(int index, int total, String url, String bytes) { | ||
+ this.index = index; | ||
+ this.total = total; | ||
+ this.url = url; | ||
+ this.bytes = bytes; | ||
+ } | ||
+} | ||
\ No newline at end of file |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | ||
From: CerealAxis <2741798712@qq.com> | ||
Date: Mon, 17 Jun 2024 21:38:42 +0800 | ||
Subject: [PATCH] Leaf-AsteorBar-Protocol | ||
|
||
|
||
diff --git a/src/main/java/org/leavesmc/leaves/LeavesConfig.java b/src/main/java/org/leavesmc/leaves/LeavesConfig.java | ||
index 25949297734351ef566d6769da4b76bc790cbd65..ac5ae104bd29af77ac251038ec40f977815a45db 100644 | ||
--- a/src/main/java/org/leavesmc/leaves/LeavesConfig.java | ||
+++ b/src/main/java/org/leavesmc/leaves/LeavesConfig.java | ||
@@ -766,6 +766,9 @@ public final class LeavesConfig { | ||
@GlobalConfig(name = "leaves-carpet-support", category = "protocol") | ||
public static boolean leavesCarpetSupport = false; | ||
|
||
+ @GlobalConfig(name = "asteor-bar-protocol", category = "protocol") | ||
+ public static boolean asteorbarProtocol = false; | ||
+ | ||
@GlobalConfig(name = "Chat-Image-support", category = "protocol") | ||
public static boolean chatimageSupport = false; | ||
|
||
diff --git a/src/main/java/org/leavesmc/leaves/protocol/AsteorBarProtocol.java b/src/main/java/org/leavesmc/leaves/protocol/AsteorBarProtocol.java | ||
new file mode 100644 | ||
index 0000000000000000000000000000000000000000..3db86d1710cc474d13cd1f2f6f91919f6067b198 | ||
--- /dev/null | ||
+++ b/src/main/java/org/leavesmc/leaves/protocol/AsteorBarProtocol.java | ||
@@ -0,0 +1,103 @@ | ||
+package org.leavesmc.leaves.protocol; | ||
+ | ||
+import net.minecraft.resources.ResourceLocation; | ||
+import net.minecraft.server.MinecraftServer; | ||
+import net.minecraft.server.level.ServerPlayer; | ||
+import net.minecraft.world.food.FoodData; | ||
+import org.jetbrains.annotations.Contract; | ||
+import org.jetbrains.annotations.NotNull; | ||
+import org.leavesmc.leaves.LeavesConfig; | ||
+import org.leavesmc.leaves.protocol.core.LeavesProtocol; | ||
+import org.leavesmc.leaves.protocol.core.ProtocolHandler; | ||
+import org.leavesmc.leaves.protocol.core.ProtocolUtils; | ||
+ | ||
+import java.util.*; | ||
+ | ||
+@LeavesProtocol(namespace = "asteorbar") | ||
+public class AsteorBarProtocol { | ||
+ | ||
+ public static final String PROTOCOL_ID = "asteorbar"; | ||
+ | ||
+ private static final ResourceLocation NETWORK_KEY = id("network"); | ||
+ | ||
+ private static final Map<UUID, Float> previousSaturationLevels = new HashMap<>(); | ||
+ private static final Map<UUID, Float> previousExhaustionLevels = new HashMap<>(); | ||
+ | ||
+ private static final float THRESHOLD = 0.01F; | ||
+ | ||
+ private static final Set<ServerPlayer> players = new HashSet<>(); | ||
+ | ||
+ @Contract("_ -> new") | ||
+ public static @NotNull ResourceLocation id(String path) { | ||
+ return new ResourceLocation(PROTOCOL_ID, path); | ||
+ } | ||
+ | ||
+ @ProtocolHandler.PlayerJoin | ||
+ public static void onPlayerLoggedIn(@NotNull ServerPlayer player) { | ||
+ if (LeavesConfig.asteorbarProtocol) { | ||
+ resetPlayerData(player); | ||
+ } | ||
+ } | ||
+ | ||
+ @ProtocolHandler.PlayerLeave | ||
+ public static void onPlayerLoggedOut(@NotNull ServerPlayer player) { | ||
+ if (LeavesConfig.asteorbarProtocol) { | ||
+ players.remove(player); | ||
+ resetPlayerData(player); | ||
+ } | ||
+ } | ||
+ | ||
+ @ProtocolHandler.MinecraftRegister(ignoreId = true) | ||
+ public static void onPlayerSubscribed(@NotNull ServerPlayer player) { | ||
+ if (LeavesConfig.asteorbarProtocol) { | ||
+ players.add(player); | ||
+ } | ||
+ } | ||
+ | ||
+ @ProtocolHandler.Ticker | ||
+ public static void tick() { | ||
+ if (LeavesConfig.asteorbarProtocol) { | ||
+ for (ServerPlayer player : players) { | ||
+ FoodData data = player.getFoodData(); | ||
+ | ||
+ float saturation = data.getSaturationLevel(); | ||
+ Float previousSaturation = previousSaturationLevels.get(player.getUUID()); | ||
+ if (previousSaturation == null || saturation != previousSaturation) { | ||
+ ProtocolUtils.sendPayloadPacket(player, NETWORK_KEY, buf -> { | ||
+ buf.writeByte(1); | ||
+ buf.writeFloat(saturation); | ||
+ }); | ||
+ previousSaturationLevels.put(player.getUUID(), saturation); | ||
+ } | ||
+ | ||
+ float exhaustion = data.getExhaustionLevel(); | ||
+ Float previousExhaustion = previousExhaustionLevels.get(player.getUUID()); | ||
+ if (previousExhaustion == null || Math.abs(exhaustion - previousExhaustion) >= THRESHOLD) { | ||
+ ProtocolUtils.sendPayloadPacket(player, NETWORK_KEY, buf -> { | ||
+ buf.writeByte(0); | ||
+ buf.writeFloat(exhaustion); | ||
+ }); | ||
+ previousExhaustionLevels.put(player.getUUID(), exhaustion); | ||
+ } | ||
+ } | ||
+ } | ||
+ } | ||
+ | ||
+ @ProtocolHandler.ReloadServer | ||
+ public static void onServerReload() { | ||
+ if (LeavesConfig.asteorbarProtocol) { | ||
+ disableAllPlayer(); | ||
+ } | ||
+ } | ||
+ | ||
+ public static void disableAllPlayer() { | ||
+ for (ServerPlayer player : MinecraftServer.getServer().getPlayerList().getPlayers()) { | ||
+ onPlayerLoggedOut(player); | ||
+ } | ||
+ } | ||
+ | ||
+ private static void resetPlayerData(@NotNull ServerPlayer player) { | ||
+ previousExhaustionLevels.remove(player.getUUID()); | ||
+ previousSaturationLevels.remove(player.getUUID()); | ||
+ } | ||
+} |