diff --git a/patches/server/0035-Chat-Image-protocol.patch b/patches/server/0035-Chat-Image-protocol.patch index 95468de8..e206d990 100644 --- a/patches/server/0035-Chat-Image-protocol.patch +++ b/patches/server/0035-Chat-Image-protocol.patch @@ -27,10 +27,10 @@ index 9bff9c7fce4fec7687940f4212ac05d460ab2ab5..6f151c185850738a9f8a575f9c09e3c4 syncmaticaProtocol = config.getBoolean(getBasePath() + ".syncmatica-protocol", syncmaticaProtocol); 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..87ffe8a81a8bab7d20ff9551b105487d47616ee1 +index 0000000000000000000000000000000000000000..5ef387ccfe19bb91bbcb926d44e7a01450035a1d --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/ChatImageProtocol.java -@@ -0,0 +1,160 @@ +@@ -0,0 +1,140 @@ +package org.leavesmc.leaves.protocol; + +import com.google.common.collect.Lists; @@ -83,9 +83,6 @@ index 0000000000000000000000000000000000000000..87ffe8a81a8bab7d20ff9551b105487d + } + + public record DownloadFileChannelPacket(String message) implements LeavesCustomPayload { -+ /** -+ * 发送文件分块到客户端通道(Map) -+ */ + private static final ResourceLocation DOWNLOAD_FILE_CHANNEL = ChatImageProtocol.id("download_file_channel"); + + @New @@ -106,9 +103,6 @@ index 0000000000000000000000000000000000000000..87ffe8a81a8bab7d20ff9551b105487d + } + + public record FileChannelPacket(String message) implements LeavesCustomPayload { -+ /** -+ * 客户端发送文件分块到服务器通道(Map) -+ */ + private static final ResourceLocation FILE_CHANNEL = ChatImageProtocol.id("file_channel"); + + @New @@ -130,55 +124,41 @@ index 0000000000000000000000000000000000000000..87ffe8a81a8bab7d20ff9551b105487d + + @ProtocolHandler.PayloadReceiver(payload = FileChannelPacket.class, payloadId = "file_channel") + public static void serverFileChannelReceived(ServerPlayer player, String res) { -+ if (!ProtocolSupport.chatImageProtocol) return; + ChatImageIndex title = gson.fromJson(res, ChatImageIndex.class); + HashMap 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 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 (!ProtocolSupport.chatImageProtocol) return; + if (SERVER_BLOCK_CACHE.containsKey(url) && FILE_COUNT_MAP.containsKey(url)) { + HashMap list = SERVER_BLOCK_CACHE.get(url); + Integer total = FILE_COUNT_MAP.get(url); + if (total == list.size()) { -+ // 服务器存在缓存图片,直接发送给客户端 + for (Map.Entry 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 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") diff --git a/patches/server/0091-Reduce-worldgen-allocations.patch b/patches/server/0091-Reduce-worldgen-allocations.patch index 48ec4ebd..da4f0332 100644 --- a/patches/server/0091-Reduce-worldgen-allocations.patch +++ b/patches/server/0091-Reduce-worldgen-allocations.patch @@ -10,6 +10,26 @@ Additionally, the tryApply method in SurfaceRules now avoids iterator allocation by directly accessing the rules list, which further contributes to reducing garbage collection pressure during world generation. +diff --git a/src/main/java/net/minecraft/world/level/levelgen/NoiseChunk.java b/src/main/java/net/minecraft/world/level/levelgen/NoiseChunk.java +index 5e89428321d91edb893826b0eb0b9050d327d310..2bee2988b5019d81da25784ef60feb3589f32538 100644 +--- a/src/main/java/net/minecraft/world/level/levelgen/NoiseChunk.java ++++ b/src/main/java/net/minecraft/world/level/levelgen/NoiseChunk.java +@@ -359,7 +359,14 @@ public class NoiseChunk implements DensityFunction.ContextProvider, DensityFunct + } + + protected DensityFunction wrap(DensityFunction function) { +- return this.wrapped.computeIfAbsent(function, this::wrapNew); ++ // Leaf start - Avoid lambda allocation ++ DensityFunction func = this.wrapped.get(function); ++ if (func == null) { ++ func = this.wrapNew(function); ++ this.wrapped.put(function, func); ++ } ++ return func; ++ // Leaf end + } + + private DensityFunction wrapNew(DensityFunction function) { diff --git a/src/main/java/net/minecraft/world/level/levelgen/SurfaceRules.java b/src/main/java/net/minecraft/world/level/levelgen/SurfaceRules.java index 9df053ddff459d4aab478106c6e66a5fc3cda8f6..7a9b36b93032fbbfd439b8d95c82c7515616cbbd 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/SurfaceRules.java @@ -46,6 +66,33 @@ index 9df053ddff459d4aab478106c6e66a5fc3cda8f6..7a9b36b93032fbbfd439b8d95c82c751 if (blockState != null) { return blockState; } +diff --git a/src/main/java/net/minecraft/world/level/levelgen/material/MaterialRuleList.java b/src/main/java/net/minecraft/world/level/levelgen/material/MaterialRuleList.java +index afdbc74a3012fa717f59ecef613567338d285b7b..b219a5c1a489f337ceb96a80246fa8c8121f8a4f 100644 +--- a/src/main/java/net/minecraft/world/level/levelgen/material/MaterialRuleList.java ++++ b/src/main/java/net/minecraft/world/level/levelgen/material/MaterialRuleList.java +@@ -10,13 +10,16 @@ public record MaterialRuleList(List materialRuleLis + @Nullable + @Override + public BlockState calculate(DensityFunction.FunctionContext pos) { +- for (NoiseChunk.BlockStateFiller blockStateFiller : this.materialRuleList) { +- BlockState blockState = blockStateFiller.calculate(pos); +- if (blockState != null) { +- return blockState; +- } ++ // Leaf start - avoid iterator allocation ++ BlockState blockState = null; ++ int s = this.materialRuleList.size(); ++ ++ for (int i = 0; blockState == null && i < s; i++) { ++ NoiseChunk.BlockStateFiller blockStateFiller = this.materialRuleList.get(i); ++ blockState = blockStateFiller.calculate(pos); + } + +- return null; ++ return blockState; ++ // Leaf end + } + } diff --git a/src/main/java/org/dreeam/leaf/util/biome/PositionalBiomeGetter.java b/src/main/java/org/dreeam/leaf/util/biome/PositionalBiomeGetter.java new file mode 100644 index 0000000000000000000000000000000000000000..2385f09404274aa650d082e2928deab847b570a0 diff --git a/patches/server/0098-Optimize-LeavesProtocolManager-init-protocol.patch b/patches/server/0098-Optimize-LeavesProtocolManager-init-protocol.patch index 9ae5f2c4..9e41253b 100644 --- a/patches/server/0098-Optimize-LeavesProtocolManager-init-protocol.patch +++ b/patches/server/0098-Optimize-LeavesProtocolManager-init-protocol.patch @@ -190,18 +190,10 @@ index ed8d9888a24d3ae6cf8fe2f8b269554102e451df..1bdd77078c7345db1a675fbdc26b37e9 } } diff --git a/src/main/java/org/leavesmc/leaves/protocol/ChatImageProtocol.java b/src/main/java/org/leavesmc/leaves/protocol/ChatImageProtocol.java -index 87ffe8a81a8bab7d20ff9551b105487d47616ee1..b026b9fefd85d16b0294738034bfae1220d47eac 100644 +index 25f893aad5c7fa289f484355635f528cb2e17459..1cc499393256e4eaaf2333076201fb702606462d 100644 --- a/src/main/java/org/leavesmc/leaves/protocol/ChatImageProtocol.java +++ b/src/main/java/org/leavesmc/leaves/protocol/ChatImageProtocol.java -@@ -7,7 +7,6 @@ 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.dreeam.leaf.config.modules.network.ProtocolSupport; - import org.jetbrains.annotations.Contract; - import org.jetbrains.annotations.NotNull; - import org.leavesmc.leaves.protocol.chatimage.ChatImageIndex; -@@ -30,7 +29,12 @@ public class ChatImageProtocol { +@@ -30,7 +30,12 @@ public class ChatImageProtocol { public static int MAX_STRING = 532767; private static final Gson gson = new Gson(); @@ -215,42 +207,6 @@ index 87ffe8a81a8bab7d20ff9551b105487d47616ee1..b026b9fefd85d16b0294738034bfae12 private static final ResourceLocation FILE_INFO = ChatImageProtocol.id("file_info"); @New -@@ -49,7 +53,8 @@ public class ChatImageProtocol { - } - } - -- public record DownloadFileChannelPacket(String message) implements LeavesCustomPayload { -+ public record DownloadFileChannelPacket( -+ String message) implements LeavesCustomPayload { - /** - * 发送文件分块到客户端通道(Map) - */ -@@ -72,7 +77,8 @@ public class ChatImageProtocol { - - } - -- public record FileChannelPacket(String message) implements LeavesCustomPayload { -+ public record FileChannelPacket( -+ String message) implements LeavesCustomPayload { - /** - * 客户端发送文件分块到服务器通道(Map) - */ -@@ -97,7 +103,6 @@ public class ChatImageProtocol { - - @ProtocolHandler.PayloadReceiver(payload = FileChannelPacket.class, payloadId = "file_channel") - public static void serverFileChannelReceived(ServerPlayer player, String res) { -- if (!ProtocolSupport.chatImageProtocol) return; - ChatImageIndex title = gson.fromJson(res, ChatImageIndex.class); - HashMap blocks = SERVER_BLOCK_CACHE.containsKey(title.url) ? SERVER_BLOCK_CACHE.get(title.url) : new HashMap<>(); - blocks.put(title.index, res); -@@ -123,7 +128,6 @@ public class ChatImageProtocol { - - @ProtocolHandler.PayloadReceiver(payload = FileInfoChannelPacket.class, payloadId = "file_info") - public static void serverFileInfoChannelReceived(ServerPlayer player, String url) { -- if (!ProtocolSupport.chatImageProtocol) return; - if (SERVER_BLOCK_CACHE.containsKey(url) && FILE_COUNT_MAP.containsKey(url)) { - HashMap list = SERVER_BLOCK_CACHE.get(url); - Integer total = FILE_COUNT_MAP.get(url); diff --git a/src/main/java/org/leavesmc/leaves/protocol/XaeroMapProtocol.java b/src/main/java/org/leavesmc/leaves/protocol/XaeroMapProtocol.java index 9e35dfaf8bb5511b4cd0a71175d7ecb6d835042f..5ef19098512ae8a070dea270a68c27695c34624b 100644 --- a/src/main/java/org/leavesmc/leaves/protocol/XaeroMapProtocol.java