Skip to content

Commit 9affb18

Browse files
authored
redid scanning to scan in sections to make it more efficient
1 parent b223143 commit 9affb18

File tree

1 file changed

+106
-89
lines changed

1 file changed

+106
-89
lines changed

src/main/java/net/potato/tuff/TuffX.java

Lines changed: 106 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,24 @@
11
package net.potato.tuff;
22

3-
import org.bukkit.ChatColor;
4-
import org.bukkit.command.Command;
5-
import org.bukkit.command.CommandSender;
6-
import org.bukkit.command.TabCompleter;
7-
import org.bukkit.Chunk;
8-
import org.bukkit.GameMode;
9-
import org.bukkit.Location;
10-
import org.bukkit.Material;
11-
import org.bukkit.World;
3+
import org.bukkit.*;
124
import org.bukkit.block.Block;
5+
import org.bukkit.command.*;
136
import org.bukkit.entity.Player;
14-
import org.bukkit.event.EventHandler;
15-
import org.bukkit.event.EventPriority;
16-
import org.bukkit.event.Listener;
17-
import org.bukkit.event.block.Action;
18-
import org.bukkit.event.player.PlayerInteractEvent;
19-
import org.bukkit.event.player.PlayerJoinEvent;
20-
import org.bukkit.event.player.PlayerQuitEvent;
21-
import org.bukkit.event.player.PlayerTeleportEvent;
22-
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
7+
import org.bukkit.event.*;
8+
import org.bukkit.event.block.*;
9+
import org.bukkit.event.player.*;
2310
import org.bukkit.event.world.ChunkLoadEvent;
2411
import org.bukkit.inventory.ItemStack;
2512
import org.bukkit.plugin.java.JavaPlugin;
2613
import org.bukkit.plugin.messaging.PluginMessageListener;
2714
import org.bukkit.scheduler.BukkitRunnable;
2815

29-
import java.io.ByteArrayInputStream;
30-
import java.io.ByteArrayOutputStream;
31-
import java.io.DataInputStream;
32-
import java.io.DataOutputStream;
33-
import java.io.IOException;
16+
import java.io.*;
3417
import java.nio.charset.StandardCharsets;
35-
import java.util.ArrayList;
36-
import java.util.Collections;
37-
import java.util.List;
38-
import java.util.Set;
39-
import java.util.UUID;
18+
import java.util.*;
4019
import java.util.concurrent.ConcurrentHashMap;
4120
import java.util.stream.Collectors;
4221

43-
import org.bukkit.event.block.BlockBreakEvent;
44-
import org.bukkit.event.block.BlockPlaceEvent;
45-
import org.bukkit.event.block.BlockPhysicsEvent;
46-
import org.bukkit.event.EventPriority;
47-
48-
import org.bukkit.ChunkSnapshot;
49-
import org.bukkit.Chunk;
50-
5122
public class TuffX extends JavaPlugin implements Listener, PluginMessageListener, TabCompleter {
5223

5324
public static final String CHANNEL = "eagler:below_y0";
@@ -66,50 +37,39 @@ public void onEnable() {
6637
}
6738

6839
@Override
69-
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
70-
if (!command.getName().equalsIgnoreCase("tuffx")) {
71-
return false;
72-
}
40+
public void onDisable() {
41+
getServer().getMessenger().unregisterOutgoingPluginChannel(this);
42+
getServer().getMessenger().unregisterIncomingPluginChannel(this);
43+
sentSections.clear();
44+
if (!isMuted) getLogger().info("TuffX disabled");
45+
}
7346

47+
@Override
48+
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
49+
if (!command.getName().equalsIgnoreCase("tuffx")) return false;
7450
if (args.length == 0) {
7551
handleHelpCommand(sender);
7652
return true;
7753
}
78-
7954
switch (args[0].toLowerCase()) {
80-
case "mute":
81-
handleMuteCommand(sender);
82-
break;
83-
case "reload":
84-
handleReloadCommand(sender);
85-
break;
86-
case "reloadchunks":
87-
handleReloadChunksCommand(sender);
88-
break;
89-
case "help":
90-
handleHelpCommand(sender);
91-
break;
92-
default:
93-
sender.sendMessage(ChatColor.GOLD + "[TuffX] " + ChatColor.RED + "Unknown subcommand. Use /tuffx help.");
94-
break;
55+
case "mute" -> handleMuteCommand(sender);
56+
case "reload" -> handleReloadCommand(sender);
57+
case "reloadchunks" -> handleReloadChunksCommand(sender);
58+
case "help" -> handleHelpCommand(sender);
59+
default -> sender.sendMessage(ChatColor.GOLD + "[TuffX] " + ChatColor.RED + "Unknown subcommand. Use /tuffx help.");
9560
}
9661
return true;
9762
}
9863

9964
@Override
10065
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
101-
if (command.getName().equalsIgnoreCase("tuffx")) {
102-
if (args.length == 1) {
103-
List<String> subcommands = new ArrayList<>();
104-
if (sender.hasPermission("tuffx.mute")) subcommands.add("mute");
105-
if (sender.hasPermission("tuffx.reload")) subcommands.add("reload");
106-
if (sender.hasPermission("tuffx.reloadchunks")) subcommands.add("reloadchunks");
107-
if (sender.hasPermission("tuffx.help")) subcommands.add("help");
108-
109-
return subcommands.stream()
110-
.filter(s -> s.toLowerCase().startsWith(args[0].toLowerCase()))
111-
.collect(Collectors.toList());
112-
}
66+
if (command.getName().equalsIgnoreCase("tuffx") && args.length == 1) {
67+
List<String> subcommands = new ArrayList<>();
68+
if (sender.hasPermission("tuffx.mute")) subcommands.add("mute");
69+
if (sender.hasPermission("tuffx.reload")) subcommands.add("reload");
70+
if (sender.hasPermission("tuffx.reloadchunks")) subcommands.add("reloadchunks");
71+
if (sender.hasPermission("tuffx.help")) subcommands.add("help");
72+
return subcommands.stream().filter(s -> s.startsWith(args[0].toLowerCase())).collect(Collectors.toList());
11373
}
11474
return Collections.emptyList();
11575
}
@@ -129,51 +89,108 @@ private void handleReloadCommand(CommandSender sender) {
12989
sender.sendMessage(ChatColor.RED + "You don't have permission to use this command.");
13090
return;
13191
}
132-
sender.sendMessage(ChatColor.GOLD + "[TuffX] " + ChatColor.YELLOW + "Reloading TuffX...");
92+
sender.sendMessage(ChatColor.GOLD + "[TuffX] Reloading...");
13393
onDisable();
13494
onEnable();
135-
sender.sendMessage(ChatColor.GOLD + "[TuffX] " + ChatColor.GREEN + "Reload complete.");
95+
sender.sendMessage(ChatColor.GOLD + "[TuffX] Reload complete.");
13696
}
13797

13898
private void handleReloadChunksCommand(CommandSender sender) {
13999
if (!sender.hasPermission("tuffx.reloadchunks")) {
140100
sender.sendMessage(ChatColor.RED + "You don't have permission to use this command.");
141101
return;
142102
}
143-
sender.sendMessage(ChatColor.GOLD + "[TuffX] " + ChatColor.YELLOW + "Clearing chunk cache and resending to all players...");
103+
sender.sendMessage(ChatColor.GOLD + "[TuffX] Clearing chunk cache and resending...");
144104
sentSections.clear();
145-
146105
for (Player player : getServer().getOnlinePlayers()) {
147106
Chunk playerChunk = player.getLocation().getChunk();
148107
int viewDistance = getServer().getViewDistance();
149108
World world = player.getWorld();
150-
151109
for (int x = -viewDistance; x <= viewDistance; x++) {
152110
for (int z = -viewDistance; z <= viewDistance; z++) {
153111
if (world.isChunkLoaded(playerChunk.getX() + x, playerChunk.getZ() + z)) {
154-
Chunk chunk = world.getChunkAt(playerChunk.getX() + x, playerChunk.getZ() + z);
155-
sendChunkSectionsAsync(player, chunk);
112+
sendChunkSectionsAsync(player, world.getChunkAt(playerChunk.getX() + x, playerChunk.getZ() + z));
113+
}
114+
}
115+
}
116+
}
117+
sender.sendMessage(ChatColor.GOLD + "[TuffX] Chunk reload complete.");
118+
}
119+
120+
private byte[] createSectionPayload(World world, int cx, int cz, int sectionY) throws IOException {
121+
Chunk chunk = world.getChunkAt(cx, cz);
122+
ChunkSnapshot snapshot = chunk.getChunkSnapshot(true, false, false);
123+
try (ByteArrayOutputStream bout = new ByteArrayOutputStream(8200);
124+
DataOutputStream out = new DataOutputStream(bout)) {
125+
out.writeUTF("chunk_data");
126+
out.writeInt(cx);
127+
out.writeInt(cz);
128+
out.writeInt(sectionY);
129+
int baseY = sectionY * 16;
130+
for (int y = 0; y < 16; y++) {
131+
int worldY = baseY + y;
132+
for (int z = 0; z < 16; z++) {
133+
for (int x = 0; x < 16; x++) {
134+
Material type;
135+
if (worldY >= world.getMinHeight() && worldY < world.getMaxHeight()) {
136+
try {
137+
type = snapshot.getBlockType(x, worldY, z);
138+
} catch (Exception e) {
139+
type = Material.AIR;
140+
}
141+
} else {
142+
type = Material.AIR;
143+
}
144+
out.writeShort(LegacyBlockIdManager.getLegacyShort(type));
156145
}
157146
}
158147
}
148+
return bout.toByteArray();
159149
}
160-
sender.sendMessage(ChatColor.GOLD + "[TuffX] " + ChatColor.GREEN + "Chunk reload initiated for all online players. Reload is complete.");
161150
}
162151

152+
private void sendChunkSectionsAsync(Player player, Chunk chunk) {
153+
new BukkitRunnable() {
154+
@Override
155+
public void run() {
156+
int cx = chunk.getX();
157+
int cz = chunk.getZ();
158+
UUID uid = player.getUniqueId();
159+
String worldName = chunk.getWorld().getName();
160+
World world = chunk.getWorld();
161+
162+
int minSectionY = Math.max(world.getMinHeight() >> 4, -4);
163+
int maxSectionY = 0;
164+
for (int sectionY = minSectionY; sectionY < maxSectionY; sectionY++) {
165+
ChunkSectionKey key = new ChunkSectionKey(uid, worldName, cx, cz, sectionY);
166+
if (sentSections.contains(key)) continue;
167+
try {
168+
byte[] payload = createSectionPayload(world, cx, cz, sectionY);
169+
new BukkitRunnable() {
170+
@Override
171+
public void run() {
172+
if (player.isOnline()) {
173+
player.sendPluginMessage(TuffX.this, CHANNEL, payload);
174+
sentSections.add(key);
175+
}
176+
}
177+
}.runTask(TuffX.this);
178+
} catch (IOException e) {
179+
if (!isMuted) getLogger().severe("Failed to create section payload: " + key);
180+
}
181+
}
182+
}
183+
}.runTaskAsynchronously(this);
184+
}
185+
186+
private record ChunkSectionKey(UUID playerId, String worldName, int cx, int cz, int sectionY) {}
187+
163188
private void handleHelpCommand(CommandSender sender) {
164189
sender.sendMessage(ChatColor.GOLD + "--- TuffX Commands ---");
165-
if (sender.hasPermission("tuffx.help")) {
166-
sender.sendMessage(ChatColor.YELLOW + "/tuffx help" + ChatColor.GRAY + " - Shows this help message.");
167-
}
168-
if (sender.hasPermission("tuffx.mute")) {
169-
sender.sendMessage(ChatColor.YELLOW + "/tuffx mute" + ChatColor.GRAY + " - Toggles console logging for the plugin.");
170-
}
171-
if (sender.hasPermission("tuffx.reload")) {
172-
sender.sendMessage(ChatColor.YELLOW + "/tuffx reload" + ChatColor.GRAY + " - Reloads the TuffX plugin.");
173-
}
174-
if (sender.hasPermission("tuffx.reloadchunks")) {
175-
sender.sendMessage(ChatColor.YELLOW + "/tuffx reloadchunks" + ChatColor.GRAY + " - Resends below y0 chunks to players.");
176-
}
190+
if (sender.hasPermission("tuffx.help")) sender.sendMessage(ChatColor.YELLOW + "/tuffx help" + ChatColor.GRAY + " - Shows help message");
191+
if (sender.hasPermission("tuffx.mute")) sender.sendMessage(ChatColor.YELLOW + "/tuffx mute" + ChatColor.GRAY + " - Toggles plugin logging");
192+
if (sender.hasPermission("tuffx.reload")) sender.sendMessage(ChatColor.YELLOW + "/tuffx reload" + ChatColor.GRAY + " - Reload plugin");
193+
if (sender.hasPermission("tuffx.reloadchunks")) sender.sendMessage(ChatColor.YELLOW + "/tuffx reloadchunks" + ChatColor.GRAY + " - Resend chunks");
177194
sender.sendMessage(ChatColor.GOLD + "----------------------");
178195
}
179196

@@ -500,4 +517,4 @@ private void sendChunkSectionIfBelowY0(Player player, Block block) {
500517
}
501518
}
502519
}
503-
}
520+
}

0 commit comments

Comments
 (0)