Skip to content

Commit fba2233

Browse files
committed
perf: dedupe map sends and cleanup player cache on quit
1 parent 18f0c39 commit fba2233

1 file changed

Lines changed: 39 additions & 12 deletions

File tree

src/main/java/io/github/md5sha256/SmartMapLoader/SmartMapLoader.java

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
package io.github.md5sha256.SmartMapLoader;
22

33
import io.papermc.paper.event.packet.PlayerChunkLoadEvent;
4-
import java.util.Arrays;
4+
import java.util.HashMap;
5+
import java.util.Map;
6+
import java.util.UUID;
57
import org.bukkit.Material;
68
import org.bukkit.entity.Entity;
79
import org.bukkit.entity.ItemFrame;
810
import org.bukkit.entity.Player;
911
import org.bukkit.event.EventHandler;
1012
import org.bukkit.event.Listener;
1113
import org.bukkit.event.player.PlayerInteractEntityEvent;
14+
import org.bukkit.event.player.PlayerQuitEvent;
1215
import org.bukkit.event.player.PlayerShowEntityEvent;
1316
import org.bukkit.inventory.ItemStack;
1417
import org.bukkit.inventory.meta.ItemMeta;
@@ -17,6 +20,9 @@
1720
import org.bukkit.plugin.java.JavaPlugin;
1821

1922
public final class SmartMapLoader extends JavaPlugin implements Listener {
23+
private static final long MAP_SEND_DEDUPE_MS = 300L;
24+
private final Map<UUID, Map<Integer, Long>> lastMapSendByPlayer = new HashMap<>();
25+
2026
public void onEnable() {
2127
this.getServer().getPluginManager().registerEvents(this, this);
2228
}
@@ -28,15 +34,16 @@ public void onDisable() {
2834
public void onChunkSend(PlayerChunkLoadEvent event) {
2935
Entity[] entities = event.getChunk().getEntities();
3036
Player player = event.getPlayer();
31-
Arrays.stream(entities)
32-
.filter(ItemFrame.class::isInstance)
33-
.map(ItemFrame.class::cast)
34-
.forEach(frame -> {
35-
ItemStack item = frame.getItem();
36-
if (item != null) {
37-
this.showMapItem(item, player);
38-
}
39-
});
37+
for (Entity entity : entities) {
38+
if (!(entity instanceof ItemFrame frame)) {
39+
continue;
40+
}
41+
42+
ItemStack item = frame.getItem();
43+
if (item != null) {
44+
this.showMapItem(item, player);
45+
}
46+
}
4047
}
4148

4249
@EventHandler
@@ -67,10 +74,17 @@ public void onMapPlacedInItemFrame(PlayerInteractEntityEvent event) {
6774
return;
6875
}
6976

70-
itemFrame.getTrackedBy().forEach(viewer -> this.showMapItem(frameItem, viewer));
77+
for (Player viewer : itemFrame.getTrackedBy()) {
78+
this.showMapItem(frameItem, viewer);
79+
}
7180
});
7281
}
7382

83+
@EventHandler
84+
public void onPlayerQuit(PlayerQuitEvent event) {
85+
this.lastMapSendByPlayer.remove(event.getPlayer().getUniqueId());
86+
}
87+
7488
private void showMapItem(ItemStack item, Player player) {
7589
if (item == null || item.getType() != Material.FILLED_MAP || !item.hasItemMeta()) {
7690
return;
@@ -82,9 +96,22 @@ private void showMapItem(ItemStack item, Player player) {
8296
}
8397

8498
MapView mapView = mapMeta.getMapView();
85-
if (mapView != null) {
99+
if (mapView != null && this.shouldSendMap(player, mapView.getId())) {
86100
player.sendMap(mapView);
87101
}
88102
}
103+
104+
private boolean shouldSendMap(Player player, int mapId) {
105+
long now = System.currentTimeMillis();
106+
UUID playerId = player.getUniqueId();
107+
Map<Integer, Long> lastSentByMap = this.lastMapSendByPlayer.computeIfAbsent(playerId, key -> new HashMap<>());
108+
Long lastSentAt = lastSentByMap.get(mapId);
109+
if (lastSentAt != null && now - lastSentAt < MAP_SEND_DEDUPE_MS) {
110+
return false;
111+
}
112+
113+
lastSentByMap.put(mapId, now);
114+
return true;
115+
}
89116
}
90117

0 commit comments

Comments
 (0)