Fixed chunk loaders can be placed next to each other and overlap chunks (#64)

This commit is contained in:
OmerBenGera 2023-01-13 16:48:36 +02:00
parent 6e0d1fa310
commit 22d8f0d1fb
5 changed files with 111 additions and 76 deletions

View File

@ -2,15 +2,18 @@ package com.bgsoftware.wildloaders.handlers;
import com.bgsoftware.wildloaders.WildLoadersPlugin;
import com.bgsoftware.wildloaders.api.loaders.LoaderData;
import com.bgsoftware.wildloaders.utils.ChunkLoaderChunks;
import com.bgsoftware.wildloaders.utils.ServerVersion;
import com.bgsoftware.wildloaders.utils.database.Database;
import com.bgsoftware.wildloaders.utils.locations.LocationUtils;
import com.bgsoftware.wildloaders.utils.threads.Executor;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.Material;
import java.io.File;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
@ -18,20 +21,20 @@ public final class DataHandler {
private final WildLoadersPlugin plugin;
public DataHandler(WildLoadersPlugin plugin){
public DataHandler(WildLoadersPlugin plugin) {
this.plugin = plugin;
Executor.sync(() -> {
try {
Database.start(new File(plugin.getDataFolder(), "database.db"));
loadDatabase();
}catch (Exception ex){
} catch (Exception ex) {
ex.printStackTrace();
Bukkit.getPluginManager().disablePlugin(plugin);
}
}, 2L);
}
public void loadDatabase(){
public void loadDatabase() {
Database.executeUpdate("CREATE TABLE IF NOT EXISTS npc_identifiers (location TEXT NOT NULL PRIMARY KEY, uuid TEXT NOT NULL);");
Database.executeQuery("SELECT * FROM npc_identifiers;", resultSet -> {
while (resultSet.next()) {
@ -43,27 +46,30 @@ public final class DataHandler {
Database.executeUpdate("CREATE TABLE IF NOT EXISTS chunk_loaders (location TEXT NOT NULL PRIMARY KEY, placer TEXT NOT NULL, loader_data TEXT NOT NULL, timeLeft BIGINT NOT NULL);");
Database.executeQuery("SELECT * FROM chunk_loaders;", resultSet -> {
while(resultSet.next()){
while (resultSet.next()) {
Location location = LocationUtils.getLocation(resultSet.getString("location"));
UUID placer = UUID.fromString(resultSet.getString("placer"));
Optional<LoaderData> loaderData = plugin.getLoaders().getLoaderData(resultSet.getString("loader_data"));
long timeLeft = resultSet.getLong("timeLeft");
if(!loaderData.isPresent())
if (!loaderData.isPresent())
continue;
Material blockType = location.getBlock().getType();
if(ServerVersion.isLegacy() && blockType == Material.CAULDRON){
if (ServerVersion.isLegacy() && blockType == Material.CAULDRON) {
blockType = Material.CAULDRON_ITEM;
}
if(blockType != loaderData.get().getLoaderItem().getType()){
if (blockType != loaderData.get().getLoaderItem().getType()) {
WildLoadersPlugin.log("The chunk-loader at " + LocationUtils.getLocation(location) + " is invalid.");
continue;
}
plugin.getLoaders().addChunkLoader(loaderData.get(), placer, location, timeLeft);
List<Chunk> chunksToLoad = ChunkLoaderChunks.calculateChunks(loaderData.get(), placer, location);
chunksToLoad.removeIf(chunk -> plugin.getLoaders().getChunkLoader(chunk).isPresent());
plugin.getLoaders().addChunkLoaderWithoutDBSave(loaderData.get(), placer, location, timeLeft, chunksToLoad);
}
});
}

View File

@ -1,11 +1,12 @@
package com.bgsoftware.wildloaders.handlers;
import com.bgsoftware.wildloaders.WildLoadersPlugin;
import com.bgsoftware.wildloaders.api.managers.LoadersManager;
import com.bgsoftware.wildloaders.api.loaders.ChunkLoader;
import com.bgsoftware.wildloaders.api.loaders.LoaderData;
import com.bgsoftware.wildloaders.api.managers.LoadersManager;
import com.bgsoftware.wildloaders.loaders.WChunkLoader;
import com.bgsoftware.wildloaders.loaders.WLoaderData;
import com.bgsoftware.wildloaders.utils.ChunkLoaderChunks;
import com.bgsoftware.wildloaders.utils.chunks.ChunkPosition;
import com.bgsoftware.wildloaders.utils.database.Query;
import com.google.common.collect.Maps;
@ -28,7 +29,7 @@ public final class LoadersHandler implements LoadersManager {
private final Map<String, LoaderData> loadersData = Maps.newConcurrentMap();
private final WildLoadersPlugin plugin;
public LoadersHandler(WildLoadersPlugin plugin){
public LoadersHandler(WildLoadersPlugin plugin) {
this.plugin = plugin;
}
@ -59,7 +60,8 @@ public final class LoadersHandler implements LoadersManager {
@Override
public ChunkLoader addChunkLoader(LoaderData loaderData, Player whoPlaced, Location location, long timeLeft) {
WChunkLoader chunkLoader = addChunkLoader(loaderData, whoPlaced.getUniqueId(), location, timeLeft);
WChunkLoader chunkLoader = addChunkLoaderWithoutDBSave(loaderData, whoPlaced.getUniqueId(), location, timeLeft,
ChunkLoaderChunks.calculateChunks(loaderData, whoPlaced.getUniqueId(), location));
Query.INSERT_CHUNK_LOADER.insertParameters()
.setLocation(location)
@ -71,8 +73,8 @@ public final class LoadersHandler implements LoadersManager {
return chunkLoader;
}
public WChunkLoader addChunkLoader(LoaderData loaderData, UUID placer, Location location, long timeLeft){
WChunkLoader chunkLoader = new WChunkLoader(loaderData, placer, location, timeLeft);
public WChunkLoader addChunkLoaderWithoutDBSave(LoaderData loaderData, UUID placer, Location location, long timeLeft, List<Chunk> loadedChunks) {
WChunkLoader chunkLoader = new WChunkLoader(loaderData, placer, location, loadedChunks.toArray(new Chunk[0]), timeLeft);
chunkLoaders.put(location, chunkLoader);
for (Chunk loadedChunk : chunkLoader.getLoadedChunks()) {
chunkLoadersByChunks.put(ChunkPosition.of(loadedChunk), chunkLoader);

View File

@ -4,8 +4,10 @@ import com.bgsoftware.wildloaders.Locale;
import com.bgsoftware.wildloaders.WildLoadersPlugin;
import com.bgsoftware.wildloaders.api.loaders.ChunkLoader;
import com.bgsoftware.wildloaders.api.loaders.LoaderData;
import com.bgsoftware.wildloaders.utils.ChunkLoaderChunks;
import com.bgsoftware.wildloaders.utils.chunks.ChunkPosition;
import com.bgsoftware.wildloaders.utils.legacy.Materials;
import org.bukkit.Chunk;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.block.Block;
@ -27,32 +29,34 @@ public final class BlocksListener implements Listener {
private final WildLoadersPlugin plugin;
public BlocksListener(WildLoadersPlugin plugin){
public BlocksListener(WildLoadersPlugin plugin) {
this.plugin = plugin;
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onLoaderPlace(BlockPlaceEvent e){
public void onLoaderPlace(BlockPlaceEvent e) {
String loaderName = plugin.getNMSAdapter().getTag(e.getItemInHand(), "loader-name", "");
Optional<LoaderData> optionalLoaderData = plugin.getLoaders().getLoaderData(loaderName);
if(!optionalLoaderData.isPresent())
if (!optionalLoaderData.isPresent())
return;
if(!e.getPlayer().hasPermission("wildloaders.use")) {
if (!e.getPlayer().hasPermission("wildloaders.use")) {
e.setCancelled(true);
Locale.NO_PLACE_PERMISSION.send(e.getPlayer());
return;
}
if(plugin.getLoaders().getChunkLoader(e.getBlock().getLocation().getChunk()).isPresent()){
e.setCancelled(true);
Locale.ALREADY_LOADED.send(e.getPlayer());
return;
}
LoaderData loaderData = optionalLoaderData.get();
for (Chunk chunk : ChunkLoaderChunks.calculateChunks(loaderData, e.getPlayer().getUniqueId(), e.getBlock().getLocation())) {
if (plugin.getLoaders().getChunkLoader(chunk).isPresent()) {
e.setCancelled(true);
Locale.ALREADY_LOADED.send(e.getPlayer());
return;
}
}
long timeLeft = plugin.getNMSAdapter().getTag(e.getItemInHand(), "loader-time", loaderData.getTimeLeft());
plugin.getLoaders().addChunkLoader(loaderData, e.getPlayer(), e.getBlock().getLocation(), timeLeft);
@ -61,33 +65,33 @@ public final class BlocksListener implements Listener {
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onLoaderBreak(BlockBreakEvent e){
if(handleLoaderBreak(e.getBlock(), e.getPlayer().getGameMode() != GameMode.CREATIVE))
public void onLoaderBreak(BlockBreakEvent e) {
if (handleLoaderBreak(e.getBlock(), e.getPlayer().getGameMode() != GameMode.CREATIVE))
Locale.BROKE_LOADER.send(e.getPlayer());
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onLoaderExplode(EntityExplodeEvent e){
public void onLoaderExplode(EntityExplodeEvent e) {
e.blockList().removeIf(block -> handleLoaderBreak(block, true));
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onSpawnerPlace(BlockPlaceEvent e){
if(e.getBlock().getType() != Materials.SPAWNER.toBukkitType())
public void onSpawnerPlace(BlockPlaceEvent e) {
if (e.getBlock().getType() != Materials.SPAWNER.toBukkitType())
return;
if(!plugin.getLoaders().getChunkLoader(e.getBlock().getChunk()).isPresent())
if (!plugin.getLoaders().getChunkLoader(e.getBlock().getChunk()).isPresent())
return;
plugin.getNMSAdapter().updateSpawner(e.getBlock().getLocation(), false);
}
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onLoaderInteract(PlayerInteractEvent e){
if(e.getAction() != Action.RIGHT_CLICK_BLOCK)
public void onLoaderInteract(PlayerInteractEvent e) {
if (e.getAction() != Action.RIGHT_CLICK_BLOCK)
return;
if(plugin.getLoaders().getChunkLoader(e.getClickedBlock().getLocation()).isPresent())
if (plugin.getLoaders().getChunkLoader(e.getClickedBlock().getLocation()).isPresent())
e.setCancelled(true);
}
@ -95,37 +99,39 @@ public final class BlocksListener implements Listener {
public void onLoaderPistonRetract(BlockPistonRetractEvent e) {
try {
for (Block block : e.getBlocks()) {
if(plugin.getLoaders().getChunkLoader(block.getLocation()).isPresent()) {
if (plugin.getLoaders().getChunkLoader(block.getLocation()).isPresent()) {
e.setCancelled(true);
return;
}
}
} catch (Throwable ignored) {}
} catch (Throwable ignored) {
}
}
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onLoaderPistonExtend(BlockPistonExtendEvent e) {
try {
for (Block block : e.getBlocks()) {
if(plugin.getLoaders().getChunkLoader(block.getLocation()).isPresent()) {
if (plugin.getLoaders().getChunkLoader(block.getLocation()).isPresent()) {
e.setCancelled(true);
return;
}
}
} catch (Throwable ignored) {}
} catch (Throwable ignored) {
}
}
private boolean handleLoaderBreak(Block block, boolean dropItem){
private boolean handleLoaderBreak(Block block, boolean dropItem) {
Location blockLoc = block.getLocation();
Optional<ChunkLoader> optionalChunkLoader = plugin.getLoaders().getChunkLoader(blockLoc);
if(!optionalChunkLoader.isPresent())
if (!optionalChunkLoader.isPresent())
return false;
ChunkLoader chunkLoader = optionalChunkLoader.get();
chunkLoader.remove();
if(dropItem)
if (dropItem)
blockLoc.getWorld().dropItemNaturally(blockLoc, chunkLoader.getLoaderItem());
return true;

View File

@ -5,6 +5,7 @@ import com.bgsoftware.wildloaders.api.holograms.Hologram;
import com.bgsoftware.wildloaders.api.loaders.ChunkLoader;
import com.bgsoftware.wildloaders.api.loaders.LoaderData;
import com.bgsoftware.wildloaders.api.npc.ChunkLoaderNPC;
import com.bgsoftware.wildloaders.utils.ChunkLoaderChunks;
import com.bgsoftware.wildloaders.utils.database.Query;
import com.bgsoftware.wildloaders.utils.threads.Executor;
import org.bukkit.Bukkit;
@ -14,7 +15,6 @@ import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
@ -33,11 +33,11 @@ public final class WChunkLoader implements ChunkLoader {
private boolean active = true;
private long timeLeft;
public WChunkLoader(LoaderData loaderData, UUID whoPlaced, Location location, long timeLeft) {
public WChunkLoader(LoaderData loaderData, UUID whoPlaced, Location location, Chunk[] loadedChunks, long timeLeft) {
this.loaderName = loaderData.getName();
this.whoPlaced = whoPlaced;
this.location = location.clone();
this.loadedChunks = calculateChunks(loaderData, whoPlaced, this.location);
this.loadedChunks = loadedChunks;
this.timeLeft = timeLeft;
this.tileEntityChunkLoader = plugin.getNMSAdapter().createLoader(this);
}
@ -125,39 +125,5 @@ public final class WChunkLoader implements ChunkLoader {
return isInfinite() ? plugin.getSettings().infiniteHologramLines : plugin.getSettings().hologramLines;
}
private static Chunk[] calculateChunks(LoaderData loaderData, UUID whoPlaced, Location original) {
List<Chunk> chunkList = new ArrayList<>();
if (loaderData.isChunksSpread()) {
calculateClaimChunks(original.getChunk(), whoPlaced, chunkList);
}
if (chunkList.isEmpty()) {
int chunkX = original.getBlockX() >> 4, chunkZ = original.getBlockZ() >> 4;
for (int x = -loaderData.getChunksRadius(); x <= loaderData.getChunksRadius(); x++)
for (int z = -loaderData.getChunksRadius(); z <= loaderData.getChunksRadius(); z++)
chunkList.add(original.getWorld().getChunkAt(chunkX + x, chunkZ + z));
}
return chunkList.toArray(new Chunk[0]);
}
private static void calculateClaimChunks(Chunk originalChunk, UUID whoPlaced, List<Chunk> chunkList) {
if (!plugin.getProviders().hasChunkAccess(whoPlaced, originalChunk))
return;
chunkList.add(originalChunk);
int chunkX = originalChunk.getX(), chunkZ = originalChunk.getZ();
for (int x = -1; x <= 1; x++) {
for (int z = -1; z <= 1; z++) {
if (x != 0 || z != 0) // We don't want to add the originalChunk again.
calculateClaimChunks(originalChunk.getWorld().getChunkAt(chunkX + x, chunkZ + z), whoPlaced, chunkList);
}
}
}
}

View File

@ -0,0 +1,55 @@
package com.bgsoftware.wildloaders.utils;
import com.bgsoftware.wildloaders.WildLoadersPlugin;
import com.bgsoftware.wildloaders.api.loaders.LoaderData;
import org.bukkit.Chunk;
import org.bukkit.Location;
import java.util.LinkedList;
import java.util.List;
import java.util.UUID;
public class ChunkLoaderChunks {
private static final WildLoadersPlugin plugin = WildLoadersPlugin.getPlugin();
private ChunkLoaderChunks() {
}
public static List<Chunk> calculateChunks(LoaderData loaderData, UUID whoPlaced, Location original) {
List<Chunk> chunkList = new LinkedList<>();
if (loaderData.isChunksSpread()) {
calculateClaimChunksRecursive(original.getChunk(), whoPlaced, chunkList);
}
if (chunkList.isEmpty()) {
int chunkX = original.getBlockX() >> 4, chunkZ = original.getBlockZ() >> 4;
for (int x = -loaderData.getChunksRadius(); x <= loaderData.getChunksRadius(); x++)
for (int z = -loaderData.getChunksRadius(); z <= loaderData.getChunksRadius(); z++)
chunkList.add(original.getWorld().getChunkAt(chunkX + x, chunkZ + z));
}
return chunkList;
}
private static void calculateClaimChunksRecursive(Chunk originalChunk, UUID whoPlaced, List<Chunk> chunkList) {
if (!plugin.getProviders().hasChunkAccess(whoPlaced, originalChunk))
return;
chunkList.add(originalChunk);
int chunkX = originalChunk.getX(), chunkZ = originalChunk.getZ();
for (int x = -1; x <= 1; x++) {
for (int z = -1; z <= 1; z++) {
if (x != 0 || z != 0) // We don't want to add the originalChunk again.
calculateClaimChunksRecursive(originalChunk.getWorld().getChunkAt(chunkX + x, chunkZ + z), whoPlaced, chunkList);
}
}
}
}