Adds the ability for plugins to have custom implementation for changing range of spawners

This commit is contained in:
OmerBenGera 2024-11-16 12:30:26 +02:00
parent 307c181552
commit ebe21c0329
19 changed files with 486 additions and 170 deletions

View File

@ -0,0 +1,16 @@
package com.bgsoftware.wildloaders.api.hooks;
import org.bukkit.Location;
public interface SpawnersProvider {
/**
* Sets the required-player range for the spawner in {@param spawnerLocation}.
*
* @param spawnerLocation The location of the spawner to set the range to.
* @param requiredRange The range to set.
* Negative value means unlimited range.
*/
void setSpawnerRequiredRange(Location spawnerLocation, int requiredRange);
}

View File

@ -1,6 +1,7 @@
package com.bgsoftware.wildloaders.api.managers;
import com.bgsoftware.wildloaders.api.hooks.ClaimsProvider;
import com.bgsoftware.wildloaders.api.hooks.SpawnersProvider;
import com.bgsoftware.wildloaders.api.hooks.TickableProvider;
import com.bgsoftware.wildloaders.api.hooks.WorldsProvider;
@ -12,6 +13,12 @@ public interface ProvidersManager {
*/
void addClaimsProvider(ClaimsProvider claimsProvider);
/**
* Add a spawners provider to the plugin.
* @param spawnersProvider The spawners provider to add.
*/
void addSpawnersProvider(SpawnersProvider spawnersProvider);
/**
* Add a tickable provider to the plugin.
* @param tickableProvider The tickable provider to add.

View File

@ -17,12 +17,14 @@ import net.minecraft.server.v1_12_R1.NBTTagString;
import net.minecraft.server.v1_12_R1.TileEntity;
import net.minecraft.server.v1_12_R1.TileEntityMobSpawner;
import net.minecraft.server.v1_12_R1.World;
import net.minecraft.server.v1_12_R1.WorldServer;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_12_R1.CraftChunk;
import org.bukkit.craftbukkit.v1_12_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_12_R1.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_12_R1.util.LongHash;
import javax.annotation.Nullable;
import java.util.UUID;
public final class NMSAdapterImpl implements NMSAdapter {
@ -106,27 +108,30 @@ public final class NMSAdapterImpl implements NMSAdapter {
}
@Override
public ITileEntityChunkLoader createLoader(ChunkLoader chunkLoader) {
public ITileEntityChunkLoader createLoader(ChunkLoader chunkLoader,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
Location loaderLoc = chunkLoader.getLocation();
World world = ((CraftWorld) loaderLoc.getWorld()).getHandle();
WorldServer worldServer = ((CraftWorld) loaderLoc.getWorld()).getHandle();
BlockPosition blockPosition = new BlockPosition(loaderLoc.getX(), loaderLoc.getY(), loaderLoc.getZ());
TileEntityChunkLoader tileEntityChunkLoader = new TileEntityChunkLoader(chunkLoader, world, blockPosition);
world.tileEntityListTick.add(tileEntityChunkLoader);
TileEntityChunkLoader tileEntityChunkLoader = new TileEntityChunkLoader(chunkLoader, worldServer, blockPosition);
worldServer.tileEntityListTick.add(tileEntityChunkLoader);
if (Scheduler.isRegionScheduler()) {
Scheduler.runTask(() -> setSpawnersRangeForLoader(chunkLoader, true));
Scheduler.runTask(() ->
setSpawnersRangeForLoader(chunkLoader, worldServer, true, onSpawnerChangeCallback));
} else {
setSpawnersRangeForLoader(chunkLoader, true);
setSpawnersRangeForLoader(chunkLoader, worldServer, true, onSpawnerChangeCallback);
}
return tileEntityChunkLoader;
}
@Override
public void removeLoader(ChunkLoader chunkLoader, boolean spawnParticle) {
public void removeLoader(ChunkLoader chunkLoader, boolean spawnParticle,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
Location loaderLoc = chunkLoader.getLocation();
World world = ((CraftWorld) loaderLoc.getWorld()).getHandle();
WorldServer worldServer = ((CraftWorld) loaderLoc.getWorld()).getHandle();
BlockPosition blockPosition = new BlockPosition(loaderLoc.getX(), loaderLoc.getY(), loaderLoc.getZ());
long tileEntityLong = LongHash.toLong(blockPosition.getX() >> 4, blockPosition.getZ() >> 4);
@ -134,33 +139,37 @@ public final class NMSAdapterImpl implements NMSAdapter {
if (tileEntityChunkLoader != null) {
tileEntityChunkLoader.holograms.forEach(EntityHolograms::removeHologram);
tileEntityChunkLoader.removed = true;
world.tileEntityListTick.remove(tileEntityChunkLoader);
worldServer.tileEntityListTick.remove(tileEntityChunkLoader);
}
if (spawnParticle)
world.a(null, 2001, blockPosition, Block.getCombinedId(world.getType(blockPosition)));
worldServer.a(null, 2001, blockPosition,
Block.getCombinedId(worldServer.getType(blockPosition)));
if (Scheduler.isRegionScheduler()) {
Scheduler.runTask(() -> setSpawnersRangeForLoader(chunkLoader, false));
Scheduler.runTask(() ->
setSpawnersRangeForLoader(chunkLoader, worldServer, false, onSpawnerChangeCallback));
} else {
setSpawnersRangeForLoader(chunkLoader, false);
setSpawnersRangeForLoader(chunkLoader, worldServer, false, onSpawnerChangeCallback);
}
}
private static void setSpawnersRangeForLoader(ChunkLoader chunkLoader, boolean loaded) {
private static void setSpawnersRangeForLoader(ChunkLoader chunkLoader, WorldServer worldServer, boolean loaded,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
org.bukkit.World bukkitWorld = worldServer.getWorld();
short requiredPlayerRange = (short) (loaded ? -1 : 16);
for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunksCollection()) {
Chunk chunk = ((CraftChunk) bukkitChunk).getHandle();
for (TileEntity tileEntity : chunk.tileEntities.values()) {
if (tileEntity instanceof TileEntityMobSpawner) {
NBTTagCompound nbtTagCompound = new NBTTagCompound();
tileEntity.save(nbtTagCompound);
nbtTagCompound.setShort("RequiredPlayerRange", requiredPlayerRange);
if (TILE_ENTITY_LOAD.isValid()) {
TILE_ENTITY_LOAD.invoke(tileEntity, nbtTagCompound);
} else {
tileEntity.a(nbtTagCompound);
setSpawnerRange((TileEntityMobSpawner) tileEntity, requiredPlayerRange);
if (onSpawnerChangeCallback != null) {
BlockPosition blockPosition = tileEntity.getPosition();
Location location = new Location(bukkitWorld, blockPosition.getX(), blockPosition.getY(), blockPosition.getZ());
onSpawnerChangeCallback.apply(location, requiredPlayerRange);
}
}
}
@ -168,14 +177,31 @@ public final class NMSAdapterImpl implements NMSAdapter {
}
@Override
public void updateSpawner(Location location, boolean reset) {
World world = ((CraftWorld) location.getWorld()).getHandle();
BlockPosition blockPosition = new BlockPosition(location.getX(), location.getY(), location.getZ());
TileEntityMobSpawner mobSpawner = (TileEntityMobSpawner) world.getTileEntity(blockPosition);
public void updateSpawner(Location location, boolean reset,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
org.bukkit.World bukkitWorld = location.getWorld();
if (bukkitWorld == null)
throw new IllegalArgumentException("Cannot remove loader in null world.");
World world = ((CraftWorld) bukkitWorld).getHandle();
BlockPosition blockPosition = new BlockPosition(location.getX(), location.getY(), location.getZ());
TileEntity tileEntity = world.getTileEntity(blockPosition);
if (!(tileEntity instanceof TileEntityMobSpawner))
return;
TileEntityMobSpawner mobSpawner = (TileEntityMobSpawner) tileEntity;
int requiredPlayerRange = reset ? 16 : -1;
setSpawnerRange(mobSpawner, requiredPlayerRange);
if (onSpawnerChangeCallback != null)
onSpawnerChangeCallback.apply(location, requiredPlayerRange);
}
private static void setSpawnerRange(TileEntityMobSpawner mobSpawner, int range) {
NBTTagCompound nbtTagCompound = new NBTTagCompound();
mobSpawner.save(nbtTagCompound);
nbtTagCompound.setShort("RequiredPlayerRange", (short) (reset ? 16 : -1));
nbtTagCompound.setShort("RequiredPlayerRange", (short) range);
if (TILE_ENTITY_LOAD.isValid()) {
TILE_ENTITY_LOAD.invoke(mobSpawner, nbtTagCompound);
} else {

View File

@ -9,7 +9,6 @@ import net.minecraft.server.v1_16_R3.Block;
import net.minecraft.server.v1_16_R3.BlockPosition;
import net.minecraft.server.v1_16_R3.Chunk;
import net.minecraft.server.v1_16_R3.ChunkCoordIntPair;
import net.minecraft.server.v1_16_R3.IBlockData;
import net.minecraft.server.v1_16_R3.ItemStack;
import net.minecraft.server.v1_16_R3.NBTTagCompound;
import net.minecraft.server.v1_16_R3.NBTTagList;
@ -24,6 +23,7 @@ import org.bukkit.craftbukkit.v1_16_R3.CraftChunk;
import org.bukkit.craftbukkit.v1_16_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack;
import javax.annotation.Nullable;
import java.util.UUID;
public final class NMSAdapterImpl implements NMSAdapter {
@ -107,7 +107,8 @@ public final class NMSAdapterImpl implements NMSAdapter {
}
@Override
public ITileEntityChunkLoader createLoader(ChunkLoader chunkLoader) {
public ITileEntityChunkLoader createLoader(ChunkLoader chunkLoader,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
Location loaderLoc = chunkLoader.getLocation();
assert loaderLoc.getWorld() != null;
WorldServer world = ((CraftWorld) loaderLoc.getWorld()).getHandle();
@ -117,16 +118,18 @@ public final class NMSAdapterImpl implements NMSAdapter {
world.tileEntityListTick.add(tileEntityChunkLoader);
if (Scheduler.isRegionScheduler()) {
Scheduler.runTask(() -> setChunksForcedForLoader(chunkLoader, world, true));
Scheduler.runTask(() ->
setChunksForcedForLoader(chunkLoader, world, true, onSpawnerChangeCallback));
} else {
setChunksForcedForLoader(chunkLoader, world, true);
setChunksForcedForLoader(chunkLoader, world, true, onSpawnerChangeCallback);
}
return tileEntityChunkLoader;
}
@Override
public void removeLoader(ChunkLoader chunkLoader, boolean spawnParticle) {
public void removeLoader(ChunkLoader chunkLoader, boolean spawnParticle,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
Location loaderLoc = chunkLoader.getLocation();
assert loaderLoc.getWorld() != null;
WorldServer world = ((CraftWorld) loaderLoc.getWorld()).getHandle();
@ -144,20 +147,31 @@ public final class NMSAdapterImpl implements NMSAdapter {
world.a(null, 2001, blockPosition, Block.getCombinedId(world.getType(blockPosition)));
if (Scheduler.isRegionScheduler()) {
Scheduler.runTask(() -> setChunksForcedForLoader(chunkLoader, world, false));
Scheduler.runTask(() ->
setChunksForcedForLoader(chunkLoader, world, false, onSpawnerChangeCallback));
} else {
setChunksForcedForLoader(chunkLoader, world, false);
setChunksForcedForLoader(chunkLoader, world, false, onSpawnerChangeCallback);
}
}
private static void setChunksForcedForLoader(ChunkLoader chunkLoader, WorldServer worldServer, boolean forced) {
private static void setChunksForcedForLoader(ChunkLoader chunkLoader, WorldServer worldServer, boolean forced,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
org.bukkit.World bukkitWorld = worldServer.getWorld();
int requiredPlayerRange = forced ? -1 : 16;
for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunksCollection()) {
Chunk chunk = ((CraftChunk) bukkitChunk).getHandle();
for (TileEntity tileEntity : chunk.tileEntities.values()) {
if (tileEntity instanceof TileEntityMobSpawner)
if (tileEntity instanceof TileEntityMobSpawner) {
((TileEntityMobSpawner) tileEntity).getSpawner().requiredPlayerRange = requiredPlayerRange;
if (onSpawnerChangeCallback != null) {
BlockPosition blockPosition = tileEntity.getPosition();
Location location = new Location(bukkitWorld, blockPosition.getX(), blockPosition.getY(), blockPosition.getZ());
onSpawnerChangeCallback.apply(location, requiredPlayerRange);
}
}
}
ChunkCoordIntPair chunkCoord = chunk.getPos();
@ -166,18 +180,25 @@ public final class NMSAdapterImpl implements NMSAdapter {
}
@Override
public void updateSpawner(Location location, boolean reset) {
assert location.getWorld() != null;
World world = ((CraftWorld) location.getWorld()).getHandle();
public void updateSpawner(Location location, boolean reset,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
org.bukkit.World bukkitWorld = location.getWorld();
if (bukkitWorld == null)
throw new IllegalArgumentException("Cannot remove loader in null world.");
World world = ((CraftWorld) bukkitWorld).getHandle();
BlockPosition blockPosition = new BlockPosition(location.getX(), location.getY(), location.getZ());
IBlockData blockData = world.getType(blockPosition);
TileEntityMobSpawner mobSpawner = (TileEntityMobSpawner) world.getTileEntity(blockPosition);
if (mobSpawner == null)
TileEntity tileEntity = world.getTileEntity(blockPosition);
if (!(tileEntity instanceof TileEntityMobSpawner))
return;
mobSpawner.getSpawner().requiredPlayerRange = reset ? 16 : -1;
TileEntityMobSpawner mobSpawner = (TileEntityMobSpawner) tileEntity;
int requiredPlayerRange = reset ? 16 : -1;
mobSpawner.getSpawner().requiredPlayerRange = requiredPlayerRange;
if (onSpawnerChangeCallback != null)
onSpawnerChangeCallback.apply(location, requiredPlayerRange);
}
}

View File

@ -24,6 +24,7 @@ import org.bukkit.craftbukkit.v1_17_R1.CraftServer;
import org.bukkit.craftbukkit.v1_17_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack;
import javax.annotation.Nullable;
import java.util.UUID;
public final class NMSAdapterImpl implements NMSAdapter {
@ -93,7 +94,8 @@ public final class NMSAdapterImpl implements NMSAdapter {
}
@Override
public ITileEntityChunkLoader createLoader(ChunkLoader chunkLoader) {
public ITileEntityChunkLoader createLoader(ChunkLoader chunkLoader,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
Location loaderLoc = chunkLoader.getLocation();
World bukkitWorld = loaderLoc.getWorld();
@ -107,16 +109,18 @@ public final class NMSAdapterImpl implements NMSAdapter {
serverLevel.addBlockEntityTicker(ChunkLoaderBlockEntity.getTicker());
if (Scheduler.isRegionScheduler()) {
Scheduler.runTask(() -> setChunksForcedForLoader(chunkLoader, serverLevel, true));
Scheduler.runTask(() ->
setChunksForcedForLoader(chunkLoader, serverLevel, true, onSpawnerChangeCallback));
} else {
setChunksForcedForLoader(chunkLoader, serverLevel, true);
setChunksForcedForLoader(chunkLoader, serverLevel, true, onSpawnerChangeCallback);
}
return ChunkLoaderBlockEntity;
}
@Override
public void removeLoader(ChunkLoader chunkLoader, boolean spawnParticle) {
public void removeLoader(ChunkLoader chunkLoader, boolean spawnParticle,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
Location loaderLoc = chunkLoader.getLocation();
World bukkitWorld = loaderLoc.getWorld();
@ -138,20 +142,31 @@ public final class NMSAdapterImpl implements NMSAdapter {
serverLevel.levelEvent(null, 2001, blockPos, Block.getId(serverLevel.getBlockState(blockPos)));
if (Scheduler.isRegionScheduler()) {
Scheduler.runTask(() -> setChunksForcedForLoader(chunkLoader, serverLevel, false));
Scheduler.runTask(() ->
setChunksForcedForLoader(chunkLoader, serverLevel, false, onSpawnerChangeCallback));
} else {
setChunksForcedForLoader(chunkLoader, serverLevel, false);
setChunksForcedForLoader(chunkLoader, serverLevel, false, onSpawnerChangeCallback);
}
}
private static void setChunksForcedForLoader(ChunkLoader chunkLoader, ServerLevel serverLevel, boolean forced) {
private static void setChunksForcedForLoader(ChunkLoader chunkLoader, ServerLevel serverLevel, boolean forced,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
World bukkitWorld = serverLevel.getWorld();
int requiredPlayerRange = forced ? -1 : 16;
for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunksCollection()) {
LevelChunk levelChunk = ((CraftChunk) bukkitChunk).getHandle();
for (BlockEntity blockEntity : levelChunk.getBlockEntities().values()) {
if (blockEntity instanceof SpawnerBlockEntity spawnerBlockEntity)
if (blockEntity instanceof SpawnerBlockEntity spawnerBlockEntity) {
spawnerBlockEntity.getSpawner().requiredPlayerRange = requiredPlayerRange;
if (onSpawnerChangeCallback != null) {
BlockPos blockPos = blockEntity.getBlockPos();
Location location = new Location(bukkitWorld, blockPos.getX(), blockPos.getY(), blockPos.getZ());
onSpawnerChangeCallback.apply(location, requiredPlayerRange);
}
}
}
ChunkPos chunkPos = levelChunk.getPos();
@ -160,7 +175,8 @@ public final class NMSAdapterImpl implements NMSAdapter {
}
@Override
public void updateSpawner(Location location, boolean reset) {
public void updateSpawner(Location location, boolean reset,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
World bukkitWorld = location.getWorld();
if (bukkitWorld == null)
@ -169,8 +185,13 @@ public final class NMSAdapterImpl implements NMSAdapter {
ServerLevel serverLevel = ((CraftWorld) bukkitWorld).getHandle();
BlockPos blockPos = new BlockPos(location.getX(), location.getY(), location.getZ());
BlockEntity blockEntity = serverLevel.getBlockEntity(blockPos);
if (blockEntity instanceof SpawnerBlockEntity spawnerBlockEntity)
spawnerBlockEntity.getSpawner().requiredPlayerRange = reset ? 16 : -1;
if (!(blockEntity instanceof SpawnerBlockEntity spawnerBlockEntity))
return;
int requiredPlayerRange = reset ? 16 : -1;
spawnerBlockEntity.getSpawner().requiredPlayerRange = requiredPlayerRange;
if (onSpawnerChangeCallback != null)
onSpawnerChangeCallback.apply(location, requiredPlayerRange);
}
}

View File

@ -23,6 +23,7 @@ import org.bukkit.craftbukkit.v1_18_R2.CraftServer;
import org.bukkit.craftbukkit.v1_18_R2.CraftWorld;
import org.bukkit.craftbukkit.v1_18_R2.inventory.CraftItemStack;
import javax.annotation.Nullable;
import java.util.UUID;
public final class NMSAdapterImpl implements NMSAdapter {
@ -92,7 +93,8 @@ public final class NMSAdapterImpl implements NMSAdapter {
}
@Override
public ITileEntityChunkLoader createLoader(ChunkLoader chunkLoader) {
public ITileEntityChunkLoader createLoader(ChunkLoader chunkLoader,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
Location loaderLoc = chunkLoader.getLocation();
World bukkitWorld = loaderLoc.getWorld();
@ -106,16 +108,18 @@ public final class NMSAdapterImpl implements NMSAdapter {
serverLevel.addBlockEntityTicker(ChunkLoaderBlockEntity.getTicker());
if (Scheduler.isRegionScheduler()) {
Scheduler.runTask(() -> setChunksForcedForLoader(chunkLoader, serverLevel, true));
Scheduler.runTask(() ->
setChunksForcedForLoader(chunkLoader, serverLevel, true, onSpawnerChangeCallback));
} else {
setChunksForcedForLoader(chunkLoader, serverLevel, true);
setChunksForcedForLoader(chunkLoader, serverLevel, true, onSpawnerChangeCallback);
}
return ChunkLoaderBlockEntity;
}
@Override
public void removeLoader(ChunkLoader chunkLoader, boolean spawnParticle) {
public void removeLoader(ChunkLoader chunkLoader, boolean spawnParticle,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
Location loaderLoc = chunkLoader.getLocation();
World bukkitWorld = loaderLoc.getWorld();
@ -137,20 +141,31 @@ public final class NMSAdapterImpl implements NMSAdapter {
serverLevel.levelEvent(null, 2001, blockPos, Block.getId(serverLevel.getBlockState(blockPos)));
if (Scheduler.isRegionScheduler()) {
Scheduler.runTask(() -> setChunksForcedForLoader(chunkLoader, serverLevel, false));
Scheduler.runTask(() ->
setChunksForcedForLoader(chunkLoader, serverLevel, false, onSpawnerChangeCallback));
} else {
setChunksForcedForLoader(chunkLoader, serverLevel, false);
setChunksForcedForLoader(chunkLoader, serverLevel, false, onSpawnerChangeCallback);
}
}
private static void setChunksForcedForLoader(ChunkLoader chunkLoader, ServerLevel serverLevel, boolean forced) {
private static void setChunksForcedForLoader(ChunkLoader chunkLoader, ServerLevel serverLevel, boolean forced,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
World bukkitWorld = serverLevel.getWorld();
int requiredPlayerRange = forced ? -1 : 16;
for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunksCollection()) {
LevelChunk levelChunk = ((CraftChunk) bukkitChunk).getHandle();
for (BlockEntity blockEntity : levelChunk.getBlockEntities().values()) {
if (blockEntity instanceof SpawnerBlockEntity spawnerBlockEntity)
if (blockEntity instanceof SpawnerBlockEntity spawnerBlockEntity) {
spawnerBlockEntity.getSpawner().requiredPlayerRange = requiredPlayerRange;
if (onSpawnerChangeCallback != null) {
BlockPos blockPos = blockEntity.getBlockPos();
Location location = new Location(bukkitWorld, blockPos.getX(), blockPos.getY(), blockPos.getZ());
onSpawnerChangeCallback.apply(location, requiredPlayerRange);
}
}
}
ChunkPos chunkPos = levelChunk.getPos();
@ -159,7 +174,8 @@ public final class NMSAdapterImpl implements NMSAdapter {
}
@Override
public void updateSpawner(Location location, boolean reset) {
public void updateSpawner(Location location, boolean reset,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
World bukkitWorld = location.getWorld();
if (bukkitWorld == null)
@ -168,8 +184,13 @@ public final class NMSAdapterImpl implements NMSAdapter {
ServerLevel serverLevel = ((CraftWorld) bukkitWorld).getHandle();
BlockPos blockPos = new BlockPos(location.getX(), location.getY(), location.getZ());
BlockEntity blockEntity = serverLevel.getBlockEntity(blockPos);
if (blockEntity instanceof SpawnerBlockEntity spawnerBlockEntity)
spawnerBlockEntity.getSpawner().requiredPlayerRange = reset ? 16 : -1;
if (!(blockEntity instanceof SpawnerBlockEntity spawnerBlockEntity))
return;
int requiredPlayerRange = reset ? 16 : -1;
spawnerBlockEntity.getSpawner().requiredPlayerRange = requiredPlayerRange;
if (onSpawnerChangeCallback != null)
onSpawnerChangeCallback.apply(location, requiredPlayerRange);
}
}

View File

@ -22,6 +22,7 @@ import org.bukkit.craftbukkit.v1_19_R3.CraftServer;
import org.bukkit.craftbukkit.v1_19_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_19_R3.inventory.CraftItemStack;
import javax.annotation.Nullable;
import java.util.UUID;
public final class NMSAdapterImpl implements NMSAdapter {
@ -91,7 +92,8 @@ public final class NMSAdapterImpl implements NMSAdapter {
}
@Override
public ITileEntityChunkLoader createLoader(ChunkLoader chunkLoader) {
public ITileEntityChunkLoader createLoader(ChunkLoader chunkLoader,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
Location loaderLoc = chunkLoader.getLocation();
World bukkitWorld = loaderLoc.getWorld();
@ -105,16 +107,18 @@ public final class NMSAdapterImpl implements NMSAdapter {
serverLevel.addBlockEntityTicker(ChunkLoaderBlockEntity.getTicker());
if (Scheduler.isRegionScheduler()) {
Scheduler.runTask(() -> setChunksForcedForLoader(chunkLoader, serverLevel, true));
Scheduler.runTask(() ->
setChunksForcedForLoader(chunkLoader, serverLevel, true, onSpawnerChangeCallback));
} else {
setChunksForcedForLoader(chunkLoader, serverLevel, true);
setChunksForcedForLoader(chunkLoader, serverLevel, true, onSpawnerChangeCallback);
}
return ChunkLoaderBlockEntity;
}
@Override
public void removeLoader(ChunkLoader chunkLoader, boolean spawnParticle) {
public void removeLoader(ChunkLoader chunkLoader, boolean spawnParticle,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
Location loaderLoc = chunkLoader.getLocation();
World bukkitWorld = loaderLoc.getWorld();
@ -136,20 +140,31 @@ public final class NMSAdapterImpl implements NMSAdapter {
serverLevel.levelEvent(null, 2001, blockPos, Block.getId(serverLevel.getBlockState(blockPos)));
if (Scheduler.isRegionScheduler()) {
Scheduler.runTask(() -> setChunksForcedForLoader(chunkLoader, serverLevel, false));
Scheduler.runTask(() ->
setChunksForcedForLoader(chunkLoader, serverLevel, false, onSpawnerChangeCallback));
} else {
setChunksForcedForLoader(chunkLoader, serverLevel, false);
setChunksForcedForLoader(chunkLoader, serverLevel, false, onSpawnerChangeCallback);
}
}
private static void setChunksForcedForLoader(ChunkLoader chunkLoader, ServerLevel serverLevel, boolean forced) {
private static void setChunksForcedForLoader(ChunkLoader chunkLoader, ServerLevel serverLevel, boolean forced,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
World bukkitWorld = serverLevel.getWorld();
int requiredPlayerRange = forced ? -1 : 16;
for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunksCollection()) {
LevelChunk levelChunk = serverLevel.getChunk(bukkitChunk.getX(), bukkitChunk.getZ());
for (BlockEntity blockEntity : levelChunk.getBlockEntities().values()) {
if (blockEntity instanceof SpawnerBlockEntity spawnerBlockEntity)
if (blockEntity instanceof SpawnerBlockEntity spawnerBlockEntity) {
spawnerBlockEntity.getSpawner().requiredPlayerRange = requiredPlayerRange;
if (onSpawnerChangeCallback != null) {
BlockPos blockPos = blockEntity.getBlockPos();
Location location = new Location(bukkitWorld, blockPos.getX(), blockPos.getY(), blockPos.getZ());
onSpawnerChangeCallback.apply(location, requiredPlayerRange);
}
}
}
ChunkPos chunkPos = levelChunk.getPos();
@ -158,7 +173,8 @@ public final class NMSAdapterImpl implements NMSAdapter {
}
@Override
public void updateSpawner(Location location, boolean reset) {
public void updateSpawner(Location location, boolean reset,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
World bukkitWorld = location.getWorld();
if (bukkitWorld == null)
@ -167,8 +183,13 @@ public final class NMSAdapterImpl implements NMSAdapter {
ServerLevel serverLevel = ((CraftWorld) bukkitWorld).getHandle();
BlockPos blockPos = new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ());
BlockEntity blockEntity = serverLevel.getBlockEntity(blockPos);
if (blockEntity instanceof SpawnerBlockEntity spawnerBlockEntity)
spawnerBlockEntity.getSpawner().requiredPlayerRange = reset ? 16 : -1;
if (!(blockEntity instanceof SpawnerBlockEntity spawnerBlockEntity))
return;
int requiredPlayerRange = reset ? 16 : -1;
spawnerBlockEntity.getSpawner().requiredPlayerRange = requiredPlayerRange;
if (onSpawnerChangeCallback != null)
onSpawnerChangeCallback.apply(location, requiredPlayerRange);
}
}

View File

@ -22,6 +22,7 @@ import org.bukkit.craftbukkit.v1_20_R3.CraftServer;
import org.bukkit.craftbukkit.v1_20_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_20_R3.inventory.CraftItemStack;
import javax.annotation.Nullable;
import java.util.UUID;
public final class NMSAdapterImpl implements NMSAdapter {
@ -91,7 +92,8 @@ public final class NMSAdapterImpl implements NMSAdapter {
}
@Override
public ITileEntityChunkLoader createLoader(ChunkLoader chunkLoader) {
public ITileEntityChunkLoader createLoader(ChunkLoader chunkLoader,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
Location loaderLoc = chunkLoader.getLocation();
World bukkitWorld = loaderLoc.getWorld();
@ -105,16 +107,18 @@ public final class NMSAdapterImpl implements NMSAdapter {
serverLevel.addBlockEntityTicker(ChunkLoaderBlockEntity.getTicker());
if (Scheduler.isRegionScheduler()) {
Scheduler.runTask(() -> setChunksForcedForLoader(chunkLoader, serverLevel, true));
Scheduler.runTask(() ->
setChunksForcedForLoader(chunkLoader, serverLevel, true, onSpawnerChangeCallback));
} else {
setChunksForcedForLoader(chunkLoader, serverLevel, true);
setChunksForcedForLoader(chunkLoader, serverLevel, true, onSpawnerChangeCallback);
}
return ChunkLoaderBlockEntity;
}
@Override
public void removeLoader(ChunkLoader chunkLoader, boolean spawnParticle) {
public void removeLoader(ChunkLoader chunkLoader, boolean spawnParticle,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
Location loaderLoc = chunkLoader.getLocation();
World bukkitWorld = loaderLoc.getWorld();
@ -136,20 +140,31 @@ public final class NMSAdapterImpl implements NMSAdapter {
serverLevel.levelEvent(null, 2001, blockPos, Block.getId(serverLevel.getBlockState(blockPos)));
if (Scheduler.isRegionScheduler()) {
Scheduler.runTask(() -> setChunksForcedForLoader(chunkLoader, serverLevel, false));
Scheduler.runTask(() ->
setChunksForcedForLoader(chunkLoader, serverLevel, false, onSpawnerChangeCallback));
} else {
setChunksForcedForLoader(chunkLoader, serverLevel, false);
setChunksForcedForLoader(chunkLoader, serverLevel, false, onSpawnerChangeCallback);
}
}
private static void setChunksForcedForLoader(ChunkLoader chunkLoader, ServerLevel serverLevel, boolean forced) {
private static void setChunksForcedForLoader(ChunkLoader chunkLoader, ServerLevel serverLevel, boolean forced,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
World bukkitWorld = serverLevel.getWorld();
int requiredPlayerRange = forced ? -1 : 16;
for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunksCollection()) {
LevelChunk levelChunk = serverLevel.getChunk(bukkitChunk.getX(), bukkitChunk.getZ());
for (BlockEntity blockEntity : levelChunk.getBlockEntities().values()) {
if (blockEntity instanceof SpawnerBlockEntity spawnerBlockEntity)
if (blockEntity instanceof SpawnerBlockEntity spawnerBlockEntity) {
spawnerBlockEntity.getSpawner().requiredPlayerRange = requiredPlayerRange;
if (onSpawnerChangeCallback != null) {
BlockPos blockPos = blockEntity.getBlockPos();
Location location = new Location(bukkitWorld, blockPos.getX(), blockPos.getY(), blockPos.getZ());
onSpawnerChangeCallback.apply(location, requiredPlayerRange);
}
}
}
ChunkPos chunkPos = levelChunk.getPos();
@ -158,7 +173,8 @@ public final class NMSAdapterImpl implements NMSAdapter {
}
@Override
public void updateSpawner(Location location, boolean reset) {
public void updateSpawner(Location location, boolean reset,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
World bukkitWorld = location.getWorld();
if (bukkitWorld == null)
@ -167,8 +183,13 @@ public final class NMSAdapterImpl implements NMSAdapter {
ServerLevel serverLevel = ((CraftWorld) bukkitWorld).getHandle();
BlockPos blockPos = new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ());
BlockEntity blockEntity = serverLevel.getBlockEntity(blockPos);
if (blockEntity instanceof SpawnerBlockEntity spawnerBlockEntity)
spawnerBlockEntity.getSpawner().requiredPlayerRange = reset ? 16 : -1;
if (!(blockEntity instanceof SpawnerBlockEntity spawnerBlockEntity))
return;
int requiredPlayerRange = reset ? 16 : -1;
spawnerBlockEntity.getSpawner().requiredPlayerRange = requiredPlayerRange;
if (onSpawnerChangeCallback != null)
onSpawnerChangeCallback.apply(location, requiredPlayerRange);
}
}

View File

@ -26,6 +26,7 @@ import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.craftbukkit.inventory.CraftItemStack;
import javax.annotation.Nullable;
import java.util.Optional;
import java.util.UUID;
@ -97,7 +98,8 @@ public final class NMSAdapterImpl implements NMSAdapter {
}
@Override
public ITileEntityChunkLoader createLoader(ChunkLoader chunkLoader) {
public ITileEntityChunkLoader createLoader(ChunkLoader chunkLoader,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
Location loaderLoc = chunkLoader.getLocation();
World bukkitWorld = loaderLoc.getWorld();
@ -111,16 +113,18 @@ public final class NMSAdapterImpl implements NMSAdapter {
serverLevel.addBlockEntityTicker(ChunkLoaderBlockEntity.getTicker());
if (Scheduler.isRegionScheduler()) {
Scheduler.runTask(() -> setChunksForcedForLoader(chunkLoader, serverLevel, true));
Scheduler.runTask(() ->
setChunksForcedForLoader(chunkLoader, serverLevel, true, onSpawnerChangeCallback));
} else {
setChunksForcedForLoader(chunkLoader, serverLevel, true);
setChunksForcedForLoader(chunkLoader, serverLevel, true, onSpawnerChangeCallback);
}
return ChunkLoaderBlockEntity;
}
@Override
public void removeLoader(ChunkLoader chunkLoader, boolean spawnParticle) {
public void removeLoader(ChunkLoader chunkLoader, boolean spawnParticle,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
Location loaderLoc = chunkLoader.getLocation();
World bukkitWorld = loaderLoc.getWorld();
@ -142,20 +146,31 @@ public final class NMSAdapterImpl implements NMSAdapter {
serverLevel.levelEvent(null, 2001, blockPos, Block.getId(serverLevel.getBlockState(blockPos)));
if (Scheduler.isRegionScheduler()) {
Scheduler.runTask(() -> setChunksForcedForLoader(chunkLoader, serverLevel, false));
Scheduler.runTask(() ->
setChunksForcedForLoader(chunkLoader, serverLevel, false, onSpawnerChangeCallback));
} else {
setChunksForcedForLoader(chunkLoader, serverLevel, false);
setChunksForcedForLoader(chunkLoader, serverLevel, false, onSpawnerChangeCallback);
}
}
private static void setChunksForcedForLoader(ChunkLoader chunkLoader, ServerLevel serverLevel, boolean forced) {
private static void setChunksForcedForLoader(ChunkLoader chunkLoader, ServerLevel serverLevel, boolean forced,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
World bukkitWorld = serverLevel.getWorld();
int requiredPlayerRange = forced ? -1 : 16;
for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunksCollection()) {
LevelChunk levelChunk = serverLevel.getChunk(bukkitChunk.getX(), bukkitChunk.getZ());
for (BlockEntity blockEntity : levelChunk.getBlockEntities().values()) {
if (blockEntity instanceof SpawnerBlockEntity spawnerBlockEntity)
if (blockEntity instanceof SpawnerBlockEntity spawnerBlockEntity) {
spawnerBlockEntity.getSpawner().requiredPlayerRange = requiredPlayerRange;
if (onSpawnerChangeCallback != null) {
BlockPos blockPos = blockEntity.getBlockPos();
Location location = new Location(bukkitWorld, blockPos.getX(), blockPos.getY(), blockPos.getZ());
onSpawnerChangeCallback.apply(location, requiredPlayerRange);
}
}
}
ChunkPos chunkPos = levelChunk.getPos();
@ -164,7 +179,8 @@ public final class NMSAdapterImpl implements NMSAdapter {
}
@Override
public void updateSpawner(Location location, boolean reset) {
public void updateSpawner(Location location, boolean reset,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
World bukkitWorld = location.getWorld();
if (bukkitWorld == null)
@ -173,8 +189,13 @@ public final class NMSAdapterImpl implements NMSAdapter {
ServerLevel serverLevel = ((CraftWorld) bukkitWorld).getHandle();
BlockPos blockPos = new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ());
BlockEntity blockEntity = serverLevel.getBlockEntity(blockPos);
if (blockEntity instanceof SpawnerBlockEntity spawnerBlockEntity)
spawnerBlockEntity.getSpawner().requiredPlayerRange = reset ? 16 : -1;
if (!(blockEntity instanceof SpawnerBlockEntity spawnerBlockEntity))
return;
int requiredPlayerRange = reset ? 16 : -1;
spawnerBlockEntity.getSpawner().requiredPlayerRange = requiredPlayerRange;
if (onSpawnerChangeCallback != null)
onSpawnerChangeCallback.apply(location, requiredPlayerRange);
}
}

View File

@ -26,6 +26,7 @@ import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.craftbukkit.inventory.CraftItemStack;
import javax.annotation.Nullable;
import java.util.Optional;
import java.util.UUID;
@ -97,7 +98,8 @@ public final class NMSAdapterImpl implements NMSAdapter {
}
@Override
public ITileEntityChunkLoader createLoader(ChunkLoader chunkLoader) {
public ITileEntityChunkLoader createLoader(ChunkLoader chunkLoader,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
Location loaderLoc = chunkLoader.getLocation();
World bukkitWorld = loaderLoc.getWorld();
@ -111,16 +113,18 @@ public final class NMSAdapterImpl implements NMSAdapter {
serverLevel.addBlockEntityTicker(ChunkLoaderBlockEntity.getTicker());
if (Scheduler.isRegionScheduler()) {
Scheduler.runTask(() -> setChunksForcedForLoader(chunkLoader, serverLevel, true));
Scheduler.runTask(() ->
setChunksForcedForLoader(chunkLoader, serverLevel, true, onSpawnerChangeCallback));
} else {
setChunksForcedForLoader(chunkLoader, serverLevel, true);
setChunksForcedForLoader(chunkLoader, serverLevel, true, onSpawnerChangeCallback);
}
return ChunkLoaderBlockEntity;
}
@Override
public void removeLoader(ChunkLoader chunkLoader, boolean spawnParticle) {
public void removeLoader(ChunkLoader chunkLoader, boolean spawnParticle,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
Location loaderLoc = chunkLoader.getLocation();
World bukkitWorld = loaderLoc.getWorld();
@ -142,20 +146,31 @@ public final class NMSAdapterImpl implements NMSAdapter {
serverLevel.levelEvent(null, 2001, blockPos, Block.getId(serverLevel.getBlockState(blockPos)));
if (Scheduler.isRegionScheduler()) {
Scheduler.runTask(() -> setChunksForcedForLoader(chunkLoader, serverLevel, false));
Scheduler.runTask(() ->
setChunksForcedForLoader(chunkLoader, serverLevel, false, onSpawnerChangeCallback));
} else {
setChunksForcedForLoader(chunkLoader, serverLevel, false);
setChunksForcedForLoader(chunkLoader, serverLevel, false, onSpawnerChangeCallback);
}
}
private static void setChunksForcedForLoader(ChunkLoader chunkLoader, ServerLevel serverLevel, boolean forced) {
private static void setChunksForcedForLoader(ChunkLoader chunkLoader, ServerLevel serverLevel, boolean forced,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
World bukkitWorld = serverLevel.getWorld();
int requiredPlayerRange = forced ? -1 : 16;
for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunksCollection()) {
LevelChunk levelChunk = serverLevel.getChunk(bukkitChunk.getX(), bukkitChunk.getZ());
for (BlockEntity blockEntity : levelChunk.getBlockEntities().values()) {
if (blockEntity instanceof SpawnerBlockEntity spawnerBlockEntity)
if (blockEntity instanceof SpawnerBlockEntity spawnerBlockEntity) {
spawnerBlockEntity.getSpawner().requiredPlayerRange = requiredPlayerRange;
if (onSpawnerChangeCallback != null) {
BlockPos blockPos = blockEntity.getBlockPos();
Location location = new Location(bukkitWorld, blockPos.getX(), blockPos.getY(), blockPos.getZ());
onSpawnerChangeCallback.apply(location, requiredPlayerRange);
}
}
}
ChunkPos chunkPos = levelChunk.getPos();
@ -164,7 +179,8 @@ public final class NMSAdapterImpl implements NMSAdapter {
}
@Override
public void updateSpawner(Location location, boolean reset) {
public void updateSpawner(Location location, boolean reset,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
World bukkitWorld = location.getWorld();
if (bukkitWorld == null)
@ -173,8 +189,13 @@ public final class NMSAdapterImpl implements NMSAdapter {
ServerLevel serverLevel = ((CraftWorld) bukkitWorld).getHandle();
BlockPos blockPos = new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ());
BlockEntity blockEntity = serverLevel.getBlockEntity(blockPos);
if (blockEntity instanceof SpawnerBlockEntity spawnerBlockEntity)
spawnerBlockEntity.getSpawner().requiredPlayerRange = reset ? 16 : -1;
if (!(blockEntity instanceof SpawnerBlockEntity spawnerBlockEntity))
return;
int requiredPlayerRange = reset ? 16 : -1;
spawnerBlockEntity.getSpawner().requiredPlayerRange = requiredPlayerRange;
if (onSpawnerChangeCallback != null)
onSpawnerChangeCallback.apply(location, requiredPlayerRange);
}
}

View File

@ -26,6 +26,7 @@ import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.craftbukkit.inventory.CraftItemStack;
import javax.annotation.Nullable;
import java.util.Optional;
import java.util.UUID;
@ -97,7 +98,8 @@ public final class NMSAdapterImpl implements NMSAdapter {
}
@Override
public ITileEntityChunkLoader createLoader(ChunkLoader chunkLoader) {
public ITileEntityChunkLoader createLoader(ChunkLoader chunkLoader,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
Location loaderLoc = chunkLoader.getLocation();
World bukkitWorld = loaderLoc.getWorld();
@ -111,16 +113,18 @@ public final class NMSAdapterImpl implements NMSAdapter {
serverLevel.addBlockEntityTicker(ChunkLoaderBlockEntity.getTicker());
if (Scheduler.isRegionScheduler()) {
Scheduler.runTask(() -> setChunksForcedForLoader(chunkLoader, serverLevel, true));
Scheduler.runTask(() ->
setChunksForcedForLoader(chunkLoader, serverLevel, true, onSpawnerChangeCallback));
} else {
setChunksForcedForLoader(chunkLoader, serverLevel, true);
setChunksForcedForLoader(chunkLoader, serverLevel, true, onSpawnerChangeCallback);
}
return ChunkLoaderBlockEntity;
}
@Override
public void removeLoader(ChunkLoader chunkLoader, boolean spawnParticle) {
public void removeLoader(ChunkLoader chunkLoader, boolean spawnParticle,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
Location loaderLoc = chunkLoader.getLocation();
World bukkitWorld = loaderLoc.getWorld();
@ -142,20 +146,31 @@ public final class NMSAdapterImpl implements NMSAdapter {
serverLevel.levelEvent(null, 2001, blockPos, Block.getId(serverLevel.getBlockState(blockPos)));
if (Scheduler.isRegionScheduler()) {
Scheduler.runTask(() -> setChunksForcedForLoader(chunkLoader, serverLevel, false));
Scheduler.runTask(() ->
setChunksForcedForLoader(chunkLoader, serverLevel, false, onSpawnerChangeCallback));
} else {
setChunksForcedForLoader(chunkLoader, serverLevel, false);
setChunksForcedForLoader(chunkLoader, serverLevel, false, onSpawnerChangeCallback);
}
}
private static void setChunksForcedForLoader(ChunkLoader chunkLoader, ServerLevel serverLevel, boolean forced) {
private static void setChunksForcedForLoader(ChunkLoader chunkLoader, ServerLevel serverLevel, boolean forced,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
World bukkitWorld = serverLevel.getWorld();
int requiredPlayerRange = forced ? -1 : 16;
for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunksCollection()) {
LevelChunk levelChunk = serverLevel.getChunk(bukkitChunk.getX(), bukkitChunk.getZ());
for (BlockEntity blockEntity : levelChunk.getBlockEntities().values()) {
if (blockEntity instanceof SpawnerBlockEntity spawnerBlockEntity)
if (blockEntity instanceof SpawnerBlockEntity spawnerBlockEntity) {
spawnerBlockEntity.getSpawner().requiredPlayerRange = requiredPlayerRange;
if (onSpawnerChangeCallback != null) {
BlockPos blockPos = blockEntity.getBlockPos();
Location location = new Location(bukkitWorld, blockPos.getX(), blockPos.getY(), blockPos.getZ());
onSpawnerChangeCallback.apply(location, requiredPlayerRange);
}
}
}
ChunkPos chunkPos = levelChunk.getPos();
@ -164,7 +179,8 @@ public final class NMSAdapterImpl implements NMSAdapter {
}
@Override
public void updateSpawner(Location location, boolean reset) {
public void updateSpawner(Location location, boolean reset,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
World bukkitWorld = location.getWorld();
if (bukkitWorld == null)
@ -173,8 +189,13 @@ public final class NMSAdapterImpl implements NMSAdapter {
ServerLevel serverLevel = ((CraftWorld) bukkitWorld).getHandle();
BlockPos blockPos = new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ());
BlockEntity blockEntity = serverLevel.getBlockEntity(blockPos);
if (blockEntity instanceof SpawnerBlockEntity spawnerBlockEntity)
spawnerBlockEntity.getSpawner().requiredPlayerRange = reset ? 16 : -1;
if (!(blockEntity instanceof SpawnerBlockEntity spawnerBlockEntity))
return;
int requiredPlayerRange = reset ? 16 : -1;
spawnerBlockEntity.getSpawner().requiredPlayerRange = requiredPlayerRange;
if (onSpawnerChangeCallback != null)
onSpawnerChangeCallback.apply(location, requiredPlayerRange);
}
}

View File

@ -15,12 +15,14 @@ import net.minecraft.server.v1_7_R4.NBTTagString;
import net.minecraft.server.v1_7_R4.TileEntity;
import net.minecraft.server.v1_7_R4.TileEntityMobSpawner;
import net.minecraft.server.v1_7_R4.World;
import net.minecraft.server.v1_7_R4.WorldServer;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_7_R4.CraftChunk;
import org.bukkit.craftbukkit.v1_7_R4.CraftWorld;
import org.bukkit.craftbukkit.v1_7_R4.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_7_R4.util.LongHash;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.UUID;
@ -105,73 +107,98 @@ public final class NMSAdapterImpl implements NMSAdapter {
}
@Override
public ITileEntityChunkLoader createLoader(ChunkLoader chunkLoader) {
public ITileEntityChunkLoader createLoader(ChunkLoader chunkLoader,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
Location loaderLoc = chunkLoader.getLocation();
World world = ((CraftWorld) loaderLoc.getWorld()).getHandle();
WorldServer worldServer = ((CraftWorld) loaderLoc.getWorld()).getHandle();
int x = loaderLoc.getBlockX(), y = loaderLoc.getBlockY(), z = loaderLoc.getBlockZ();
TileEntityChunkLoader tileEntityChunkLoader = new TileEntityChunkLoader(chunkLoader, world, x, y, z);
TileEntityChunkLoader tileEntityChunkLoader = new TileEntityChunkLoader(chunkLoader, worldServer, x, y, z);
//noinspection unchecked
world.tileEntityList.add(tileEntityChunkLoader);
worldServer.tileEntityList.add(tileEntityChunkLoader);
if (Scheduler.isRegionScheduler()) {
Scheduler.runTask(() -> setSpawnersRangeForLoader(chunkLoader, true));
Scheduler.runTask(() ->
setSpawnersRangeForLoader(chunkLoader, worldServer, true, onSpawnerChangeCallback));
} else {
setSpawnersRangeForLoader(chunkLoader, true);
setSpawnersRangeForLoader(chunkLoader, worldServer, true, onSpawnerChangeCallback);
}
return tileEntityChunkLoader;
}
@Override
public void removeLoader(ChunkLoader chunkLoader, boolean spawnParticle) {
public void removeLoader(ChunkLoader chunkLoader, boolean spawnParticle,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
Location loaderLoc = chunkLoader.getLocation();
World world = ((CraftWorld) loaderLoc.getWorld()).getHandle();
WorldServer worldServer = ((CraftWorld) loaderLoc.getWorld()).getHandle();
int x = loaderLoc.getBlockX(), y = loaderLoc.getBlockY(), z = loaderLoc.getBlockZ();
long tileEntityLong = LongHash.toLong(x >> 4, z >> 4);
TileEntityChunkLoader tileEntityChunkLoader = TileEntityChunkLoader.tileEntityChunkLoaderMap.remove(tileEntityLong);
if (tileEntityChunkLoader != null) {
tileEntityChunkLoader.removed = true;
world.tileEntityList.remove(tileEntityChunkLoader);
worldServer.tileEntityList.remove(tileEntityChunkLoader);
}
if (spawnParticle)
world.a(null, 2001, x, y, z, Block.getId(world.getType(x, y, z)) + (world.getData(x, y, z) << 12));
worldServer.a(null, 2001, x, y, z,
Block.getId(worldServer.getType(x, y, z)) + (worldServer.getData(x, y, z) << 12));
if (Scheduler.isRegionScheduler()) {
Scheduler.runTask(() -> setSpawnersRangeForLoader(chunkLoader, false));
Scheduler.runTask(() ->
setSpawnersRangeForLoader(chunkLoader, worldServer, false, onSpawnerChangeCallback));
} else {
setSpawnersRangeForLoader(chunkLoader, false);
setSpawnersRangeForLoader(chunkLoader, worldServer, false, onSpawnerChangeCallback);
}
}
private static void setSpawnersRangeForLoader(ChunkLoader chunkLoader, boolean loaded) {
private static void setSpawnersRangeForLoader(ChunkLoader chunkLoader, WorldServer worldServer, boolean loaded,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
org.bukkit.World bukkitWorld = worldServer.getWorld();
short requiredPlayerRange = (short) (loaded ? -1 : 16);
for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunksCollection()) {
Chunk chunk = ((CraftChunk) bukkitChunk).getHandle();
for (TileEntity tileEntity : (Collection<TileEntity>) chunk.tileEntities.values()) {
if (tileEntity instanceof TileEntityMobSpawner) {
NBTTagCompound nbtTagCompound = new NBTTagCompound();
tileEntity.b(nbtTagCompound);
nbtTagCompound.setShort("RequiredPlayerRange", requiredPlayerRange);
tileEntity.a(nbtTagCompound);
setSpawnerRange((TileEntityMobSpawner) tileEntity, requiredPlayerRange);
if (onSpawnerChangeCallback != null) {
Location location = new Location(bukkitWorld, tileEntity.x, tileEntity.y, tileEntity.z);
onSpawnerChangeCallback.apply(location, requiredPlayerRange);
}
}
}
}
}
@Override
public void updateSpawner(Location location, boolean reset) {
World world = ((CraftWorld) location.getWorld()).getHandle();
public void updateSpawner(Location location, boolean reset,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
org.bukkit.World bukkitWorld = location.getWorld();
TileEntityMobSpawner mobSpawner = (TileEntityMobSpawner)
world.getTileEntity(location.getBlockX(), location.getBlockY(), location.getBlockZ());
if (bukkitWorld == null)
throw new IllegalArgumentException("Cannot remove loader in null world.");
World world = ((CraftWorld) bukkitWorld).getHandle();
TileEntity tileEntity = world.getTileEntity(location.getBlockX(), location.getBlockY(), location.getBlockZ());
if (!(tileEntity instanceof TileEntityMobSpawner))
return;
TileEntityMobSpawner mobSpawner = (TileEntityMobSpawner) tileEntity;
int requiredPlayerRange = reset ? 16 : -1;
setSpawnerRange(mobSpawner, requiredPlayerRange);
if (onSpawnerChangeCallback != null)
onSpawnerChangeCallback.apply(location, requiredPlayerRange);
}
private static void setSpawnerRange(TileEntityMobSpawner mobSpawner, int range) {
NBTTagCompound nbtTagCompound = new NBTTagCompound();
mobSpawner.b(nbtTagCompound);
nbtTagCompound.setShort("RequiredPlayerRange", (short) (reset ? 16 : -1));
nbtTagCompound.setShort("RequiredPlayerRange", (short) range);
mobSpawner.a(nbtTagCompound);
}

View File

@ -16,12 +16,14 @@ import net.minecraft.server.v1_8_R3.NBTTagString;
import net.minecraft.server.v1_8_R3.TileEntity;
import net.minecraft.server.v1_8_R3.TileEntityMobSpawner;
import net.minecraft.server.v1_8_R3.World;
import net.minecraft.server.v1_8_R3.WorldServer;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_8_R3.CraftChunk;
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_8_R3.util.LongHash;
import javax.annotation.Nullable;
import java.util.UUID;
public final class NMSAdapterImpl implements NMSAdapter {
@ -105,27 +107,30 @@ public final class NMSAdapterImpl implements NMSAdapter {
}
@Override
public ITileEntityChunkLoader createLoader(ChunkLoader chunkLoader) {
public ITileEntityChunkLoader createLoader(ChunkLoader chunkLoader,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
Location loaderLoc = chunkLoader.getLocation();
World world = ((CraftWorld) loaderLoc.getWorld()).getHandle();
WorldServer worldServer = ((CraftWorld) loaderLoc.getWorld()).getHandle();
BlockPosition blockPosition = new BlockPosition(loaderLoc.getX(), loaderLoc.getY(), loaderLoc.getZ());
TileEntityChunkLoader tileEntityChunkLoader = new TileEntityChunkLoader(chunkLoader, world, blockPosition);
world.tileEntityList.add(tileEntityChunkLoader);
TileEntityChunkLoader tileEntityChunkLoader = new TileEntityChunkLoader(chunkLoader, worldServer, blockPosition);
worldServer.tileEntityList.add(tileEntityChunkLoader);
if (Scheduler.isRegionScheduler()) {
Scheduler.runTask(() -> setSpawnersRangeForLoader(chunkLoader, true));
Scheduler.runTask(() ->
setSpawnersRangeForLoader(chunkLoader, worldServer, true, onSpawnerChangeCallback));
} else {
setSpawnersRangeForLoader(chunkLoader, true);
setSpawnersRangeForLoader(chunkLoader, worldServer, true, onSpawnerChangeCallback);
}
return tileEntityChunkLoader;
}
@Override
public void removeLoader(ChunkLoader chunkLoader, boolean spawnParticle) {
public void removeLoader(ChunkLoader chunkLoader, boolean spawnParticle,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
Location loaderLoc = chunkLoader.getLocation();
World world = ((CraftWorld) loaderLoc.getWorld()).getHandle();
WorldServer worldServer = ((CraftWorld) loaderLoc.getWorld()).getHandle();
BlockPosition blockPosition = new BlockPosition(loaderLoc.getX(), loaderLoc.getY(), loaderLoc.getZ());
long tileEntityLong = LongHash.toLong(blockPosition.getX() >> 4, blockPosition.getZ() >> 4);
@ -133,45 +138,68 @@ public final class NMSAdapterImpl implements NMSAdapter {
if (tileEntityChunkLoader != null) {
tileEntityChunkLoader.holograms.forEach(EntityHolograms::removeHologram);
tileEntityChunkLoader.removed = true;
world.tileEntityList.remove(tileEntityChunkLoader);
worldServer.tileEntityList.remove(tileEntityChunkLoader);
}
if (spawnParticle)
world.a(null, 2001, blockPosition, Block.getCombinedId(world.getType(blockPosition)));
worldServer.a(null, 2001, blockPosition, Block.getCombinedId(worldServer.getType(blockPosition)));
if (Scheduler.isRegionScheduler()) {
Scheduler.runTask(() -> setSpawnersRangeForLoader(chunkLoader, false));
Scheduler.runTask(() ->
setSpawnersRangeForLoader(chunkLoader, worldServer, false, onSpawnerChangeCallback));
} else {
setSpawnersRangeForLoader(chunkLoader, false);
setSpawnersRangeForLoader(chunkLoader, worldServer, false, onSpawnerChangeCallback);
}
}
private static void setSpawnersRangeForLoader(ChunkLoader chunkLoader, boolean loaded) {
private static void setSpawnersRangeForLoader(ChunkLoader chunkLoader, WorldServer worldServer, boolean loaded,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
org.bukkit.World bukkitWorld = worldServer.getWorld();
short requiredPlayerRange = (short) (loaded ? -1 : 16);
for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunksCollection()) {
Chunk chunk = ((CraftChunk) bukkitChunk).getHandle();
for (TileEntity tileEntity : chunk.tileEntities.values()) {
if (tileEntity instanceof TileEntityMobSpawner) {
NBTTagCompound nbtTagCompound = new NBTTagCompound();
tileEntity.b(nbtTagCompound);
nbtTagCompound.setShort("RequiredPlayerRange", requiredPlayerRange);
tileEntity.a(nbtTagCompound);
setSpawnerRange((TileEntityMobSpawner) tileEntity, requiredPlayerRange);
if (onSpawnerChangeCallback != null) {
BlockPosition blockPosition = tileEntity.getPosition();
Location location = new Location(bukkitWorld, blockPosition.getX(), blockPosition.getY(), blockPosition.getZ());
onSpawnerChangeCallback.apply(location, requiredPlayerRange);
}
}
}
}
}
@Override
public void updateSpawner(Location location, boolean reset) {
World world = ((CraftWorld) location.getWorld()).getHandle();
public void updateSpawner(Location location, boolean reset,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback) {
org.bukkit.World bukkitWorld = location.getWorld();
if (bukkitWorld == null)
throw new IllegalArgumentException("Cannot remove loader in null world.");
World world = ((CraftWorld) bukkitWorld).getHandle();
BlockPosition blockPosition = new BlockPosition(location.getX(), location.getY(), location.getZ());
TileEntityMobSpawner mobSpawner = (TileEntityMobSpawner) world.getTileEntity(blockPosition);
TileEntity tileEntity = world.getTileEntity(blockPosition);
if (!(tileEntity instanceof TileEntityMobSpawner))
return;
TileEntityMobSpawner mobSpawner = (TileEntityMobSpawner) tileEntity;
int requiredPlayerRange = reset ? 16 : -1;
setSpawnerRange(mobSpawner, requiredPlayerRange);
if (onSpawnerChangeCallback != null)
onSpawnerChangeCallback.apply(location, requiredPlayerRange);
}
private static void setSpawnerRange(TileEntityMobSpawner mobSpawner, int range) {
NBTTagCompound nbtTagCompound = new NBTTagCompound();
mobSpawner.b(nbtTagCompound);
nbtTagCompound.setShort("RequiredPlayerRange", (short) (reset ? 16 : -1));
nbtTagCompound.setShort("RequiredPlayerRange", (short) range);
mobSpawner.a(nbtTagCompound);
}

View File

@ -10,6 +10,7 @@ import com.bgsoftware.wildloaders.loaders.WLoaderData;
import com.bgsoftware.wildloaders.utils.BlockPosition;
import com.bgsoftware.wildloaders.utils.ChunkLoaderChunks;
import com.bgsoftware.wildloaders.utils.ServerVersion;
import com.bgsoftware.wildloaders.utils.SpawnerChangeListener;
import com.bgsoftware.wildloaders.utils.chunks.ChunkPosition;
import com.bgsoftware.wildloaders.utils.database.Query;
import com.google.common.collect.Maps;
@ -143,7 +144,7 @@ public final class LoadersHandler implements LoadersManager {
List<UnloadedChunkLoader> unloadedChunkLoaders = new LinkedList<>();
worldChunkLoaders.forEach(chunkLoader -> {
plugin.getNMSAdapter().removeLoader(chunkLoader, false);
plugin.getNMSAdapter().removeLoader(chunkLoader, false, SpawnerChangeListener.CALLBACK);
BlockPosition blockPosition = removeChunkLoaderWithoutDBSave(chunkLoader);
UnloadedChunkLoader unloadedChunkLoader = new UnloadedChunkLoader(chunkLoader.getLoaderData(),
chunkLoader.getWhoPlaced().getUniqueId(), blockPosition, chunkLoader.getTimeLeft());
@ -195,7 +196,8 @@ public final class LoadersHandler implements LoadersManager {
@Override
public void removeChunkLoaders() {
chunkLoaders.values().forEach(chunkLoader -> plugin.getNMSAdapter().removeLoader(chunkLoader, false));
chunkLoaders.values().forEach(chunkLoader ->
plugin.getNMSAdapter().removeLoader(chunkLoader, false, SpawnerChangeListener.CALLBACK));
chunkLoaders.clear();
chunkLoadersByChunks.clear();
chunkLoadersByWorlds.clear();

View File

@ -2,13 +2,16 @@ package com.bgsoftware.wildloaders.handlers;
import com.bgsoftware.wildloaders.WildLoadersPlugin;
import com.bgsoftware.wildloaders.api.hooks.ClaimsProvider;
import com.bgsoftware.wildloaders.api.hooks.SpawnersProvider;
import com.bgsoftware.wildloaders.api.hooks.TickableProvider;
import com.bgsoftware.wildloaders.api.hooks.WorldsProvider;
import com.bgsoftware.wildloaders.api.managers.ProvidersManager;
import com.bgsoftware.wildloaders.scheduler.Scheduler;
import com.bgsoftware.wildloaders.utils.SpawnerChangeListener;
import com.google.common.base.Preconditions;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.plugin.Plugin;
@ -27,6 +30,7 @@ public final class ProvidersHandler implements ProvidersManager {
private final List<ClaimsProvider> claimsProviders = new LinkedList<>();
private final List<TickableProvider> tickableProviders = new LinkedList<>();
private final List<WorldsProvider> worldsProviders = new LinkedList<>();
private final List<SpawnersProvider> spawnersProviders = new LinkedList<>();
public ProvidersHandler(WildLoadersPlugin plugin) {
this.plugin = plugin;
@ -108,6 +112,13 @@ public final class ProvidersHandler implements ProvidersManager {
claimsProviders.add(claimsProvider);
}
@Override
public void addSpawnersProvider(SpawnersProvider spawnersProvider) {
Preconditions.checkNotNull(spawnersProvider, "spawnersProvider cannot be null");
spawnersProviders.add(spawnersProvider);
SpawnerChangeListener.CALLBACK = this::setSpawnerRequiredRange;
}
@Override
public void addTickableProvider(TickableProvider tickableProvider) {
Preconditions.checkNotNull(tickableProvider, "tickableProvider cannot be null");
@ -133,6 +144,12 @@ public final class ProvidersHandler implements ProvidersManager {
tickableProviders.forEach(tickableProvider -> tickableProvider.tick(chunks));
}
public void setSpawnerRequiredRange(Location spawnerLocation, int requiredRange) {
for (SpawnersProvider spawnersProvider : this.spawnersProviders) {
spawnersProvider.setSpawnerRequiredRange(spawnerLocation, requiredRange);
}
}
@Nullable
public World loadWorld(String worldName) {
for (WorldsProvider worldsProvider : this.worldsProviders) {

View File

@ -5,6 +5,7 @@ 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.SpawnerChangeListener;
import com.bgsoftware.wildloaders.utils.chunks.ChunkPosition;
import com.bgsoftware.wildloaders.utils.legacy.Materials;
import org.bukkit.Chunk;
@ -85,7 +86,7 @@ public final class BlocksListener implements Listener {
if (!plugin.getLoaders().getChunkLoader(e.getBlock().getChunk()).isPresent())
return;
plugin.getNMSAdapter().updateSpawner(e.getBlock().getLocation(), false);
plugin.getNMSAdapter().updateSpawner(e.getBlock().getLocation(), false, SpawnerChangeListener.CALLBACK);
}
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)

View File

@ -7,6 +7,7 @@ import com.bgsoftware.wildloaders.api.loaders.LoaderData;
import com.bgsoftware.wildloaders.api.npc.ChunkLoaderNPC;
import com.bgsoftware.wildloaders.scheduler.Scheduler;
import com.bgsoftware.wildloaders.utils.BlockPosition;
import com.bgsoftware.wildloaders.utils.SpawnerChangeListener;
import com.bgsoftware.wildloaders.utils.database.Query;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
@ -40,7 +41,7 @@ public final class WChunkLoader implements ChunkLoader {
this.blockPosition = blockPosition;
this.loadedChunks = loadedChunks;
this.timeLeft = timeLeft;
this.tileEntityChunkLoader = plugin.getNMSAdapter().createLoader(this);
this.tileEntityChunkLoader = plugin.getNMSAdapter().createLoader(this, SpawnerChangeListener.CALLBACK);
}
@Override
@ -115,7 +116,8 @@ public final class WChunkLoader implements ChunkLoader {
}
private void removeInternal() {
plugin.getNMSAdapter().removeLoader(this, timeLeft <= 0 || isNotActive());
plugin.getNMSAdapter().removeLoader(this, timeLeft <= 0 || isNotActive(),
SpawnerChangeListener.CALLBACK);
plugin.getLoaders().removeChunkLoader(this);
getLocation().getBlock().setType(Material.AIR);

View File

@ -6,6 +6,7 @@ import com.bgsoftware.wildloaders.loaders.ITileEntityChunkLoader;
import org.bukkit.Location;
import org.bukkit.inventory.ItemStack;
import javax.annotation.Nullable;
import java.util.UUID;
public interface NMSAdapter {
@ -22,10 +23,18 @@ public interface NMSAdapter {
ChunkLoaderNPC createNPC(Location location, UUID uuid);
ITileEntityChunkLoader createLoader(ChunkLoader chunkLoader);
ITileEntityChunkLoader createLoader(ChunkLoader chunkLoader,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback);
void removeLoader(ChunkLoader chunkLoader, boolean spawnParticle);
void removeLoader(ChunkLoader chunkLoader, boolean spawnParticle,
@Nullable OnSpawnerChangeCallback onSpawnerChangeCallback);
void updateSpawner(Location location, boolean reset);
void updateSpawner(Location location, boolean reset, @Nullable OnSpawnerChangeCallback onSpawnerChangeCallback);
interface OnSpawnerChangeCallback {
void apply(Location blockLocation, int newRange);
}
}

View File

@ -0,0 +1,13 @@
package com.bgsoftware.wildloaders.utils;
import com.bgsoftware.wildloaders.nms.NMSAdapter;
public class SpawnerChangeListener {
public static NMSAdapter.OnSpawnerChangeCallback CALLBACK = null;
private SpawnerChangeListener() {
}
}