mirror of
https://github.com/BG-Software-LLC/WildLoaders.git
synced 2024-11-23 12:05:22 +01:00
Merge branch 'dev'
This commit is contained in:
commit
f5bfbe2281
@ -2,12 +2,28 @@ package com.bgsoftware.wildloaders.api.hooks;
|
||||
|
||||
import org.bukkit.Chunk;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public interface TickableProvider {
|
||||
|
||||
/**
|
||||
* Simulate a tick on a list of provided chunks.
|
||||
*
|
||||
* @param chunks The chunks to tick.
|
||||
* @deprecated See {@link #tick(Collection)}
|
||||
*/
|
||||
@Deprecated
|
||||
default void tick(Chunk[] chunks) {
|
||||
throw new UnsupportedOperationException("TickableProvider#tick is not supported anymore");
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulate a tick on a list of provided chunks.
|
||||
*
|
||||
* @param chunks The chunks to tick.
|
||||
*/
|
||||
void tick(Chunk[] chunks);
|
||||
default void tick(Collection<Chunk> chunks) {
|
||||
tick(chunks.toArray(new Chunk[0]));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,18 @@
|
||||
package com.bgsoftware.wildloaders.api.hooks;
|
||||
|
||||
import org.bukkit.World;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public interface WorldsProvider {
|
||||
|
||||
/**
|
||||
* Load a world.
|
||||
*
|
||||
* @param worldName The name of the world
|
||||
* @return The loaded world, or null if couldn't load the world.
|
||||
*/
|
||||
@Nullable
|
||||
World loadWorld(String worldName);
|
||||
|
||||
}
|
@ -34,9 +34,17 @@ public interface ChunkLoader {
|
||||
|
||||
/**
|
||||
* Get the chunks that this chunk-loader is loading.
|
||||
*
|
||||
* @deprecated See {@link #getLoadedChunksCollection()}
|
||||
*/
|
||||
@Deprecated
|
||||
Chunk[] getLoadedChunks();
|
||||
|
||||
/**
|
||||
* Get the chunks that this chunk-loader is loading.
|
||||
*/
|
||||
Collection<Chunk> getLoadedChunksCollection();
|
||||
|
||||
/**
|
||||
* Get the NPC of this chunk loader.
|
||||
*/
|
||||
|
@ -2,6 +2,7 @@ package com.bgsoftware.wildloaders.api.managers;
|
||||
|
||||
import com.bgsoftware.wildloaders.api.hooks.ClaimsProvider;
|
||||
import com.bgsoftware.wildloaders.api.hooks.TickableProvider;
|
||||
import com.bgsoftware.wildloaders.api.hooks.WorldsProvider;
|
||||
|
||||
public interface ProvidersManager {
|
||||
|
||||
@ -17,4 +18,11 @@ public interface ProvidersManager {
|
||||
*/
|
||||
void addTickableProvider(TickableProvider tickableProvider);
|
||||
|
||||
/**
|
||||
* Add a worlds provider to the plugin.
|
||||
*
|
||||
* @param worldsProvider The worlds provider to add.
|
||||
*/
|
||||
void addWorldsProvider(WorldsProvider worldsProvider);
|
||||
|
||||
}
|
||||
|
19
Hooks/AdvancedSlimePaper/build.gradle
Normal file
19
Hooks/AdvancedSlimePaper/build.gradle
Normal file
@ -0,0 +1,19 @@
|
||||
group 'Hooks:AdvancedSlimePaper'
|
||||
|
||||
java {
|
||||
toolchain {
|
||||
languageVersion.set(JavaLanguageVersion.of(17))
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly 'com.infernalsuite:AdvancedSlimePaper:1.19.4-R0.1'
|
||||
compileOnly "org.spigotmc:v1_8_R3-Taco:latest"
|
||||
compileOnly project(":API")
|
||||
compileOnly rootProject
|
||||
}
|
||||
|
||||
if (project.hasProperty('hook.compile_advancedslimepaper') &&
|
||||
!Boolean.valueOf(project.findProperty("hook.compile_advancedslimepaper").toString())) {
|
||||
project.tasks.all { task -> task.enabled = false }
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package com.bgsoftware.wildloaders.hooks;
|
||||
|
||||
import com.bgsoftware.wildloaders.WildLoadersPlugin;
|
||||
import com.bgsoftware.wildloaders.api.hooks.WorldsProvider;
|
||||
import com.infernalsuite.aswm.api.SlimePlugin;
|
||||
import com.infernalsuite.aswm.api.loaders.SlimeLoader;
|
||||
import com.infernalsuite.aswm.api.world.SlimeWorld;
|
||||
import com.infernalsuite.aswm.api.world.properties.SlimePropertyMap;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class WorldsProvider_AdvancedSlimePaper implements WorldsProvider {
|
||||
|
||||
private static final List<String> WORLD_LOADERS = Arrays.asList("file", "mysql", "mongodb", "redis", "api");
|
||||
private static final SlimePropertyMap EMPTY_PROPERTIES = new SlimePropertyMap();
|
||||
|
||||
private final SlimePlugin slimePlugin;
|
||||
|
||||
public WorldsProvider_AdvancedSlimePaper() {
|
||||
this.slimePlugin = (SlimePlugin) Bukkit.getPluginManager().getPlugin("SlimeWorldManager");
|
||||
}
|
||||
|
||||
@Override
|
||||
public World loadWorld(String worldName) {
|
||||
for (String loaderName : WORLD_LOADERS) {
|
||||
SlimeLoader slimeLoader = this.slimePlugin.getLoader(loaderName);
|
||||
try {
|
||||
if (slimeLoader != null && slimeLoader.worldExists(worldName)) {
|
||||
SlimeWorld slimeWorld = slimePlugin.loadWorld(slimeLoader, worldName, false, EMPTY_PROPERTIES);
|
||||
if (slimeWorld != null) {
|
||||
slimePlugin.loadWorld(slimeWorld);
|
||||
World bukkitWorld = Bukkit.getWorld(slimeWorld.getName());
|
||||
if (bukkitWorld != null)
|
||||
return bukkitWorld;
|
||||
}
|
||||
}
|
||||
} catch (Exception error) {
|
||||
WildLoadersPlugin.log("An error occurred while trying to load world " + worldName);
|
||||
error.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
19
Hooks/AdvancedSlimeWorldManager/build.gradle
Normal file
19
Hooks/AdvancedSlimeWorldManager/build.gradle
Normal file
@ -0,0 +1,19 @@
|
||||
group 'Hooks:AdvancedSlimeWorldManager'
|
||||
|
||||
java {
|
||||
toolchain {
|
||||
languageVersion.set(JavaLanguageVersion.of(17))
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly "com.grinderwolf:slimeworldmanager-api:2.10.0"
|
||||
compileOnly "org.spigotmc:v1_8_R3-Taco:latest"
|
||||
compileOnly project(":API")
|
||||
compileOnly rootProject
|
||||
}
|
||||
|
||||
if (project.hasProperty('hook.compile_advancedslimeworldmanager') &&
|
||||
!Boolean.valueOf(project.findProperty("hook.compile_advancedslimeworldmanager").toString())) {
|
||||
project.tasks.all { task -> task.enabled = false }
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package com.bgsoftware.wildloaders.hooks;
|
||||
|
||||
import com.bgsoftware.wildloaders.WildLoadersPlugin;
|
||||
import com.bgsoftware.wildloaders.api.hooks.WorldsProvider;
|
||||
import com.grinderwolf.swm.api.SlimePlugin;
|
||||
import com.grinderwolf.swm.api.loaders.SlimeLoader;
|
||||
import com.grinderwolf.swm.api.world.SlimeWorld;
|
||||
import com.grinderwolf.swm.api.world.properties.SlimePropertyMap;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class WorldsProvider_AdvancedSlimeWorldManager implements WorldsProvider {
|
||||
|
||||
private static final List<String> WORLD_LOADERS = Arrays.asList("file", "mysql", "mongodb", "redis", "api");
|
||||
private static final SlimePropertyMap EMPTY_PROPERTIES = new SlimePropertyMap();
|
||||
|
||||
private final SlimePlugin slimePlugin;
|
||||
|
||||
public WorldsProvider_AdvancedSlimeWorldManager() {
|
||||
this.slimePlugin = (SlimePlugin) Bukkit.getPluginManager().getPlugin("SlimeWorldManager");
|
||||
}
|
||||
|
||||
@Override
|
||||
public World loadWorld(String worldName) {
|
||||
for (String loaderName : WORLD_LOADERS) {
|
||||
SlimeLoader slimeLoader = this.slimePlugin.getLoader(loaderName);
|
||||
try {
|
||||
if (slimeLoader != null && slimeLoader.worldExists(worldName)) {
|
||||
SlimeWorld slimeWorld = slimePlugin.loadWorld(slimeLoader, worldName, false, EMPTY_PROPERTIES);
|
||||
if (slimeWorld != null) {
|
||||
World bukkitWorld = Bukkit.getWorld(slimeWorld.getName());
|
||||
if (bukkitWorld != null)
|
||||
return bukkitWorld;
|
||||
}
|
||||
}
|
||||
} catch (Exception error) {
|
||||
WildLoadersPlugin.log("An error occurred while trying to load world " + worldName);
|
||||
error.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -5,25 +5,26 @@ import com.songoda.epicspawners.EpicSpawners;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.Set;
|
||||
|
||||
public final class TickableProvider_EpicSpawners6 implements TickableProvider {
|
||||
|
||||
private final Map<Location, TickDelay> spawnerDelays = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void tick(Chunk[] chunks) {
|
||||
public void tick(Collection<Chunk> chunks) {
|
||||
if (EpicSpawners.getInstance().getSpawnerManager() == null)
|
||||
return;
|
||||
|
||||
List<Long> chunkList = Stream.of(chunks).map(chunk -> pair(chunk.getX(), chunk.getZ())).collect(Collectors.toList());
|
||||
Set<Long> chunkKeys = new HashSet<>();
|
||||
chunks.forEach(chunk -> chunkKeys.add(pair(chunk.getX(), chunk.getZ())));
|
||||
|
||||
EpicSpawners.getInstance().getSpawnerManager().getSpawners().stream()
|
||||
.filter(spawner -> chunkList.contains(pair(spawner.getX() >> 4, spawner.getZ() >> 4)))
|
||||
.filter(spawner -> chunkKeys.contains(pair(spawner.getX() >> 4, spawner.getZ() >> 4)))
|
||||
.forEach(spawner -> {
|
||||
Location location = spawner.getLocation();
|
||||
TickDelay tickDelay = spawnerDelays.get(location);
|
||||
|
@ -5,25 +5,26 @@ import com.songoda.epicspawners.EpicSpawners;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.Set;
|
||||
|
||||
public final class TickableProvider_EpicSpawners7 implements TickableProvider {
|
||||
|
||||
private final Map<Location, TickDelay> spawnerDelays = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void tick(Chunk[] chunks) {
|
||||
public void tick(Collection<Chunk> chunks) {
|
||||
if (EpicSpawners.getInstance().getSpawnerManager() == null)
|
||||
return;
|
||||
|
||||
List<Long> chunkList = Stream.of(chunks).map(chunk -> pair(chunk.getX(), chunk.getZ())).collect(Collectors.toList());
|
||||
Set<Long> chunkKeys = new HashSet<>();
|
||||
chunks.forEach(chunk -> chunkKeys.add(pair(chunk.getX(), chunk.getZ())));
|
||||
|
||||
EpicSpawners.getInstance().getSpawnerManager().getSpawners().stream()
|
||||
.filter(spawner -> chunkList.contains(pair(spawner.getX() >> 4, spawner.getZ() >> 4)))
|
||||
.filter(spawner -> chunkKeys.contains(pair(spawner.getX() >> 4, spawner.getZ() >> 4)))
|
||||
.forEach(spawner -> {
|
||||
Location location = spawner.getLocation();
|
||||
TickDelay tickDelay = spawnerDelays.get(location);
|
||||
|
@ -5,25 +5,26 @@ import com.craftaro.epicspawners.api.EpicSpawnersApi;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.Set;
|
||||
|
||||
public final class TickableProvider_EpicSpawners8 implements TickableProvider {
|
||||
|
||||
private final Map<Location, TickDelay> spawnerDelays = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void tick(Chunk[] chunks) {
|
||||
public void tick(Collection<Chunk> chunks) {
|
||||
if (EpicSpawnersApi.getSpawnerManager() == null)
|
||||
return;
|
||||
|
||||
List<Long> chunkList = Stream.of(chunks).map(chunk -> pair(chunk.getX(), chunk.getZ())).collect(Collectors.toList());
|
||||
Set<Long> chunkKeys = new HashSet<>();
|
||||
chunks.forEach(chunk -> chunkKeys.add(pair(chunk.getX(), chunk.getZ())));
|
||||
|
||||
EpicSpawnersApi.getSpawnerManager().getSpawners().stream()
|
||||
.filter(spawner -> chunkList.contains(pair(spawner.getX() >> 4, spawner.getZ() >> 4)))
|
||||
.filter(spawner -> chunkKeys.contains(pair(spawner.getX() >> 4, spawner.getZ() >> 4)))
|
||||
.forEach(spawner -> {
|
||||
Location location = spawner.getLocation();
|
||||
TickDelay tickDelay = spawnerDelays.get(location);
|
||||
|
22
Hooks/Folia/build.gradle
Normal file
22
Hooks/Folia/build.gradle
Normal file
@ -0,0 +1,22 @@
|
||||
group 'Hooks:Folia'
|
||||
|
||||
java {
|
||||
toolchain {
|
||||
languageVersion.set(JavaLanguageVersion.of(17))
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven { url 'https://repo.papermc.io/repository/maven-public/' }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly 'dev.folia:folia-api:1.20.1-R0.1-SNAPSHOT'
|
||||
compileOnly project(":API")
|
||||
compileOnly rootProject
|
||||
}
|
||||
|
||||
if (project.hasProperty('hook.compile_folia') &&
|
||||
!Boolean.valueOf(project.findProperty("hook.compile_folia").toString())) {
|
||||
project.tasks.all { task -> task.enabled = false }
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
package com.bgsoftware.wildloaders.scheduler;
|
||||
|
||||
import com.bgsoftware.wildloaders.WildLoadersPlugin;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class FoliaSchedulerImplementation implements ISchedulerImplementation {
|
||||
|
||||
public static final FoliaSchedulerImplementation INSTANCE = new FoliaSchedulerImplementation();
|
||||
|
||||
private static final WildLoadersPlugin plugin = WildLoadersPlugin.getPlugin();
|
||||
|
||||
private FoliaSchedulerImplementation() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRegionScheduler() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScheduledTask scheduleTask(World world, int chunkX, int chunkZ, Runnable task, long delay) {
|
||||
io.papermc.paper.threadedregions.scheduler.ScheduledTask handle;
|
||||
if (delay <= 0) {
|
||||
handle = Bukkit.getServer().getRegionScheduler().run(plugin, world, chunkX, chunkZ, v -> task.run());
|
||||
} else {
|
||||
handle = Bukkit.getServer().getRegionScheduler().runDelayed(plugin, world, chunkX, chunkZ, v -> task.run(), delay);
|
||||
}
|
||||
return new FoliaScheduledTask(handle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScheduledTask scheduleTask(Entity entity, Runnable task, long delay) {
|
||||
io.papermc.paper.threadedregions.scheduler.ScheduledTask handle;
|
||||
if (delay <= 0) {
|
||||
handle = entity.getScheduler().run(plugin, v -> task.run(), task);
|
||||
} else {
|
||||
handle = entity.getScheduler().runDelayed(plugin, v -> task.run(), task, delay);
|
||||
}
|
||||
return new FoliaScheduledTask(handle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScheduledTask scheduleTask(Runnable task, long delay) {
|
||||
io.papermc.paper.threadedregions.scheduler.ScheduledTask handle;
|
||||
if (delay <= 0) {
|
||||
handle = Bukkit.getServer().getGlobalRegionScheduler().run(plugin, v -> task.run());
|
||||
} else {
|
||||
handle = Bukkit.getServer().getGlobalRegionScheduler().runDelayed(plugin, v -> task.run(), delay);
|
||||
}
|
||||
|
||||
return new FoliaScheduledTask(handle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScheduledTask scheduleAsyncTask(Runnable task, long delay) {
|
||||
io.papermc.paper.threadedregions.scheduler.ScheduledTask handle;
|
||||
if (delay <= 0) {
|
||||
handle = Bukkit.getServer().getAsyncScheduler().runNow(plugin, v -> task.run());
|
||||
} else {
|
||||
handle = Bukkit.getServer().getAsyncScheduler().runDelayed(plugin, v -> task.run(), delay * 50L, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
return new FoliaScheduledTask(handle);
|
||||
}
|
||||
|
||||
private static class FoliaScheduledTask implements ScheduledTask {
|
||||
|
||||
private final io.papermc.paper.threadedregions.scheduler.ScheduledTask handle;
|
||||
|
||||
public FoliaScheduledTask(io.papermc.paper.threadedregions.scheduler.ScheduledTask handle) {
|
||||
this.handle = handle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
if (!handle.isCancelled())
|
||||
handle.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
13
Hooks/SlimeWorldManager/build.gradle
Normal file
13
Hooks/SlimeWorldManager/build.gradle
Normal file
@ -0,0 +1,13 @@
|
||||
group 'Hooks:SlimeWorldManager'
|
||||
|
||||
dependencies {
|
||||
compileOnly "com.grinderwolf:slimeworldmanager-api:2.2.1"
|
||||
compileOnly "org.spigotmc:v1_8_R3-Taco:latest"
|
||||
compileOnly project(":API")
|
||||
compileOnly rootProject
|
||||
}
|
||||
|
||||
if (project.hasProperty('hook.compile_slimeworldmanager') &&
|
||||
!Boolean.valueOf(project.findProperty("hook.compile_slimeworldmanager").toString())) {
|
||||
project.tasks.all { task -> task.enabled = false }
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package com.bgsoftware.wildloaders.hooks;
|
||||
|
||||
import com.bgsoftware.wildloaders.WildLoadersPlugin;
|
||||
import com.bgsoftware.wildloaders.api.hooks.WorldsProvider;
|
||||
import com.grinderwolf.swm.api.SlimePlugin;
|
||||
import com.grinderwolf.swm.api.loaders.SlimeLoader;
|
||||
import com.grinderwolf.swm.api.world.SlimeWorld;
|
||||
import com.grinderwolf.swm.api.world.properties.SlimePropertyMap;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class WorldsProvider_SlimeWorldManager implements WorldsProvider {
|
||||
|
||||
private static final List<String> WORLD_LOADERS = Arrays.asList("file", "mysql", "mongodb", "redis", "api");
|
||||
private static final SlimePropertyMap EMPTY_PROPERTIES = new SlimePropertyMap();
|
||||
|
||||
private final SlimePlugin slimePlugin;
|
||||
|
||||
public WorldsProvider_SlimeWorldManager() {
|
||||
this.slimePlugin = (SlimePlugin) Bukkit.getPluginManager().getPlugin("SlimeWorldManager");
|
||||
}
|
||||
|
||||
@Override
|
||||
public World loadWorld(String worldName) {
|
||||
for (String loaderName : WORLD_LOADERS) {
|
||||
SlimeLoader slimeLoader = this.slimePlugin.getLoader(loaderName);
|
||||
try {
|
||||
if (slimeLoader != null && slimeLoader.worldExists(worldName)) {
|
||||
SlimeWorld slimeWorld = slimePlugin.loadWorld(slimeLoader, worldName, false, EMPTY_PROPERTIES);
|
||||
if (slimeWorld != null) {
|
||||
World bukkitWorld = Bukkit.getWorld(slimeWorld.getName());
|
||||
if (bukkitWorld != null)
|
||||
return bukkitWorld;
|
||||
}
|
||||
}
|
||||
} catch (Exception error) {
|
||||
WildLoadersPlugin.log("An error occurred while trying to load world " + worldName);
|
||||
error.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
package com.bgsoftware.wildloaders.nms.v1_12_R1;
|
||||
|
||||
import com.bgsoftware.common.reflection.ReflectField;
|
||||
import com.bgsoftware.common.reflection.ReflectMethod;
|
||||
import com.bgsoftware.wildloaders.handlers.NPCHandler;
|
||||
import com.bgsoftware.wildloaders.npc.DummyChannel;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
@ -38,6 +40,11 @@ import java.util.UUID;
|
||||
|
||||
public final class ChunkLoaderNPC extends EntityPlayer implements com.bgsoftware.wildloaders.api.npc.ChunkLoaderNPC {
|
||||
|
||||
private static final ReflectMethod<Void> PLAYER_SET_VIEW_DISTANCE = new ReflectMethod<>(
|
||||
EntityPlayer.class, "setViewDistance", int.class);
|
||||
private static final ReflectField<Boolean> PLAYER_AFFECTS_SPAWNING = new ReflectField<>(
|
||||
EntityPlayer.class, boolean.class, "affectsSpawning");
|
||||
|
||||
private final AxisAlignedBB boundingBox;
|
||||
private final AdvancementDataPlayer advancements;
|
||||
|
||||
@ -53,8 +60,15 @@ public final class ChunkLoaderNPC extends EntityPlayer implements com.bgsoftware
|
||||
this.advancements = new DummyPlayerAdvancements(server, this);
|
||||
|
||||
this.playerInteractManager.setGameMode(EnumGamemode.CREATIVE);
|
||||
|
||||
fallDistance = 0.0F;
|
||||
fauxSleeping = true;
|
||||
|
||||
if (PLAYER_SET_VIEW_DISTANCE.isValid())
|
||||
PLAYER_SET_VIEW_DISTANCE.invoke(this, 0);
|
||||
if (PLAYER_AFFECTS_SPAWNING.isValid())
|
||||
PLAYER_AFFECTS_SPAWNING.set(this, true);
|
||||
|
||||
spawnIn(world);
|
||||
setLocation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
|
||||
|
||||
|
@ -5,6 +5,7 @@ import com.bgsoftware.wildloaders.api.loaders.ChunkLoader;
|
||||
import com.bgsoftware.wildloaders.loaders.ITileEntityChunkLoader;
|
||||
import com.bgsoftware.wildloaders.nms.NMSAdapter;
|
||||
import com.bgsoftware.wildloaders.nms.v1_12_R1.loader.TileEntityChunkLoader;
|
||||
import com.bgsoftware.wildloaders.scheduler.Scheduler;
|
||||
import net.minecraft.server.v1_12_R1.Block;
|
||||
import net.minecraft.server.v1_12_R1.BlockPosition;
|
||||
import net.minecraft.server.v1_12_R1.Chunk;
|
||||
@ -113,18 +114,10 @@ public final class NMSAdapterImpl implements NMSAdapter {
|
||||
TileEntityChunkLoader tileEntityChunkLoader = new TileEntityChunkLoader(chunkLoader, world, blockPosition);
|
||||
world.tileEntityListTick.add(tileEntityChunkLoader);
|
||||
|
||||
for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunks()) {
|
||||
Chunk chunk = ((CraftChunk) bukkitChunk).getHandle();
|
||||
chunk.tileEntities.values().stream().filter(tileEntity -> tileEntity instanceof TileEntityMobSpawner).forEach(tileEntity -> {
|
||||
NBTTagCompound nbtTagCompound = new NBTTagCompound();
|
||||
tileEntity.save(nbtTagCompound);
|
||||
nbtTagCompound.setShort("RequiredPlayerRange", (short) -1);
|
||||
if (TILE_ENTITY_LOAD.isValid()) {
|
||||
TILE_ENTITY_LOAD.invoke(tileEntity, nbtTagCompound);
|
||||
if (Scheduler.isRegionScheduler()) {
|
||||
Scheduler.runTask(() -> setSpawnersRangeForLoader(chunkLoader, true));
|
||||
} else {
|
||||
tileEntity.a(nbtTagCompound);
|
||||
}
|
||||
});
|
||||
setSpawnersRangeForLoader(chunkLoader, true);
|
||||
}
|
||||
|
||||
return tileEntityChunkLoader;
|
||||
@ -147,18 +140,30 @@ public final class NMSAdapterImpl implements NMSAdapter {
|
||||
if (spawnParticle)
|
||||
world.a(null, 2001, blockPosition, Block.getCombinedId(world.getType(blockPosition)));
|
||||
|
||||
for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunks()) {
|
||||
if (Scheduler.isRegionScheduler()) {
|
||||
Scheduler.runTask(() -> setSpawnersRangeForLoader(chunkLoader, false));
|
||||
} else {
|
||||
setSpawnersRangeForLoader(chunkLoader, false);
|
||||
}
|
||||
}
|
||||
|
||||
private static void setSpawnersRangeForLoader(ChunkLoader chunkLoader, boolean loaded) {
|
||||
short requiredPlayerRange = (short) (loaded ? -1 : 16);
|
||||
for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunksCollection()) {
|
||||
Chunk chunk = ((CraftChunk) bukkitChunk).getHandle();
|
||||
chunk.tileEntities.values().stream().filter(tileEntity -> tileEntity instanceof TileEntityMobSpawner).forEach(tileEntity -> {
|
||||
|
||||
for (TileEntity tileEntity : chunk.tileEntities.values()) {
|
||||
if (tileEntity instanceof TileEntityMobSpawner) {
|
||||
NBTTagCompound nbtTagCompound = new NBTTagCompound();
|
||||
tileEntity.save(nbtTagCompound);
|
||||
nbtTagCompound.setShort("RequiredPlayerRange", (short) 16);
|
||||
nbtTagCompound.setShort("RequiredPlayerRange", requiredPlayerRange);
|
||||
if (TILE_ENTITY_LOAD.isValid()) {
|
||||
TILE_ENTITY_LOAD.invoke(tileEntity, nbtTagCompound);
|
||||
} else {
|
||||
tileEntity.a(nbtTagCompound);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,6 +40,7 @@ import java.util.UUID;
|
||||
|
||||
public final class ChunkLoaderNPC extends EntityPlayer implements com.bgsoftware.wildloaders.api.npc.ChunkLoaderNPC {
|
||||
|
||||
|
||||
private final AxisAlignedBB boundingBox;
|
||||
private final AdvancementDataPlayer advancements;
|
||||
|
||||
@ -57,9 +58,16 @@ public final class ChunkLoaderNPC extends EntityPlayer implements com.bgsoftware
|
||||
this.advancements = new DummyPlayerAdvancements(server, this);
|
||||
|
||||
this.playerInteractManager.setGameMode(EnumGamemode.CREATIVE);
|
||||
clientViewDistance = 1;
|
||||
|
||||
fallDistance = 0.0F;
|
||||
fauxSleeping = true;
|
||||
clientViewDistance = 0;
|
||||
|
||||
try {
|
||||
// Paper
|
||||
affectsSpawning = true;
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
|
||||
spawnIn(world);
|
||||
setLocation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
|
||||
|
@ -4,6 +4,7 @@ import com.bgsoftware.wildloaders.api.loaders.ChunkLoader;
|
||||
import com.bgsoftware.wildloaders.loaders.ITileEntityChunkLoader;
|
||||
import com.bgsoftware.wildloaders.nms.NMSAdapter;
|
||||
import com.bgsoftware.wildloaders.nms.v1_16_R3.loader.TileEntityChunkLoader;
|
||||
import com.bgsoftware.wildloaders.scheduler.Scheduler;
|
||||
import net.minecraft.server.v1_16_R3.Block;
|
||||
import net.minecraft.server.v1_16_R3.BlockPosition;
|
||||
import net.minecraft.server.v1_16_R3.Chunk;
|
||||
@ -14,6 +15,7 @@ import net.minecraft.server.v1_16_R3.NBTTagCompound;
|
||||
import net.minecraft.server.v1_16_R3.NBTTagList;
|
||||
import net.minecraft.server.v1_16_R3.NBTTagLong;
|
||||
import net.minecraft.server.v1_16_R3.NBTTagString;
|
||||
import net.minecraft.server.v1_16_R3.TileEntity;
|
||||
import net.minecraft.server.v1_16_R3.TileEntityMobSpawner;
|
||||
import net.minecraft.server.v1_16_R3.World;
|
||||
import net.minecraft.server.v1_16_R3.WorldServer;
|
||||
@ -114,12 +116,10 @@ public final class NMSAdapterImpl implements NMSAdapter {
|
||||
TileEntityChunkLoader tileEntityChunkLoader = new TileEntityChunkLoader(chunkLoader, world, blockPosition);
|
||||
world.tileEntityListTick.add(tileEntityChunkLoader);
|
||||
|
||||
for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunks()) {
|
||||
Chunk chunk = ((CraftChunk) bukkitChunk).getHandle();
|
||||
chunk.tileEntities.values().stream().filter(tileEntity -> tileEntity instanceof TileEntityMobSpawner)
|
||||
.forEach(tileEntity -> ((TileEntityMobSpawner) tileEntity).getSpawner().requiredPlayerRange = -1);
|
||||
|
||||
world.setForceLoaded(chunk.getPos().x, chunk.getPos().z, true);
|
||||
if (Scheduler.isRegionScheduler()) {
|
||||
Scheduler.runTask(() -> setChunksForcedForLoader(chunkLoader, world, true));
|
||||
} else {
|
||||
setChunksForcedForLoader(chunkLoader, world, true);
|
||||
}
|
||||
|
||||
return tileEntityChunkLoader;
|
||||
@ -143,12 +143,25 @@ public final class NMSAdapterImpl implements NMSAdapter {
|
||||
if (spawnParticle)
|
||||
world.a(null, 2001, blockPosition, Block.getCombinedId(world.getType(blockPosition)));
|
||||
|
||||
for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunks()) {
|
||||
Chunk chunk = ((CraftChunk) bukkitChunk).getHandle();
|
||||
chunk.tileEntities.values().stream().filter(tileEntity -> tileEntity instanceof TileEntityMobSpawner)
|
||||
.forEach(tileEntity -> ((TileEntityMobSpawner) tileEntity).getSpawner().requiredPlayerRange = 16);
|
||||
if (Scheduler.isRegionScheduler()) {
|
||||
Scheduler.runTask(() -> setChunksForcedForLoader(chunkLoader, world, false));
|
||||
} else {
|
||||
setChunksForcedForLoader(chunkLoader, world, false);
|
||||
}
|
||||
}
|
||||
|
||||
world.setForceLoaded(chunk.getPos().x, chunk.getPos().z, false);
|
||||
private static void setChunksForcedForLoader(ChunkLoader chunkLoader, WorldServer worldServer, boolean forced) {
|
||||
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)
|
||||
((TileEntityMobSpawner) tileEntity).getSpawner().requiredPlayerRange = requiredPlayerRange;
|
||||
}
|
||||
|
||||
ChunkCoordIntPair chunkCoord = chunk.getPos();
|
||||
worldServer.setForceLoaded(chunkCoord.x, chunkCoord.z, forced);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
plugins {
|
||||
id("io.papermc.paperweight.userdev") version "1.6.0"
|
||||
id("io.papermc.paperweight.userdev") version "1.7.1"
|
||||
}
|
||||
|
||||
java {
|
||||
|
@ -5,6 +5,7 @@ import com.bgsoftware.wildloaders.loaders.ITileEntityChunkLoader;
|
||||
import com.bgsoftware.wildloaders.nms.NMSAdapter;
|
||||
import com.bgsoftware.wildloaders.nms.v1_17.loader.ChunkLoaderBlockEntity;
|
||||
import com.bgsoftware.wildloaders.nms.v1_17.npc.ChunkLoaderNPCWrapper;
|
||||
import com.bgsoftware.wildloaders.scheduler.Scheduler;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
@ -105,16 +106,10 @@ public final class NMSAdapterImpl implements NMSAdapter {
|
||||
ChunkLoaderBlockEntity ChunkLoaderBlockEntity = new ChunkLoaderBlockEntity(chunkLoader, serverLevel, blockPos);
|
||||
serverLevel.addBlockEntityTicker(ChunkLoaderBlockEntity.getTicker());
|
||||
|
||||
for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunks()) {
|
||||
LevelChunk levelChunk = ((CraftChunk) bukkitChunk).getHandle();
|
||||
levelChunk.getBlockEntities().values().stream()
|
||||
.filter(blockEntity -> blockEntity instanceof SpawnerBlockEntity)
|
||||
.forEach(blockEntity -> {
|
||||
((SpawnerBlockEntity) blockEntity).getSpawner().requiredPlayerRange = -1;
|
||||
});
|
||||
|
||||
ChunkPos chunkPos = levelChunk.getPos();
|
||||
serverLevel.setChunkForced(chunkPos.x, chunkPos.z, true);
|
||||
if (Scheduler.isRegionScheduler()) {
|
||||
Scheduler.runTask(() -> setChunksForcedForLoader(chunkLoader, serverLevel, true));
|
||||
} else {
|
||||
setChunksForcedForLoader(chunkLoader, serverLevel, true);
|
||||
}
|
||||
|
||||
return ChunkLoaderBlockEntity;
|
||||
@ -142,16 +137,25 @@ public final class NMSAdapterImpl implements NMSAdapter {
|
||||
if (spawnParticle)
|
||||
serverLevel.levelEvent(null, 2001, blockPos, Block.getId(serverLevel.getBlockState(blockPos)));
|
||||
|
||||
for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunks()) {
|
||||
if (Scheduler.isRegionScheduler()) {
|
||||
Scheduler.runTask(() -> setChunksForcedForLoader(chunkLoader, serverLevel, false));
|
||||
} else {
|
||||
setChunksForcedForLoader(chunkLoader, serverLevel, false);
|
||||
}
|
||||
}
|
||||
|
||||
private static void setChunksForcedForLoader(ChunkLoader chunkLoader, ServerLevel serverLevel, boolean forced) {
|
||||
int requiredPlayerRange = forced ? -1 : 16;
|
||||
for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunksCollection()) {
|
||||
LevelChunk levelChunk = ((CraftChunk) bukkitChunk).getHandle();
|
||||
levelChunk.getBlockEntities().values().stream()
|
||||
.filter(blockEntity -> blockEntity instanceof SpawnerBlockEntity)
|
||||
.forEach(blockEntity -> {
|
||||
((SpawnerBlockEntity) blockEntity).getSpawner().requiredPlayerRange = 16;
|
||||
});
|
||||
|
||||
for (BlockEntity blockEntity : levelChunk.getBlockEntities().values()) {
|
||||
if (blockEntity instanceof SpawnerBlockEntity spawnerBlockEntity)
|
||||
spawnerBlockEntity.getSpawner().requiredPlayerRange = requiredPlayerRange;
|
||||
}
|
||||
|
||||
ChunkPos chunkPos = levelChunk.getPos();
|
||||
serverLevel.setChunkForced(chunkPos.x, chunkPos.z, false);
|
||||
serverLevel.setChunkForced(chunkPos.x, chunkPos.z, forced);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,9 +56,16 @@ public final class ChunkLoaderPlayer extends ServerPlayer {
|
||||
this.advancements = new DummyPlayerAdvancements(minecraftServer, this);
|
||||
|
||||
SET_GAMEMODE.invoke(this.gameMode, GameType.CREATIVE, null);
|
||||
clientViewDistance = 1;
|
||||
|
||||
fallDistance = 0.0F;
|
||||
fauxSleeping = true;
|
||||
clientViewDistance = 0;
|
||||
|
||||
try {
|
||||
// Paper
|
||||
affectsSpawning = true;
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
|
||||
spawnIn(this.serverLevel);
|
||||
moveTo(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
|
||||
|
@ -1,5 +1,5 @@
|
||||
plugins {
|
||||
id("io.papermc.paperweight.userdev") version "1.6.0"
|
||||
id("io.papermc.paperweight.userdev") version "1.7.1"
|
||||
}
|
||||
|
||||
java {
|
||||
|
@ -58,9 +58,16 @@ public final class ChunkLoaderNPCImpl extends ServerPlayer implements ChunkLoade
|
||||
this.advancements = new DummyPlayerAdvancements(minecraftServer, this);
|
||||
|
||||
SET_GAMEMODE.invoke(this.gameMode, GameType.CREATIVE, null);
|
||||
clientViewDistance = 1;
|
||||
|
||||
fallDistance = 0.0F;
|
||||
fauxSleeping = true;
|
||||
clientViewDistance = 0;
|
||||
|
||||
try {
|
||||
// Paper
|
||||
affectsSpawning = true;
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
|
||||
spawnIn(this.serverLevel);
|
||||
moveTo(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
|
||||
|
@ -4,6 +4,7 @@ import com.bgsoftware.wildloaders.api.loaders.ChunkLoader;
|
||||
import com.bgsoftware.wildloaders.loaders.ITileEntityChunkLoader;
|
||||
import com.bgsoftware.wildloaders.nms.NMSAdapter;
|
||||
import com.bgsoftware.wildloaders.nms.v1_18.loader.ChunkLoaderBlockEntity;
|
||||
import com.bgsoftware.wildloaders.scheduler.Scheduler;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
@ -104,16 +105,10 @@ public final class NMSAdapterImpl implements NMSAdapter {
|
||||
ChunkLoaderBlockEntity ChunkLoaderBlockEntity = new ChunkLoaderBlockEntity(chunkLoader, serverLevel, blockPos);
|
||||
serverLevel.addBlockEntityTicker(ChunkLoaderBlockEntity.getTicker());
|
||||
|
||||
for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunks()) {
|
||||
LevelChunk levelChunk = ((CraftChunk) bukkitChunk).getHandle();
|
||||
levelChunk.getBlockEntities().values().stream()
|
||||
.filter(blockEntity -> blockEntity instanceof SpawnerBlockEntity)
|
||||
.forEach(blockEntity -> {
|
||||
((SpawnerBlockEntity) blockEntity).getSpawner().requiredPlayerRange = -1;
|
||||
});
|
||||
|
||||
ChunkPos chunkPos = levelChunk.getPos();
|
||||
serverLevel.setChunkForced(chunkPos.x, chunkPos.z, true);
|
||||
if (Scheduler.isRegionScheduler()) {
|
||||
Scheduler.runTask(() -> setChunksForcedForLoader(chunkLoader, serverLevel, true));
|
||||
} else {
|
||||
setChunksForcedForLoader(chunkLoader, serverLevel, true);
|
||||
}
|
||||
|
||||
return ChunkLoaderBlockEntity;
|
||||
@ -141,16 +136,25 @@ public final class NMSAdapterImpl implements NMSAdapter {
|
||||
if (spawnParticle)
|
||||
serverLevel.levelEvent(null, 2001, blockPos, Block.getId(serverLevel.getBlockState(blockPos)));
|
||||
|
||||
for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunks()) {
|
||||
if (Scheduler.isRegionScheduler()) {
|
||||
Scheduler.runTask(() -> setChunksForcedForLoader(chunkLoader, serverLevel, false));
|
||||
} else {
|
||||
setChunksForcedForLoader(chunkLoader, serverLevel, false);
|
||||
}
|
||||
}
|
||||
|
||||
private static void setChunksForcedForLoader(ChunkLoader chunkLoader, ServerLevel serverLevel, boolean forced) {
|
||||
int requiredPlayerRange = forced ? -1 : 16;
|
||||
for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunksCollection()) {
|
||||
LevelChunk levelChunk = ((CraftChunk) bukkitChunk).getHandle();
|
||||
levelChunk.getBlockEntities().values().stream()
|
||||
.filter(blockEntity -> blockEntity instanceof SpawnerBlockEntity)
|
||||
.forEach(blockEntity -> {
|
||||
((SpawnerBlockEntity) blockEntity).getSpawner().requiredPlayerRange = 16;
|
||||
});
|
||||
|
||||
for (BlockEntity blockEntity : levelChunk.getBlockEntities().values()) {
|
||||
if (blockEntity instanceof SpawnerBlockEntity spawnerBlockEntity)
|
||||
spawnerBlockEntity.getSpawner().requiredPlayerRange = requiredPlayerRange;
|
||||
}
|
||||
|
||||
ChunkPos chunkPos = levelChunk.getPos();
|
||||
serverLevel.setChunkForced(chunkPos.x, chunkPos.z, false);
|
||||
serverLevel.setChunkForced(chunkPos.x, chunkPos.z, forced);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
plugins {
|
||||
id("io.papermc.paperweight.userdev") version "1.6.0"
|
||||
id("io.papermc.paperweight.userdev") version "1.7.1"
|
||||
}
|
||||
|
||||
java {
|
||||
|
@ -60,9 +60,16 @@ public final class ChunkLoaderNPCImpl extends ServerPlayer implements ChunkLoade
|
||||
this.advancements = new DummyPlayerAdvancements(minecraftServer, this);
|
||||
|
||||
SET_GAMEMODE.invoke(this.gameMode, GameType.CREATIVE, null);
|
||||
clientViewDistance = 1;
|
||||
|
||||
fallDistance = 0.0F;
|
||||
fauxSleeping = true;
|
||||
clientViewDistance = 0;
|
||||
|
||||
try {
|
||||
// Paper
|
||||
affectsSpawning = true;
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
|
||||
spawnIn(this.serverLevel);
|
||||
moveTo(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.bgsoftware.wildloaders.nms.v1_19;
|
||||
|
||||
import com.bgsoftware.wildloaders.api.holograms.Hologram;
|
||||
import com.bgsoftware.wildloaders.scheduler.Scheduler;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
@ -15,6 +16,7 @@ import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.v1_19_R3.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_19_R3.entity.CraftArmorStand;
|
||||
import org.bukkit.craftbukkit.v1_19_R3.entity.CraftEntity;
|
||||
@ -48,8 +50,15 @@ public final class EntityHologram extends ArmorStand implements Hologram {
|
||||
|
||||
@Override
|
||||
public void removeHologram() {
|
||||
if (Scheduler.isRegionScheduler() || !Bukkit.isPrimaryThread()) {
|
||||
World world = level.getWorld();
|
||||
int chunkX = getBlockX() >> 4;
|
||||
int chunkZ = getBlockZ() >> 4;
|
||||
Scheduler.runTask(world, chunkX, chunkZ, () -> super.remove(RemovalReason.DISCARDED));
|
||||
} else {
|
||||
super.remove(RemovalReason.DISCARDED);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.bukkit.entity.Entity getEntity() {
|
||||
|
@ -4,6 +4,7 @@ import com.bgsoftware.wildloaders.api.loaders.ChunkLoader;
|
||||
import com.bgsoftware.wildloaders.loaders.ITileEntityChunkLoader;
|
||||
import com.bgsoftware.wildloaders.nms.NMSAdapter;
|
||||
import com.bgsoftware.wildloaders.nms.v1_19.loader.ChunkLoaderBlockEntity;
|
||||
import com.bgsoftware.wildloaders.scheduler.Scheduler;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
@ -103,16 +104,10 @@ public final class NMSAdapterImpl implements NMSAdapter {
|
||||
ChunkLoaderBlockEntity ChunkLoaderBlockEntity = new ChunkLoaderBlockEntity(chunkLoader, serverLevel, blockPos);
|
||||
serverLevel.addBlockEntityTicker(ChunkLoaderBlockEntity.getTicker());
|
||||
|
||||
for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunks()) {
|
||||
LevelChunk levelChunk = serverLevel.getChunk(bukkitChunk.getX(), bukkitChunk.getZ());
|
||||
levelChunk.getBlockEntities().values().stream()
|
||||
.filter(blockEntity -> blockEntity instanceof SpawnerBlockEntity)
|
||||
.forEach(blockEntity -> {
|
||||
((SpawnerBlockEntity) blockEntity).getSpawner().requiredPlayerRange = -1;
|
||||
});
|
||||
|
||||
ChunkPos chunkPos = levelChunk.getPos();
|
||||
serverLevel.setChunkForced(chunkPos.x, chunkPos.z, true);
|
||||
if (Scheduler.isRegionScheduler()) {
|
||||
Scheduler.runTask(() -> setChunksForcedForLoader(chunkLoader, serverLevel, true));
|
||||
} else {
|
||||
setChunksForcedForLoader(chunkLoader, serverLevel, true);
|
||||
}
|
||||
|
||||
return ChunkLoaderBlockEntity;
|
||||
@ -140,16 +135,25 @@ public final class NMSAdapterImpl implements NMSAdapter {
|
||||
if (spawnParticle)
|
||||
serverLevel.levelEvent(null, 2001, blockPos, Block.getId(serverLevel.getBlockState(blockPos)));
|
||||
|
||||
for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunks()) {
|
||||
if (Scheduler.isRegionScheduler()) {
|
||||
Scheduler.runTask(() -> setChunksForcedForLoader(chunkLoader, serverLevel, false));
|
||||
} else {
|
||||
setChunksForcedForLoader(chunkLoader, serverLevel, false);
|
||||
}
|
||||
}
|
||||
|
||||
private static void setChunksForcedForLoader(ChunkLoader chunkLoader, ServerLevel serverLevel, boolean forced) {
|
||||
int requiredPlayerRange = forced ? -1 : 16;
|
||||
for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunksCollection()) {
|
||||
LevelChunk levelChunk = serverLevel.getChunk(bukkitChunk.getX(), bukkitChunk.getZ());
|
||||
levelChunk.getBlockEntities().values().stream()
|
||||
.filter(blockEntity -> blockEntity instanceof SpawnerBlockEntity)
|
||||
.forEach(blockEntity -> {
|
||||
((SpawnerBlockEntity) blockEntity).getSpawner().requiredPlayerRange = 16;
|
||||
});
|
||||
|
||||
for (BlockEntity blockEntity : levelChunk.getBlockEntities().values()) {
|
||||
if (blockEntity instanceof SpawnerBlockEntity spawnerBlockEntity)
|
||||
spawnerBlockEntity.getSpawner().requiredPlayerRange = requiredPlayerRange;
|
||||
}
|
||||
|
||||
ChunkPos chunkPos = levelChunk.getPos();
|
||||
serverLevel.setChunkForced(chunkPos.x, chunkPos.z, false);
|
||||
serverLevel.setChunkForced(chunkPos.x, chunkPos.z, forced);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.bgsoftware.wildloaders.nms.v1_19.loader;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.entity.TickingBlockEntity;
|
||||
|
||||
@ -27,4 +28,8 @@ public record ChunkLoaderBlockEntityTicker(
|
||||
return BlockEntityType.getKey(chunkLoaderBlockEntity.getType()) + "";
|
||||
}
|
||||
|
||||
public BlockEntity getTileEntity() {
|
||||
return chunkLoaderBlockEntity;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,237 +0,0 @@
|
||||
package com.bgsoftware.wildloaders.nms.v1_20_1;
|
||||
|
||||
import com.bgsoftware.common.reflection.ReflectMethod;
|
||||
import com.bgsoftware.wildloaders.api.npc.ChunkLoaderNPC;
|
||||
import com.bgsoftware.wildloaders.handlers.NPCHandler;
|
||||
import com.bgsoftware.wildloaders.npc.DummyChannel;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import net.minecraft.advancements.Advancement;
|
||||
import net.minecraft.advancements.AdvancementProgress;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.Connection;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.protocol.PacketFlow;
|
||||
import net.minecraft.network.protocol.game.ServerboundChatPacket;
|
||||
import net.minecraft.network.protocol.game.ServerboundContainerClickPacket;
|
||||
import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket;
|
||||
import net.minecraft.network.protocol.game.ServerboundPlayerActionPacket;
|
||||
import net.minecraft.network.protocol.game.ServerboundSetCarriedItemPacket;
|
||||
import net.minecraft.network.protocol.game.ServerboundSignUpdatePacket;
|
||||
import net.minecraft.network.protocol.game.ServerboundUseItemPacket;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.PlayerAdvancements;
|
||||
import net.minecraft.server.ServerAdvancementManager;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.level.ServerPlayerGameMode;
|
||||
import net.minecraft.server.network.ServerGamePacketListenerImpl;
|
||||
import net.minecraft.world.level.GameType;
|
||||
import net.minecraft.world.level.storage.LevelResource;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.v1_20_R1.CraftWorld;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import java.util.UUID;
|
||||
|
||||
public final class ChunkLoaderNPCImpl extends ServerPlayer implements ChunkLoaderNPC {
|
||||
|
||||
private static final ReflectMethod<Void> SET_GAMEMODE = new ReflectMethod<>(ServerPlayerGameMode.class,
|
||||
1, GameType.class, GameType.class);
|
||||
|
||||
private final ServerLevel serverLevel;
|
||||
private final AABB boundingBox;
|
||||
private final PlayerAdvancements advancements;
|
||||
|
||||
private boolean dieCall = false;
|
||||
|
||||
public ChunkLoaderNPCImpl(MinecraftServer minecraftServer, Location location, UUID uuid) {
|
||||
super(minecraftServer, ((CraftWorld) location.getWorld()).getHandle(),
|
||||
new GameProfile(uuid, NPCHandler.getName(location.getWorld().getName())));
|
||||
|
||||
this.serverLevel = serverLevel();
|
||||
this.boundingBox = new AABB(new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()));
|
||||
|
||||
this.connection = new DummyServerGamePacketListenerImpl(minecraftServer, this);
|
||||
|
||||
this.advancements = new DummyPlayerAdvancements(minecraftServer, this);
|
||||
|
||||
SET_GAMEMODE.invoke(this.gameMode, GameType.CREATIVE, null);
|
||||
clientViewDistance = 1;
|
||||
|
||||
fauxSleeping = true;
|
||||
|
||||
spawnIn(this.serverLevel);
|
||||
moveTo(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
|
||||
|
||||
this.serverLevel.addNewPlayer(this);
|
||||
|
||||
super.setBoundingBox(this.boundingBox);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getUniqueId() {
|
||||
return super.getUUID();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void die() {
|
||||
discard();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AABB getBoundingBoxForCulling() {
|
||||
return this.boundingBox;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(RemovalReason removalReason) {
|
||||
if (!dieCall) {
|
||||
dieCall = true;
|
||||
this.serverLevel.removePlayerImmediately(this, RemovalReason.UNLOADED_WITH_PLAYER);
|
||||
dieCall = false;
|
||||
} else {
|
||||
super.remove(removalReason);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getLocation() {
|
||||
return getBukkitEntity().getLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player getPlayer() {
|
||||
return getBukkitEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlayerAdvancements getAdvancements() {
|
||||
return this.advancements;
|
||||
}
|
||||
|
||||
public static class DummyConnection extends Connection {
|
||||
|
||||
DummyConnection() {
|
||||
super(PacketFlow.SERVERBOUND);
|
||||
this.channel = new DummyChannel();
|
||||
this.address = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class DummyServerGamePacketListenerImpl extends ServerGamePacketListenerImpl {
|
||||
|
||||
DummyServerGamePacketListenerImpl(MinecraftServer minecraftServer, ServerPlayer serverPlayer) {
|
||||
super(minecraftServer, new DummyConnection(), serverPlayer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleContainerClick(ServerboundContainerClickPacket containerClickPacket) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMovePlayer(ServerboundMovePlayerPacket movePlayerPacket) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleSignUpdate(ServerboundSignUpdatePacket signUpdatePacket) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handlePlayerAction(ServerboundPlayerActionPacket playerActionPacket) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleUseItem(ServerboundUseItemPacket useItemPacket) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleSetCarriedItem(ServerboundSetCarriedItemPacket setCarriedItemPacket) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleChat(ServerboundChatPacket chatPacket) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnect(String s) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
public void send(Packet<?> packet) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class DummyPlayerAdvancements extends PlayerAdvancements {
|
||||
|
||||
DummyPlayerAdvancements(MinecraftServer server, ServerPlayer serverPlayer) {
|
||||
super(server.getFixerUpper(), server.getPlayerList(), server.getAdvancements(),
|
||||
getAdvancementsFile(server, serverPlayer), serverPlayer);
|
||||
}
|
||||
|
||||
private static Path getAdvancementsFile(MinecraftServer server, ServerPlayer serverPlayer) {
|
||||
File advancementsDir = server.getWorldPath(LevelResource.PLAYER_ADVANCEMENTS_DIR).toFile();
|
||||
return new File(advancementsDir, serverPlayer.getUUID() + ".json").toPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlayer(ServerPlayer owner) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopListening() {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload(ServerAdvancementManager advancementLoader) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean award(Advancement advancement, String criterionName) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean revoke(Advancement advancement, String criterionName) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flushDirty(ServerPlayer player) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelectedTab(@Nullable Advancement advancement) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public AdvancementProgress getOrStartProgress(Advancement advancement) {
|
||||
return new AdvancementProgress();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,170 +0,0 @@
|
||||
package com.bgsoftware.wildloaders.nms.v1_20_1;
|
||||
|
||||
import com.bgsoftware.wildloaders.api.loaders.ChunkLoader;
|
||||
import com.bgsoftware.wildloaders.loaders.ITileEntityChunkLoader;
|
||||
import com.bgsoftware.wildloaders.nms.NMSAdapter;
|
||||
import com.bgsoftware.wildloaders.nms.v1_20_1.loader.ChunkLoaderBlockEntity;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.SpawnerBlockEntity;
|
||||
import net.minecraft.world.level.chunk.LevelChunk;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_20_R1.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public final class NMSAdapterImpl implements NMSAdapter {
|
||||
|
||||
@Override
|
||||
public String getTag(org.bukkit.inventory.ItemStack bukkitItem, String key, String def) {
|
||||
ItemStack itemStack = CraftItemStack.asNMSCopy(bukkitItem);
|
||||
CompoundTag compoundTag = itemStack.getTag();
|
||||
return compoundTag == null || !compoundTag.contains(key, 8) ? def : compoundTag.getString(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.bukkit.inventory.ItemStack setTag(org.bukkit.inventory.ItemStack bukkitItem, String key, String value) {
|
||||
ItemStack itemStack = CraftItemStack.asNMSCopy(bukkitItem);
|
||||
CompoundTag compoundTag = itemStack.getOrCreateTag();
|
||||
|
||||
compoundTag.putString(key, value);
|
||||
|
||||
return CraftItemStack.asBukkitCopy(itemStack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTag(org.bukkit.inventory.ItemStack bukkitItem, String key, long def) {
|
||||
ItemStack itemStack = CraftItemStack.asNMSCopy(bukkitItem);
|
||||
CompoundTag compoundTag = itemStack.getTag();
|
||||
return compoundTag == null || !compoundTag.contains(key, 4) ? def : compoundTag.getLong(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.bukkit.inventory.ItemStack setTag(org.bukkit.inventory.ItemStack bukkitItem, String key, long value) {
|
||||
ItemStack itemStack = CraftItemStack.asNMSCopy(bukkitItem);
|
||||
CompoundTag compoundTag = itemStack.getOrCreateTag();
|
||||
|
||||
compoundTag.putLong(key, value);
|
||||
|
||||
return CraftItemStack.asBukkitCopy(itemStack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.bukkit.inventory.ItemStack getPlayerSkull(org.bukkit.inventory.ItemStack bukkitItem, String texture) {
|
||||
ItemStack itemStack = CraftItemStack.asNMSCopy(bukkitItem);
|
||||
CompoundTag compoundTag = itemStack.getOrCreateTag();
|
||||
|
||||
CompoundTag skullOwner = compoundTag.contains("SkullOwner") ?
|
||||
compoundTag.getCompound("SkullOwner") : new CompoundTag();
|
||||
|
||||
CompoundTag properties = new CompoundTag();
|
||||
ListTag textures = new ListTag();
|
||||
CompoundTag signature = new CompoundTag();
|
||||
|
||||
signature.putString("Value", texture);
|
||||
textures.add(signature);
|
||||
|
||||
properties.put("textures", textures);
|
||||
|
||||
skullOwner.put("Properties", properties);
|
||||
skullOwner.putString("Id", UUID.randomUUID().toString());
|
||||
|
||||
compoundTag.put("SkullOwner", skullOwner);
|
||||
|
||||
return CraftItemStack.asBukkitCopy(itemStack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public com.bgsoftware.wildloaders.api.npc.ChunkLoaderNPC createNPC(Location location, UUID uuid) {
|
||||
return new ChunkLoaderNPCImpl(((CraftServer) Bukkit.getServer()).getServer(), location, uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITileEntityChunkLoader createLoader(ChunkLoader chunkLoader) {
|
||||
Location loaderLoc = chunkLoader.getLocation();
|
||||
World bukkitWorld = loaderLoc.getWorld();
|
||||
|
||||
if (bukkitWorld == null)
|
||||
throw new IllegalArgumentException("Cannot create loader in null world.");
|
||||
|
||||
ServerLevel serverLevel = ((CraftWorld) bukkitWorld).getHandle();
|
||||
BlockPos blockPos = new BlockPos(loaderLoc.getBlockX(), loaderLoc.getBlockY(), loaderLoc.getBlockZ());
|
||||
|
||||
ChunkLoaderBlockEntity ChunkLoaderBlockEntity = new ChunkLoaderBlockEntity(chunkLoader, serverLevel, blockPos);
|
||||
serverLevel.addBlockEntityTicker(ChunkLoaderBlockEntity.getTicker());
|
||||
|
||||
for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunks()) {
|
||||
LevelChunk levelChunk = serverLevel.getChunk(bukkitChunk.getX(), bukkitChunk.getZ());
|
||||
levelChunk.getBlockEntities().values().stream()
|
||||
.filter(blockEntity -> blockEntity instanceof SpawnerBlockEntity)
|
||||
.forEach(blockEntity -> {
|
||||
((SpawnerBlockEntity) blockEntity).getSpawner().requiredPlayerRange = -1;
|
||||
});
|
||||
|
||||
ChunkPos chunkPos = levelChunk.getPos();
|
||||
serverLevel.setChunkForced(chunkPos.x, chunkPos.z, true);
|
||||
}
|
||||
|
||||
return ChunkLoaderBlockEntity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeLoader(ChunkLoader chunkLoader, boolean spawnParticle) {
|
||||
Location loaderLoc = chunkLoader.getLocation();
|
||||
World bukkitWorld = loaderLoc.getWorld();
|
||||
|
||||
if (bukkitWorld == null)
|
||||
throw new IllegalArgumentException("Cannot remove loader in null world.");
|
||||
|
||||
ServerLevel serverLevel = ((CraftWorld) bukkitWorld).getHandle();
|
||||
BlockPos blockPos = new BlockPos(loaderLoc.getBlockX(), loaderLoc.getBlockY(), loaderLoc.getBlockZ());
|
||||
|
||||
long chunkPosLong = ChunkPos.asLong(blockPos.getX() >> 4, blockPos.getZ() >> 4);
|
||||
ChunkLoaderBlockEntity chunkLoaderBlockEntity = ChunkLoaderBlockEntity.chunkLoaderBlockEntityMap.remove(chunkPosLong);
|
||||
|
||||
if (chunkLoaderBlockEntity != null) {
|
||||
chunkLoaderBlockEntity.holograms.forEach(EntityHologram::removeHologram);
|
||||
chunkLoaderBlockEntity.removed = true;
|
||||
}
|
||||
|
||||
if (spawnParticle)
|
||||
serverLevel.levelEvent(null, 2001, blockPos, Block.getId(serverLevel.getBlockState(blockPos)));
|
||||
|
||||
for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunks()) {
|
||||
LevelChunk levelChunk = serverLevel.getChunk(bukkitChunk.getX(), bukkitChunk.getZ());
|
||||
levelChunk.getBlockEntities().values().stream()
|
||||
.filter(blockEntity -> blockEntity instanceof SpawnerBlockEntity)
|
||||
.forEach(blockEntity -> {
|
||||
((SpawnerBlockEntity) blockEntity).getSpawner().requiredPlayerRange = 16;
|
||||
});
|
||||
|
||||
ChunkPos chunkPos = levelChunk.getPos();
|
||||
serverLevel.setChunkForced(chunkPos.x, chunkPos.z, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSpawner(Location location, boolean reset) {
|
||||
World bukkitWorld = location.getWorld();
|
||||
|
||||
if (bukkitWorld == null)
|
||||
throw new IllegalArgumentException("Cannot remove loader in null world.");
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
plugins {
|
||||
id("io.papermc.paperweight.userdev") version "1.6.0"
|
||||
}
|
||||
|
||||
java {
|
||||
toolchain {
|
||||
languageVersion.set(JavaLanguageVersion.of(17))
|
||||
}
|
||||
}
|
||||
|
||||
group 'NMS:v1_20_2'
|
||||
|
||||
dependencies {
|
||||
paperweightDevelopmentBundle("io.papermc.paper:dev-bundle:1.20.2-R0.1-SNAPSHOT")
|
||||
compileOnly project(":API")
|
||||
compileOnly rootProject
|
||||
}
|
||||
|
||||
shadowJar {
|
||||
archiveFileName = "${project.name}-exclude.jar"
|
||||
}
|
||||
|
||||
assemble {
|
||||
dependsOn(reobfJar)
|
||||
}
|
||||
|
||||
tasks {
|
||||
reobfJar {
|
||||
File outputFile = new File(rootProject.archiveFolder, "reobf/${project.name}.jar")
|
||||
outputJar.set(layout.buildDirectory.file(outputFile.getPath()))
|
||||
}
|
||||
}
|
||||
|
||||
if (project.hasProperty('nms.compile_v1_20') && !Boolean.valueOf(project.findProperty("nms.compile_v1_20").toString())) {
|
||||
project.tasks.all { task -> task.enabled = false }
|
||||
}
|
@ -1,165 +0,0 @@
|
||||
package com.bgsoftware.wildloaders.nms.v1_20_2;
|
||||
|
||||
import com.bgsoftware.wildloaders.api.holograms.Hologram;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.damagesource.DamageSource;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
import net.minecraft.world.entity.decoration.ArmorStand;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.craftbukkit.v1_20_R2.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_20_R2.entity.CraftArmorStand;
|
||||
import org.bukkit.craftbukkit.v1_20_R2.entity.CraftEntity;
|
||||
import org.bukkit.craftbukkit.v1_20_R2.util.CraftChatMessage;
|
||||
|
||||
public final class EntityHologram extends ArmorStand implements Hologram {
|
||||
|
||||
private static final AABB EMPTY_BOUND = new AABB(0D, 0D, 0D, 0D, 0D, 0D);
|
||||
|
||||
private CraftEntity bukkitEntity;
|
||||
|
||||
public EntityHologram(ServerLevel serverLevel, double x, double y, double z) {
|
||||
super(serverLevel, x, y, z);
|
||||
|
||||
setInvisible(true);
|
||||
setSmall(true);
|
||||
setShowArms(false);
|
||||
setNoGravity(true);
|
||||
setNoBasePlate(true);
|
||||
setMarker(true);
|
||||
|
||||
super.collides = false;
|
||||
super.setCustomNameVisible(true); // Custom name visible
|
||||
super.setBoundingBox(EMPTY_BOUND);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHologramName(String name) {
|
||||
super.setCustomName(CraftChatMessage.fromStringOrNull(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeHologram() {
|
||||
super.remove(RemovalReason.DISCARDED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.bukkit.entity.Entity getEntity() {
|
||||
return getBukkitEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
// Disable normal ticking for this entity.
|
||||
|
||||
// Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity.
|
||||
if (this.onGround) {
|
||||
this.onGround = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inactiveTick() {
|
||||
// Disable normal ticking for this entity.
|
||||
|
||||
// Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity.
|
||||
if (this.onGround) {
|
||||
this.onGround = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addAdditionalSaveData(CompoundTag compoundTag) {
|
||||
// Do not save NBT.
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean saveAsPassenger(CompoundTag compoundTag) {
|
||||
// Do not save NBT.
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag saveWithoutId(CompoundTag compoundTag) {
|
||||
// Do not save NBT.
|
||||
return compoundTag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readAdditionalSaveData(CompoundTag compoundTag) {
|
||||
// Do not load NBT.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(CompoundTag compoundTag) {
|
||||
// Do not load NBT.
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInvulnerableTo(DamageSource source) {
|
||||
/*
|
||||
* The field Entity.invulnerable is private.
|
||||
* It's only used while saving NBTTags, but since the entity would be killed
|
||||
* on chunk unload, we prefer to override isInvulnerable().
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean repositionEntityAfterLoad() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCustomName(Component component) {
|
||||
// Locks the custom name.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCustomNameVisible(boolean visible) {
|
||||
// Locks the custom name.
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionResult interactAt(Player player, Vec3 hitPos, InteractionHand hand) {
|
||||
// Prevent stand being equipped
|
||||
return InteractionResult.PASS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItemSlot(EquipmentSlot equipmentSlot, ItemStack itemStack, boolean silent) {
|
||||
// Prevent stand being equipped
|
||||
}
|
||||
|
||||
@Override
|
||||
public AABB getBoundingBoxForCulling() {
|
||||
return EMPTY_BOUND;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playSound(SoundEvent soundEvent, float volume, float pitch) {
|
||||
// Remove sounds.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(RemovalReason removalReason) {
|
||||
// Prevent being killed.
|
||||
}
|
||||
|
||||
@Override
|
||||
public CraftEntity getBukkitEntity() {
|
||||
if (bukkitEntity == null) {
|
||||
bukkitEntity = new CraftArmorStand((CraftServer) Bukkit.getServer(), this);
|
||||
}
|
||||
return bukkitEntity;
|
||||
}
|
||||
|
||||
}
|
@ -1,149 +0,0 @@
|
||||
package com.bgsoftware.wildloaders.nms.v1_20_2.loader;
|
||||
|
||||
import com.bgsoftware.wildloaders.api.holograms.Hologram;
|
||||
import com.bgsoftware.wildloaders.api.loaders.ChunkLoader;
|
||||
import com.bgsoftware.wildloaders.loaders.ITileEntityChunkLoader;
|
||||
import com.bgsoftware.wildloaders.loaders.WChunkLoader;
|
||||
import com.bgsoftware.wildloaders.nms.v1_20_2.EntityHologram;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public final class ChunkLoaderBlockEntity extends BlockEntity implements ITileEntityChunkLoader {
|
||||
|
||||
public static final Map<Long, ChunkLoaderBlockEntity> chunkLoaderBlockEntityMap = new HashMap<>();
|
||||
|
||||
public final List<EntityHologram> holograms = new ArrayList<>();
|
||||
private final WChunkLoader chunkLoader;
|
||||
private final Block loaderBlock;
|
||||
private final ChunkLoaderBlockEntityTicker ticker;
|
||||
private final ServerLevel serverLevel;
|
||||
private final BlockPos blockPos;
|
||||
private final String cachedPlacerName;
|
||||
|
||||
private short currentTick = 20;
|
||||
private short daysAmount, hoursAmount, minutesAmount, secondsAmount;
|
||||
public boolean removed = false;
|
||||
|
||||
public ChunkLoaderBlockEntity(ChunkLoader chunkLoader, ServerLevel serverLevel, BlockPos blockPos) {
|
||||
super(BlockEntityType.COMMAND_BLOCK, blockPos, serverLevel.getBlockState(blockPos));
|
||||
|
||||
this.chunkLoader = (WChunkLoader) chunkLoader;
|
||||
this.ticker = new ChunkLoaderBlockEntityTicker(this);
|
||||
this.blockPos = blockPos;
|
||||
this.serverLevel = serverLevel;
|
||||
|
||||
setLevel(serverLevel);
|
||||
|
||||
loaderBlock = serverLevel.getBlockState(blockPos).getBlock();
|
||||
|
||||
this.cachedPlacerName = Optional.ofNullable(this.chunkLoader.getWhoPlaced().getName()).orElse("");
|
||||
|
||||
if (!this.chunkLoader.isInfinite()) {
|
||||
long timeLeft = chunkLoader.getTimeLeft();
|
||||
|
||||
daysAmount = (short) (timeLeft / 86400);
|
||||
timeLeft = timeLeft % 86400;
|
||||
|
||||
hoursAmount = (short) (timeLeft / 3600);
|
||||
timeLeft = timeLeft % 3600;
|
||||
|
||||
minutesAmount = (short) (timeLeft / 60);
|
||||
timeLeft = timeLeft % 60;
|
||||
|
||||
secondsAmount = (short) timeLeft;
|
||||
}
|
||||
|
||||
long chunkPosLong = ChunkPos.asLong(blockPos.getX() >> 4, blockPos.getZ() >> 4);
|
||||
chunkLoaderBlockEntityMap.put(chunkPosLong, this);
|
||||
|
||||
List<String> hologramLines = this.chunkLoader.getHologramLines();
|
||||
|
||||
double currentY = blockPos.getY() + 1;
|
||||
for (int i = hologramLines.size(); i > 0; i--) {
|
||||
EntityHologram hologram = new EntityHologram(serverLevel, blockPos.getX() + 0.5, currentY, blockPos.getZ() + 0.5);
|
||||
updateName(hologram, hologramLines.get(i - 1));
|
||||
serverLevel.addFreshEntity(hologram);
|
||||
currentY += 0.23;
|
||||
holograms.add(hologram);
|
||||
}
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
if (removed || ++currentTick <= 20)
|
||||
return;
|
||||
|
||||
currentTick = 0;
|
||||
|
||||
if (chunkLoader.isNotActive() || this.serverLevel.getBlockState(this.blockPos).getBlock() != loaderBlock) {
|
||||
chunkLoader.remove();
|
||||
return;
|
||||
}
|
||||
|
||||
if (chunkLoader.isInfinite())
|
||||
return;
|
||||
|
||||
List<String> hologramLines = chunkLoader.getHologramLines();
|
||||
|
||||
int hologramsAmount = holograms.size();
|
||||
for (int i = hologramsAmount; i > 0; i--) {
|
||||
EntityHologram hologram = holograms.get(hologramsAmount - i);
|
||||
updateName(hologram, hologramLines.get(i - 1));
|
||||
}
|
||||
|
||||
chunkLoader.tick();
|
||||
|
||||
if (!removed) {
|
||||
secondsAmount--;
|
||||
if (secondsAmount < 0) {
|
||||
secondsAmount = 59;
|
||||
minutesAmount--;
|
||||
if (minutesAmount < 0) {
|
||||
minutesAmount = 59;
|
||||
hoursAmount--;
|
||||
if (hoursAmount < 0) {
|
||||
hoursAmount = 23;
|
||||
daysAmount--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Hologram> getHolograms() {
|
||||
return Collections.unmodifiableList(holograms);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRemoved() {
|
||||
return removed || super.isRemoved();
|
||||
}
|
||||
|
||||
public ChunkLoaderBlockEntityTicker getTicker() {
|
||||
return ticker;
|
||||
}
|
||||
|
||||
private void updateName(EntityHologram hologram, String line) {
|
||||
hologram.setHologramName(line
|
||||
.replace("{0}", this.cachedPlacerName)
|
||||
.replace("{1}", daysAmount + "")
|
||||
.replace("{2}", hoursAmount + "")
|
||||
.replace("{3}", minutesAmount + "")
|
||||
.replace("{4}", secondsAmount + "")
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,30 +0,0 @@
|
||||
package com.bgsoftware.wildloaders.nms.v1_20_2.loader;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.entity.TickingBlockEntity;
|
||||
|
||||
public record ChunkLoaderBlockEntityTicker(
|
||||
ChunkLoaderBlockEntity chunkLoaderBlockEntity) implements TickingBlockEntity {
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
chunkLoaderBlockEntity.tick();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRemoved() {
|
||||
return chunkLoaderBlockEntity.isRemoved();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos getPos() {
|
||||
return chunkLoaderBlockEntity.getBlockPos();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return BlockEntityType.getKey(chunkLoaderBlockEntity.getType()) + "";
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
plugins {
|
||||
id("io.papermc.paperweight.userdev") version "1.6.0"
|
||||
id("io.papermc.paperweight.userdev") version "1.7.1"
|
||||
}
|
||||
|
||||
java {
|
||||
|
@ -64,16 +64,19 @@ public final class ChunkLoaderNPCImpl extends ServerPlayer implements ChunkLoade
|
||||
this.advancements = new DummyPlayerAdvancements(minecraftServer, this);
|
||||
|
||||
SET_GAMEMODE.invoke(this.gameMode, GameType.CREATIVE, null);
|
||||
|
||||
fallDistance = 0.0F;
|
||||
fauxSleeping = true;
|
||||
|
||||
try {
|
||||
setLoadViewDistance(2);
|
||||
setTickViewDistance(2);
|
||||
setSendViewDistance(2);
|
||||
affectsSpawning = true;
|
||||
} catch (Throwable ignored) {
|
||||
// Doesn't exist on Spigot
|
||||
}
|
||||
|
||||
fauxSleeping = true;
|
||||
|
||||
spawnIn(this.serverLevel);
|
||||
moveTo(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.bgsoftware.wildloaders.nms.v1_20_3;
|
||||
|
||||
import com.bgsoftware.wildloaders.api.holograms.Hologram;
|
||||
import com.bgsoftware.wildloaders.scheduler.Scheduler;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
@ -15,6 +16,7 @@ import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.v1_20_R3.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_20_R3.entity.CraftArmorStand;
|
||||
import org.bukkit.craftbukkit.v1_20_R3.entity.CraftEntity;
|
||||
@ -48,8 +50,15 @@ public final class EntityHologram extends ArmorStand implements Hologram {
|
||||
|
||||
@Override
|
||||
public void removeHologram() {
|
||||
if (Scheduler.isRegionScheduler() || !Bukkit.isPrimaryThread()) {
|
||||
World world = level().getWorld();
|
||||
int chunkX = getBlockX() >> 4;
|
||||
int chunkZ = getBlockZ() >> 4;
|
||||
Scheduler.runTask(world, chunkX, chunkZ, () -> super.remove(RemovalReason.DISCARDED));
|
||||
} else {
|
||||
super.remove(RemovalReason.DISCARDED);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.bukkit.entity.Entity getEntity() {
|
||||
|
@ -4,6 +4,7 @@ import com.bgsoftware.wildloaders.api.loaders.ChunkLoader;
|
||||
import com.bgsoftware.wildloaders.loaders.ITileEntityChunkLoader;
|
||||
import com.bgsoftware.wildloaders.nms.NMSAdapter;
|
||||
import com.bgsoftware.wildloaders.nms.v1_20_3.loader.ChunkLoaderBlockEntity;
|
||||
import com.bgsoftware.wildloaders.scheduler.Scheduler;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
@ -103,16 +104,10 @@ public final class NMSAdapterImpl implements NMSAdapter {
|
||||
ChunkLoaderBlockEntity ChunkLoaderBlockEntity = new ChunkLoaderBlockEntity(chunkLoader, serverLevel, blockPos);
|
||||
serverLevel.addBlockEntityTicker(ChunkLoaderBlockEntity.getTicker());
|
||||
|
||||
for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunks()) {
|
||||
LevelChunk levelChunk = serverLevel.getChunk(bukkitChunk.getX(), bukkitChunk.getZ());
|
||||
levelChunk.getBlockEntities().values().stream()
|
||||
.filter(blockEntity -> blockEntity instanceof SpawnerBlockEntity)
|
||||
.forEach(blockEntity -> {
|
||||
((SpawnerBlockEntity) blockEntity).getSpawner().requiredPlayerRange = -1;
|
||||
});
|
||||
|
||||
ChunkPos chunkPos = levelChunk.getPos();
|
||||
serverLevel.setChunkForced(chunkPos.x, chunkPos.z, true);
|
||||
if (Scheduler.isRegionScheduler()) {
|
||||
Scheduler.runTask(() -> setChunksForcedForLoader(chunkLoader, serverLevel, true));
|
||||
} else {
|
||||
setChunksForcedForLoader(chunkLoader, serverLevel, true);
|
||||
}
|
||||
|
||||
return ChunkLoaderBlockEntity;
|
||||
@ -140,16 +135,25 @@ public final class NMSAdapterImpl implements NMSAdapter {
|
||||
if (spawnParticle)
|
||||
serverLevel.levelEvent(null, 2001, blockPos, Block.getId(serverLevel.getBlockState(blockPos)));
|
||||
|
||||
for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunks()) {
|
||||
if (Scheduler.isRegionScheduler()) {
|
||||
Scheduler.runTask(() -> setChunksForcedForLoader(chunkLoader, serverLevel, false));
|
||||
} else {
|
||||
setChunksForcedForLoader(chunkLoader, serverLevel, false);
|
||||
}
|
||||
}
|
||||
|
||||
private static void setChunksForcedForLoader(ChunkLoader chunkLoader, ServerLevel serverLevel, boolean forced) {
|
||||
int requiredPlayerRange = forced ? -1 : 16;
|
||||
for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunksCollection()) {
|
||||
LevelChunk levelChunk = serverLevel.getChunk(bukkitChunk.getX(), bukkitChunk.getZ());
|
||||
levelChunk.getBlockEntities().values().stream()
|
||||
.filter(blockEntity -> blockEntity instanceof SpawnerBlockEntity)
|
||||
.forEach(blockEntity -> {
|
||||
((SpawnerBlockEntity) blockEntity).getSpawner().requiredPlayerRange = 16;
|
||||
});
|
||||
|
||||
for (BlockEntity blockEntity : levelChunk.getBlockEntities().values()) {
|
||||
if (blockEntity instanceof SpawnerBlockEntity spawnerBlockEntity)
|
||||
spawnerBlockEntity.getSpawner().requiredPlayerRange = requiredPlayerRange;
|
||||
}
|
||||
|
||||
ChunkPos chunkPos = levelChunk.getPos();
|
||||
serverLevel.setChunkForced(chunkPos.x, chunkPos.z, false);
|
||||
serverLevel.setChunkForced(chunkPos.x, chunkPos.z, forced);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.bgsoftware.wildloaders.nms.v1_20_3.loader;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.entity.TickingBlockEntity;
|
||||
|
||||
@ -27,4 +28,8 @@ public record ChunkLoaderBlockEntityTicker(
|
||||
return BlockEntityType.getKey(chunkLoaderBlockEntity.getType()) + "";
|
||||
}
|
||||
|
||||
public BlockEntity getTileEntity() {
|
||||
return chunkLoaderBlockEntity;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
plugins {
|
||||
id("io.papermc.paperweight.userdev") version "1.6.0"
|
||||
id("io.papermc.paperweight.userdev") version "1.7.1"
|
||||
}
|
||||
|
||||
java {
|
||||
|
@ -64,16 +64,19 @@ public final class ChunkLoaderNPCImpl extends ServerPlayer implements ChunkLoade
|
||||
this.advancements = new DummyPlayerAdvancements(minecraftServer, this);
|
||||
|
||||
SET_GAMEMODE.invoke(this.gameMode, GameType.CREATIVE, null);
|
||||
|
||||
fallDistance = 0.0F;
|
||||
fauxSleeping = true;
|
||||
|
||||
try {
|
||||
setLoadViewDistance(2);
|
||||
setTickViewDistance(2);
|
||||
setSendViewDistance(2);
|
||||
affectsSpawning = true;
|
||||
} catch (Throwable ignored) {
|
||||
// Doesn't exist on Spigot
|
||||
}
|
||||
|
||||
fauxSleeping = true;
|
||||
|
||||
spawnIn(this.serverLevel);
|
||||
moveTo(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.bgsoftware.wildloaders.nms.v1_20_4;
|
||||
|
||||
import com.bgsoftware.wildloaders.api.holograms.Hologram;
|
||||
import com.bgsoftware.wildloaders.scheduler.Scheduler;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
@ -15,6 +16,7 @@ import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.craftbukkit.entity.CraftArmorStand;
|
||||
import org.bukkit.craftbukkit.entity.CraftEntity;
|
||||
@ -48,8 +50,15 @@ public final class EntityHologram extends ArmorStand implements Hologram {
|
||||
|
||||
@Override
|
||||
public void removeHologram() {
|
||||
if (Scheduler.isRegionScheduler() || !Bukkit.isPrimaryThread()) {
|
||||
World world = level().getWorld();
|
||||
int chunkX = getBlockX() >> 4;
|
||||
int chunkZ = getBlockZ() >> 4;
|
||||
Scheduler.runTask(world, chunkX, chunkZ, () -> super.remove(RemovalReason.DISCARDED));
|
||||
} else {
|
||||
super.remove(RemovalReason.DISCARDED);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.bukkit.entity.Entity getEntity() {
|
||||
|
@ -4,6 +4,7 @@ import com.bgsoftware.wildloaders.api.loaders.ChunkLoader;
|
||||
import com.bgsoftware.wildloaders.loaders.ITileEntityChunkLoader;
|
||||
import com.bgsoftware.wildloaders.nms.NMSAdapter;
|
||||
import com.bgsoftware.wildloaders.nms.v1_20_4.loader.ChunkLoaderBlockEntity;
|
||||
import com.bgsoftware.wildloaders.scheduler.Scheduler;
|
||||
import com.mojang.authlib.properties.Property;
|
||||
import com.mojang.authlib.properties.PropertyMap;
|
||||
import net.minecraft.core.BlockPos;
|
||||
@ -109,16 +110,10 @@ public final class NMSAdapterImpl implements NMSAdapter {
|
||||
ChunkLoaderBlockEntity ChunkLoaderBlockEntity = new ChunkLoaderBlockEntity(chunkLoader, serverLevel, blockPos);
|
||||
serverLevel.addBlockEntityTicker(ChunkLoaderBlockEntity.getTicker());
|
||||
|
||||
for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunks()) {
|
||||
LevelChunk levelChunk = serverLevel.getChunk(bukkitChunk.getX(), bukkitChunk.getZ());
|
||||
levelChunk.getBlockEntities().values().stream()
|
||||
.filter(blockEntity -> blockEntity instanceof SpawnerBlockEntity)
|
||||
.forEach(blockEntity -> {
|
||||
((SpawnerBlockEntity) blockEntity).getSpawner().requiredPlayerRange = -1;
|
||||
});
|
||||
|
||||
ChunkPos chunkPos = levelChunk.getPos();
|
||||
serverLevel.setChunkForced(chunkPos.x, chunkPos.z, true);
|
||||
if (Scheduler.isRegionScheduler()) {
|
||||
Scheduler.runTask(() -> setChunksForcedForLoader(chunkLoader, serverLevel, true));
|
||||
} else {
|
||||
setChunksForcedForLoader(chunkLoader, serverLevel, true);
|
||||
}
|
||||
|
||||
return ChunkLoaderBlockEntity;
|
||||
@ -146,16 +141,25 @@ public final class NMSAdapterImpl implements NMSAdapter {
|
||||
if (spawnParticle)
|
||||
serverLevel.levelEvent(null, 2001, blockPos, Block.getId(serverLevel.getBlockState(blockPos)));
|
||||
|
||||
for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunks()) {
|
||||
if (Scheduler.isRegionScheduler()) {
|
||||
Scheduler.runTask(() -> setChunksForcedForLoader(chunkLoader, serverLevel, false));
|
||||
} else {
|
||||
setChunksForcedForLoader(chunkLoader, serverLevel, false);
|
||||
}
|
||||
}
|
||||
|
||||
private static void setChunksForcedForLoader(ChunkLoader chunkLoader, ServerLevel serverLevel, boolean forced) {
|
||||
int requiredPlayerRange = forced ? -1 : 16;
|
||||
for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunksCollection()) {
|
||||
LevelChunk levelChunk = serverLevel.getChunk(bukkitChunk.getX(), bukkitChunk.getZ());
|
||||
levelChunk.getBlockEntities().values().stream()
|
||||
.filter(blockEntity -> blockEntity instanceof SpawnerBlockEntity)
|
||||
.forEach(blockEntity -> {
|
||||
((SpawnerBlockEntity) blockEntity).getSpawner().requiredPlayerRange = 16;
|
||||
});
|
||||
|
||||
for (BlockEntity blockEntity : levelChunk.getBlockEntities().values()) {
|
||||
if (blockEntity instanceof SpawnerBlockEntity spawnerBlockEntity)
|
||||
spawnerBlockEntity.getSpawner().requiredPlayerRange = requiredPlayerRange;
|
||||
}
|
||||
|
||||
ChunkPos chunkPos = levelChunk.getPos();
|
||||
serverLevel.setChunkForced(chunkPos.x, chunkPos.z, false);
|
||||
serverLevel.setChunkForced(chunkPos.x, chunkPos.z, forced);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.bgsoftware.wildloaders.nms.v1_20_4.loader;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.entity.TickingBlockEntity;
|
||||
|
||||
@ -27,4 +28,8 @@ public record ChunkLoaderBlockEntityTicker(
|
||||
return BlockEntityType.getKey(chunkLoaderBlockEntity.getType()) + "";
|
||||
}
|
||||
|
||||
public BlockEntity getTileEntity() {
|
||||
return chunkLoaderBlockEntity;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,17 +1,17 @@
|
||||
plugins {
|
||||
id("io.papermc.paperweight.userdev") version "1.6.0"
|
||||
id("io.papermc.paperweight.userdev") version "1.7.1"
|
||||
}
|
||||
|
||||
java {
|
||||
toolchain {
|
||||
languageVersion.set(JavaLanguageVersion.of(17))
|
||||
languageVersion.set(JavaLanguageVersion.of(21))
|
||||
}
|
||||
}
|
||||
|
||||
group 'NMS:v1_20_1'
|
||||
group 'NMS:v1_21'
|
||||
|
||||
dependencies {
|
||||
paperweightDevelopmentBundle("io.papermc.paper:dev-bundle:1.20.1-R0.1-SNAPSHOT")
|
||||
paperweightDevelopmentBundle("io.papermc.paper:dev-bundle:1.21-R0.1-SNAPSHOT")
|
||||
compileOnly project(":API")
|
||||
compileOnly rootProject
|
||||
}
|
||||
@ -31,6 +31,6 @@ tasks {
|
||||
}
|
||||
}
|
||||
|
||||
if (project.hasProperty('nms.compile_v1_20') && !Boolean.valueOf(project.findProperty("nms.compile_v1_20").toString())) {
|
||||
if (project.hasProperty('nms.compile_v1_21') && !Boolean.valueOf(project.findProperty("nms.compile_v1_21").toString())) {
|
||||
project.tasks.all { task -> task.enabled = false }
|
||||
}
|
@ -1,14 +1,16 @@
|
||||
package com.bgsoftware.wildloaders.nms.v1_20_2;
|
||||
package com.bgsoftware.wildloaders.nms.v1_21;
|
||||
|
||||
import com.bgsoftware.common.reflection.ReflectMethod;
|
||||
import com.bgsoftware.wildloaders.api.npc.ChunkLoaderNPC;
|
||||
import com.bgsoftware.wildloaders.handlers.NPCHandler;
|
||||
import com.bgsoftware.wildloaders.npc.DummyChannel;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.minecraft.advancements.AdvancementHolder;
|
||||
import net.minecraft.advancements.AdvancementProgress;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.Connection;
|
||||
import net.minecraft.network.DisconnectionDetails;
|
||||
import net.minecraft.network.PacketListener;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.protocol.PacketFlow;
|
||||
@ -32,8 +34,10 @@ import net.minecraft.world.level.GameType;
|
||||
import net.minecraft.world.level.storage.LevelResource;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.v1_20_R2.CraftWorld;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.PlayerKickEvent;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
@ -64,16 +68,20 @@ public final class ChunkLoaderNPCImpl extends ServerPlayer implements ChunkLoade
|
||||
this.advancements = new DummyPlayerAdvancements(minecraftServer, this);
|
||||
|
||||
SET_GAMEMODE.invoke(this.gameMode, GameType.CREATIVE, null);
|
||||
|
||||
fallDistance = 0.0F;
|
||||
fauxSleeping = true;
|
||||
|
||||
try {
|
||||
setLoadViewDistance(2);
|
||||
setTickViewDistance(2);
|
||||
setSendViewDistance(2);
|
||||
CraftPlayer craftPlayer = getBukkitEntity();
|
||||
craftPlayer.setSendViewDistance(2);
|
||||
craftPlayer.setViewDistance(2);
|
||||
craftPlayer.setSimulationDistance(2);
|
||||
affectsSpawning = true;
|
||||
} catch (Throwable ignored) {
|
||||
// Doesn't exist on Spigot
|
||||
}
|
||||
|
||||
fauxSleeping = true;
|
||||
|
||||
spawnIn(this.serverLevel);
|
||||
moveTo(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
|
||||
|
||||
@ -132,7 +140,7 @@ public final class ChunkLoaderNPCImpl extends ServerPlayer implements ChunkLoade
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setListener(PacketListener packetListener) {
|
||||
public void setListenerForServerboundHandshake(PacketListener packetListener) {
|
||||
// Do nothing.
|
||||
}
|
||||
}
|
||||
@ -140,7 +148,8 @@ public final class ChunkLoaderNPCImpl extends ServerPlayer implements ChunkLoade
|
||||
public class DummyServerGamePacketListenerImpl extends ServerGamePacketListenerImpl {
|
||||
|
||||
DummyServerGamePacketListenerImpl(MinecraftServer minecraftServer, ServerPlayer serverPlayer) {
|
||||
super(minecraftServer, new DummyConnection(), serverPlayer, CommonListenerCookie.createInitial(ChunkLoaderNPCImpl.this.getGameProfile()));
|
||||
super(minecraftServer, new DummyConnection(), serverPlayer,
|
||||
CommonListenerCookie.createInitial(ChunkLoaderNPCImpl.this.getGameProfile(), false));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -179,7 +188,7 @@ public final class ChunkLoaderNPCImpl extends ServerPlayer implements ChunkLoade
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnect(String s) {
|
||||
public void disconnect(DisconnectionDetails disconnectionInfo, PlayerKickEvent.Cause cause) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.bgsoftware.wildloaders.nms.v1_20_1;
|
||||
package com.bgsoftware.wildloaders.nms.v1_21;
|
||||
|
||||
import com.bgsoftware.wildloaders.api.holograms.Hologram;
|
||||
import com.bgsoftware.wildloaders.scheduler.Scheduler;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
@ -15,10 +16,11 @@ import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftArmorStand;
|
||||
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
|
||||
import org.bukkit.craftbukkit.v1_20_R1.util.CraftChatMessage;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.craftbukkit.entity.CraftArmorStand;
|
||||
import org.bukkit.craftbukkit.entity.CraftEntity;
|
||||
import org.bukkit.craftbukkit.util.CraftChatMessage;
|
||||
|
||||
public final class EntityHologram extends ArmorStand implements Hologram {
|
||||
|
||||
@ -48,8 +50,15 @@ public final class EntityHologram extends ArmorStand implements Hologram {
|
||||
|
||||
@Override
|
||||
public void removeHologram() {
|
||||
if (Scheduler.isRegionScheduler() || !Bukkit.isPrimaryThread()) {
|
||||
World world = level().getWorld();
|
||||
int chunkX = getBlockX() >> 4;
|
||||
int chunkZ = getBlockZ() >> 4;
|
||||
Scheduler.runTask(world, chunkX, chunkZ, () -> super.remove(RemovalReason.DISCARDED));
|
||||
} else {
|
||||
super.remove(RemovalReason.DISCARDED);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.bukkit.entity.Entity getEntity() {
|
@ -1,14 +1,19 @@
|
||||
package com.bgsoftware.wildloaders.nms.v1_20_2;
|
||||
package com.bgsoftware.wildloaders.nms.v1_21;
|
||||
|
||||
import com.bgsoftware.wildloaders.api.loaders.ChunkLoader;
|
||||
import com.bgsoftware.wildloaders.loaders.ITileEntityChunkLoader;
|
||||
import com.bgsoftware.wildloaders.nms.NMSAdapter;
|
||||
import com.bgsoftware.wildloaders.nms.v1_20_2.loader.ChunkLoaderBlockEntity;
|
||||
import com.bgsoftware.wildloaders.nms.v1_21.loader.ChunkLoaderBlockEntity;
|
||||
import com.bgsoftware.wildloaders.scheduler.Scheduler;
|
||||
import com.mojang.authlib.properties.Property;
|
||||
import com.mojang.authlib.properties.PropertyMap;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.component.CustomData;
|
||||
import net.minecraft.world.item.component.ResolvableProfile;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
@ -17,10 +22,11 @@ import net.minecraft.world.level.chunk.LevelChunk;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.v1_20_R2.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_20_R2.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_20_R2.inventory.CraftItemStack;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
public final class NMSAdapterImpl implements NMSAdapter {
|
||||
@ -28,16 +34,22 @@ public final class NMSAdapterImpl implements NMSAdapter {
|
||||
@Override
|
||||
public String getTag(org.bukkit.inventory.ItemStack bukkitItem, String key, String def) {
|
||||
ItemStack itemStack = CraftItemStack.asNMSCopy(bukkitItem);
|
||||
CompoundTag compoundTag = itemStack.getTag();
|
||||
return compoundTag == null || !compoundTag.contains(key, 8) ? def : compoundTag.getString(key);
|
||||
CustomData customData = itemStack.get(DataComponents.CUSTOM_DATA);
|
||||
if (customData != null) {
|
||||
CompoundTag compoundTag = customData.getUnsafe();
|
||||
if (compoundTag.contains(key, 8))
|
||||
return compoundTag.getString(key);
|
||||
}
|
||||
return def;
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.bukkit.inventory.ItemStack setTag(org.bukkit.inventory.ItemStack bukkitItem, String key, String value) {
|
||||
ItemStack itemStack = CraftItemStack.asNMSCopy(bukkitItem);
|
||||
CompoundTag compoundTag = itemStack.getOrCreateTag();
|
||||
|
||||
compoundTag.putString(key, value);
|
||||
CustomData customData = itemStack.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY);
|
||||
customData = customData.update(compoundTag -> compoundTag.putString(key, value));
|
||||
itemStack.set(DataComponents.CUSTOM_DATA, customData);
|
||||
|
||||
return CraftItemStack.asBukkitCopy(itemStack);
|
||||
}
|
||||
@ -45,16 +57,22 @@ public final class NMSAdapterImpl implements NMSAdapter {
|
||||
@Override
|
||||
public long getTag(org.bukkit.inventory.ItemStack bukkitItem, String key, long def) {
|
||||
ItemStack itemStack = CraftItemStack.asNMSCopy(bukkitItem);
|
||||
CompoundTag compoundTag = itemStack.getTag();
|
||||
return compoundTag == null || !compoundTag.contains(key, 4) ? def : compoundTag.getLong(key);
|
||||
CustomData customData = itemStack.get(DataComponents.CUSTOM_DATA);
|
||||
if (customData != null) {
|
||||
CompoundTag compoundTag = customData.getUnsafe();
|
||||
if (compoundTag.contains(key, 4))
|
||||
return compoundTag.getLong(key);
|
||||
}
|
||||
return def;
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.bukkit.inventory.ItemStack setTag(org.bukkit.inventory.ItemStack bukkitItem, String key, long value) {
|
||||
ItemStack itemStack = CraftItemStack.asNMSCopy(bukkitItem);
|
||||
CompoundTag compoundTag = itemStack.getOrCreateTag();
|
||||
|
||||
compoundTag.putLong(key, value);
|
||||
CustomData customData = itemStack.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY);
|
||||
customData = customData.update(compoundTag -> compoundTag.putLong(key, value));
|
||||
itemStack.set(DataComponents.CUSTOM_DATA, customData);
|
||||
|
||||
return CraftItemStack.asBukkitCopy(itemStack);
|
||||
}
|
||||
@ -62,24 +80,13 @@ public final class NMSAdapterImpl implements NMSAdapter {
|
||||
@Override
|
||||
public org.bukkit.inventory.ItemStack getPlayerSkull(org.bukkit.inventory.ItemStack bukkitItem, String texture) {
|
||||
ItemStack itemStack = CraftItemStack.asNMSCopy(bukkitItem);
|
||||
CompoundTag compoundTag = itemStack.getOrCreateTag();
|
||||
|
||||
CompoundTag skullOwner = compoundTag.contains("SkullOwner") ?
|
||||
compoundTag.getCompound("SkullOwner") : new CompoundTag();
|
||||
PropertyMap propertyMap = new PropertyMap();
|
||||
propertyMap.put("textures", new Property("textures", texture));
|
||||
|
||||
CompoundTag properties = new CompoundTag();
|
||||
ListTag textures = new ListTag();
|
||||
CompoundTag signature = new CompoundTag();
|
||||
ResolvableProfile resolvableProfile = new ResolvableProfile(Optional.empty(), Optional.empty(), propertyMap);
|
||||
|
||||
signature.putString("Value", texture);
|
||||
textures.add(signature);
|
||||
|
||||
properties.put("textures", textures);
|
||||
|
||||
skullOwner.put("Properties", properties);
|
||||
skullOwner.putString("Id", UUID.randomUUID().toString());
|
||||
|
||||
compoundTag.put("SkullOwner", skullOwner);
|
||||
itemStack.set(DataComponents.PROFILE, resolvableProfile);
|
||||
|
||||
return CraftItemStack.asBukkitCopy(itemStack);
|
||||
}
|
||||
@ -103,16 +110,10 @@ public final class NMSAdapterImpl implements NMSAdapter {
|
||||
ChunkLoaderBlockEntity ChunkLoaderBlockEntity = new ChunkLoaderBlockEntity(chunkLoader, serverLevel, blockPos);
|
||||
serverLevel.addBlockEntityTicker(ChunkLoaderBlockEntity.getTicker());
|
||||
|
||||
for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunks()) {
|
||||
LevelChunk levelChunk = serverLevel.getChunk(bukkitChunk.getX(), bukkitChunk.getZ());
|
||||
levelChunk.getBlockEntities().values().stream()
|
||||
.filter(blockEntity -> blockEntity instanceof SpawnerBlockEntity)
|
||||
.forEach(blockEntity -> {
|
||||
((SpawnerBlockEntity) blockEntity).getSpawner().requiredPlayerRange = -1;
|
||||
});
|
||||
|
||||
ChunkPos chunkPos = levelChunk.getPos();
|
||||
serverLevel.setChunkForced(chunkPos.x, chunkPos.z, true);
|
||||
if (Scheduler.isRegionScheduler()) {
|
||||
Scheduler.runTask(() -> setChunksForcedForLoader(chunkLoader, serverLevel, true));
|
||||
} else {
|
||||
setChunksForcedForLoader(chunkLoader, serverLevel, true);
|
||||
}
|
||||
|
||||
return ChunkLoaderBlockEntity;
|
||||
@ -140,16 +141,25 @@ public final class NMSAdapterImpl implements NMSAdapter {
|
||||
if (spawnParticle)
|
||||
serverLevel.levelEvent(null, 2001, blockPos, Block.getId(serverLevel.getBlockState(blockPos)));
|
||||
|
||||
for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunks()) {
|
||||
if (Scheduler.isRegionScheduler()) {
|
||||
Scheduler.runTask(() -> setChunksForcedForLoader(chunkLoader, serverLevel, false));
|
||||
} else {
|
||||
setChunksForcedForLoader(chunkLoader, serverLevel, false);
|
||||
}
|
||||
}
|
||||
|
||||
private static void setChunksForcedForLoader(ChunkLoader chunkLoader, ServerLevel serverLevel, boolean forced) {
|
||||
int requiredPlayerRange = forced ? -1 : 16;
|
||||
for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunksCollection()) {
|
||||
LevelChunk levelChunk = serverLevel.getChunk(bukkitChunk.getX(), bukkitChunk.getZ());
|
||||
levelChunk.getBlockEntities().values().stream()
|
||||
.filter(blockEntity -> blockEntity instanceof SpawnerBlockEntity)
|
||||
.forEach(blockEntity -> {
|
||||
((SpawnerBlockEntity) blockEntity).getSpawner().requiredPlayerRange = 16;
|
||||
});
|
||||
|
||||
for (BlockEntity blockEntity : levelChunk.getBlockEntities().values()) {
|
||||
if (blockEntity instanceof SpawnerBlockEntity spawnerBlockEntity)
|
||||
spawnerBlockEntity.getSpawner().requiredPlayerRange = requiredPlayerRange;
|
||||
}
|
||||
|
||||
ChunkPos chunkPos = levelChunk.getPos();
|
||||
serverLevel.setChunkForced(chunkPos.x, chunkPos.z, false);
|
||||
serverLevel.setChunkForced(chunkPos.x, chunkPos.z, forced);
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
package com.bgsoftware.wildloaders.nms.v1_20_1.loader;
|
||||
package com.bgsoftware.wildloaders.nms.v1_21.loader;
|
||||
|
||||
import com.bgsoftware.wildloaders.api.holograms.Hologram;
|
||||
import com.bgsoftware.wildloaders.api.loaders.ChunkLoader;
|
||||
import com.bgsoftware.wildloaders.loaders.ITileEntityChunkLoader;
|
||||
import com.bgsoftware.wildloaders.loaders.WChunkLoader;
|
||||
import com.bgsoftware.wildloaders.nms.v1_20_1.EntityHologram;
|
||||
import com.bgsoftware.wildloaders.nms.v1_21.EntityHologram;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.level.ChunkPos;
|
@ -1,6 +1,7 @@
|
||||
package com.bgsoftware.wildloaders.nms.v1_20_1.loader;
|
||||
package com.bgsoftware.wildloaders.nms.v1_21.loader;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.entity.TickingBlockEntity;
|
||||
|
||||
@ -27,4 +28,8 @@ public record ChunkLoaderBlockEntityTicker(
|
||||
return BlockEntityType.getKey(chunkLoaderBlockEntity.getType()) + "";
|
||||
}
|
||||
|
||||
public BlockEntity getTileEntity() {
|
||||
return chunkLoaderBlockEntity;
|
||||
}
|
||||
|
||||
}
|
@ -41,8 +41,8 @@ public final class ChunkLoaderNPC extends EntityPlayer implements com.bgsoftware
|
||||
playerConnection = new DummyPlayerConnection(server, this);
|
||||
|
||||
playerInteractManager.setGameMode(EnumGamemode.CREATIVE);
|
||||
fallDistance = 0.0F;
|
||||
|
||||
fallDistance = 0.0F;
|
||||
fauxSleeping = true;
|
||||
|
||||
spawnIn(world);
|
||||
|
@ -4,6 +4,7 @@ import com.bgsoftware.wildloaders.api.loaders.ChunkLoader;
|
||||
import com.bgsoftware.wildloaders.loaders.ITileEntityChunkLoader;
|
||||
import com.bgsoftware.wildloaders.nms.NMSAdapter;
|
||||
import com.bgsoftware.wildloaders.nms.v1_7_R4.loader.TileEntityChunkLoader;
|
||||
import com.bgsoftware.wildloaders.scheduler.Scheduler;
|
||||
import net.minecraft.server.v1_7_R4.Block;
|
||||
import net.minecraft.server.v1_7_R4.Chunk;
|
||||
import net.minecraft.server.v1_7_R4.ItemStack;
|
||||
@ -20,6 +21,7 @@ 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 java.util.Collection;
|
||||
import java.util.UUID;
|
||||
|
||||
public final class NMSAdapterImpl implements NMSAdapter {
|
||||
@ -112,15 +114,10 @@ public final class NMSAdapterImpl implements NMSAdapter {
|
||||
//noinspection unchecked
|
||||
world.tileEntityList.add(tileEntityChunkLoader);
|
||||
|
||||
for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunks()) {
|
||||
Chunk chunk = ((CraftChunk) bukkitChunk).getHandle();
|
||||
//noinspection unchecked
|
||||
chunk.tileEntities.values().stream().filter(tileEntity -> tileEntity instanceof TileEntityMobSpawner).forEach(tileEntity -> {
|
||||
NBTTagCompound nbtTagCompound = new NBTTagCompound();
|
||||
((TileEntity) tileEntity).b(nbtTagCompound);
|
||||
nbtTagCompound.setShort("RequiredPlayerRange", (short) -1);
|
||||
((TileEntity) tileEntity).a(nbtTagCompound);
|
||||
});
|
||||
if (Scheduler.isRegionScheduler()) {
|
||||
Scheduler.runTask(() -> setSpawnersRangeForLoader(chunkLoader, true));
|
||||
} else {
|
||||
setSpawnersRangeForLoader(chunkLoader, true);
|
||||
}
|
||||
|
||||
return tileEntityChunkLoader;
|
||||
@ -142,15 +139,26 @@ public final class NMSAdapterImpl implements NMSAdapter {
|
||||
if (spawnParticle)
|
||||
world.a(null, 2001, x, y, z, Block.getId(world.getType(x, y, z)) + (world.getData(x, y, z) << 12));
|
||||
|
||||
for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunks()) {
|
||||
if (Scheduler.isRegionScheduler()) {
|
||||
Scheduler.runTask(() -> setSpawnersRangeForLoader(chunkLoader, false));
|
||||
} else {
|
||||
setSpawnersRangeForLoader(chunkLoader, false);
|
||||
}
|
||||
}
|
||||
|
||||
private static void setSpawnersRangeForLoader(ChunkLoader chunkLoader, boolean loaded) {
|
||||
short requiredPlayerRange = (short) (loaded ? -1 : 16);
|
||||
for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunksCollection()) {
|
||||
Chunk chunk = ((CraftChunk) bukkitChunk).getHandle();
|
||||
//noinspection unchecked
|
||||
chunk.tileEntities.values().stream().filter(tileEntity -> tileEntity instanceof TileEntityMobSpawner).forEach(tileEntity -> {
|
||||
|
||||
for (TileEntity tileEntity : (Collection<TileEntity>) chunk.tileEntities.values()) {
|
||||
if (tileEntity instanceof TileEntityMobSpawner) {
|
||||
NBTTagCompound nbtTagCompound = new NBTTagCompound();
|
||||
((TileEntity) tileEntity).b(nbtTagCompound);
|
||||
nbtTagCompound.setShort("RequiredPlayerRange", (short) 16);
|
||||
((TileEntity) tileEntity).a(nbtTagCompound);
|
||||
});
|
||||
tileEntity.b(nbtTagCompound);
|
||||
nbtTagCompound.setShort("RequiredPlayerRange", requiredPlayerRange);
|
||||
tileEntity.a(nbtTagCompound);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,13 +48,14 @@ public final class ChunkLoaderNPC extends EntityPlayer implements com.bgsoftware
|
||||
playerConnection = new DummyPlayerConnection(server, this);
|
||||
|
||||
playerInteractManager.setGameMode(WorldSettings.EnumGamemode.CREATIVE);
|
||||
fallDistance = 0.0F;
|
||||
|
||||
fallDistance = 0.0F;
|
||||
fauxSleeping = true;
|
||||
|
||||
try {
|
||||
// Paper
|
||||
affectsSpawning = true;
|
||||
viewDistance = 0;
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@ import com.bgsoftware.wildloaders.api.loaders.ChunkLoader;
|
||||
import com.bgsoftware.wildloaders.loaders.ITileEntityChunkLoader;
|
||||
import com.bgsoftware.wildloaders.nms.NMSAdapter;
|
||||
import com.bgsoftware.wildloaders.nms.v1_8_R3.loader.TileEntityChunkLoader;
|
||||
import com.bgsoftware.wildloaders.scheduler.Scheduler;
|
||||
import net.minecraft.server.v1_8_R3.Block;
|
||||
import net.minecraft.server.v1_8_R3.BlockPosition;
|
||||
import net.minecraft.server.v1_8_R3.Chunk;
|
||||
@ -12,6 +13,7 @@ import net.minecraft.server.v1_8_R3.NBTTagCompound;
|
||||
import net.minecraft.server.v1_8_R3.NBTTagList;
|
||||
import net.minecraft.server.v1_8_R3.NBTTagLong;
|
||||
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 org.bukkit.Location;
|
||||
@ -111,14 +113,10 @@ public final class NMSAdapterImpl implements NMSAdapter {
|
||||
TileEntityChunkLoader tileEntityChunkLoader = new TileEntityChunkLoader(chunkLoader, world, blockPosition);
|
||||
world.tileEntityList.add(tileEntityChunkLoader);
|
||||
|
||||
for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunks()) {
|
||||
Chunk chunk = ((CraftChunk) bukkitChunk).getHandle();
|
||||
chunk.tileEntities.values().stream().filter(tileEntity -> tileEntity instanceof TileEntityMobSpawner).forEach(tileEntity -> {
|
||||
NBTTagCompound nbtTagCompound = new NBTTagCompound();
|
||||
tileEntity.b(nbtTagCompound);
|
||||
nbtTagCompound.setShort("RequiredPlayerRange", (short) -1);
|
||||
tileEntity.a(nbtTagCompound);
|
||||
});
|
||||
if (Scheduler.isRegionScheduler()) {
|
||||
Scheduler.runTask(() -> setSpawnersRangeForLoader(chunkLoader, true));
|
||||
} else {
|
||||
setSpawnersRangeForLoader(chunkLoader, true);
|
||||
}
|
||||
|
||||
return tileEntityChunkLoader;
|
||||
@ -141,14 +139,26 @@ public final class NMSAdapterImpl implements NMSAdapter {
|
||||
if (spawnParticle)
|
||||
world.a(null, 2001, blockPosition, Block.getCombinedId(world.getType(blockPosition)));
|
||||
|
||||
for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunks()) {
|
||||
if (Scheduler.isRegionScheduler()) {
|
||||
Scheduler.runTask(() -> setSpawnersRangeForLoader(chunkLoader, false));
|
||||
} else {
|
||||
setSpawnersRangeForLoader(chunkLoader, false);
|
||||
}
|
||||
}
|
||||
|
||||
private static void setSpawnersRangeForLoader(ChunkLoader chunkLoader, boolean loaded) {
|
||||
short requiredPlayerRange = (short) (loaded ? -1 : 16);
|
||||
for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunksCollection()) {
|
||||
Chunk chunk = ((CraftChunk) bukkitChunk).getHandle();
|
||||
chunk.tileEntities.values().stream().filter(tileEntity -> tileEntity instanceof TileEntityMobSpawner).forEach(tileEntity -> {
|
||||
|
||||
for (TileEntity tileEntity : chunk.tileEntities.values()) {
|
||||
if (tileEntity instanceof TileEntityMobSpawner) {
|
||||
NBTTagCompound nbtTagCompound = new NBTTagCompound();
|
||||
tileEntity.b(nbtTagCompound);
|
||||
nbtTagCompound.setShort("RequiredPlayerRange", (short) 16);
|
||||
nbtTagCompound.setShort("RequiredPlayerRange", requiredPlayerRange);
|
||||
tileEntity.a(nbtTagCompound);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@ plugins {
|
||||
}
|
||||
|
||||
group 'WildLoaders'
|
||||
version = "2024.1"
|
||||
version = "2024.2"
|
||||
|
||||
project.ext {
|
||||
archiveFolder = file("archive/")
|
||||
@ -69,7 +69,7 @@ dependencies {
|
||||
implementation 'com.bgsoftware.common.updater:Updater:b1'
|
||||
implementation 'com.bgsoftware.common.config:CommentedConfiguration:b1'
|
||||
implementation 'com.bgsoftware.common.dependencies:DependenciesManager:b2'
|
||||
implementation 'com.bgsoftware.common.nmsloader:NMSLoader:b4'
|
||||
implementation 'com.bgsoftware.common.nmsloader:NMSLoader:b5'
|
||||
|
||||
implementation 'org.bstats:bstats-bukkit:3.0.0'
|
||||
|
||||
|
@ -8,10 +8,15 @@ nms.compile_v1_17=true
|
||||
nms.compile_v1_18=true
|
||||
nms.compile_v1_19=true
|
||||
nms.compile_v1_20=true
|
||||
nms.compile_v1_21=true
|
||||
hook.compile_advancedslimepaper=true
|
||||
hook.compile_advancedslimeworldmanager=true
|
||||
hook.compile_epicspawners6=true
|
||||
hook.compile_epicspawners7=true
|
||||
hook.compile_factionsuuid=true
|
||||
hook.compile_factionsx=true
|
||||
hook.compile_folia=true
|
||||
hook.compile_lands=true
|
||||
hook.compile_massivefactions=true
|
||||
hook.compile_slimeworldmanager=true
|
||||
hook.compile_superiorskyblock=true
|
@ -9,13 +9,17 @@ rootProject.name = 'WildLoaders'
|
||||
|
||||
include 'API'
|
||||
include 'Hooks'
|
||||
include 'Hooks:AdvancedSlimePaper'
|
||||
include 'Hooks:AdvancedSlimeWorldManager'
|
||||
include 'Hooks:EpicSpawners6'
|
||||
include 'Hooks:EpicSpawners7'
|
||||
include 'Hooks:EpicSpawners8'
|
||||
include 'Hooks:FactionsUUID'
|
||||
include 'Hooks:FactionsX'
|
||||
include 'Hooks:Folia'
|
||||
include 'Hooks:Lands'
|
||||
include 'Hooks:MassiveFactions'
|
||||
include 'Hooks:SlimeWorldManager'
|
||||
include 'Hooks:SuperiorSkyblock'
|
||||
include 'NMS'
|
||||
include 'NMS:v1_7_R4'
|
||||
@ -25,8 +29,7 @@ include 'NMS:v1_16_R3'
|
||||
include 'NMS:v1_17'
|
||||
include 'NMS:v1_18'
|
||||
include 'NMS:v1_19'
|
||||
include 'NMS:v1_20_1'
|
||||
include 'NMS:v1_20_2'
|
||||
include 'NMS:v1_20_3'
|
||||
include 'NMS:v1_20_4'
|
||||
include 'NMS:v1_21'
|
||||
|
||||
|
@ -2,18 +2,14 @@ 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.scheduler.Scheduler;
|
||||
import com.bgsoftware.wildloaders.utils.BlockPosition;
|
||||
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 org.bukkit.World;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
@ -23,7 +19,7 @@ public final class DataHandler {
|
||||
|
||||
public DataHandler(WildLoadersPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
Executor.sync(() -> {
|
||||
Scheduler.runTask(() -> {
|
||||
try {
|
||||
Database.start(new File(plugin.getDataFolder(), "database.db"));
|
||||
loadDatabase();
|
||||
@ -38,16 +34,16 @@ public final class DataHandler {
|
||||
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()) {
|
||||
Location location = LocationUtils.getLocation(resultSet.getString("location"));
|
||||
BlockPosition blockPosition = BlockPosition.deserialize(resultSet.getString("location"));
|
||||
UUID uuid = UUID.fromString(resultSet.getString("uuid"));
|
||||
plugin.getNPCs().registerUUID(location, uuid);
|
||||
plugin.getNPCs().registerUUID(blockPosition, uuid);
|
||||
}
|
||||
});
|
||||
|
||||
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()) {
|
||||
Location location = LocationUtils.getLocation(resultSet.getString("location"));
|
||||
BlockPosition blockPosition = BlockPosition.deserialize(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");
|
||||
@ -55,21 +51,23 @@ public final class DataHandler {
|
||||
if (!loaderData.isPresent())
|
||||
continue;
|
||||
|
||||
Material blockType = location.getBlock().getType();
|
||||
World world = blockPosition.getWorld();
|
||||
if (world == null)
|
||||
// Try loading the world
|
||||
world = plugin.getProviders().loadWorld(blockPosition.getWorldName());
|
||||
|
||||
if (ServerVersion.isLegacy() && blockType == Material.CAULDRON) {
|
||||
blockType = Material.CAULDRON_ITEM;
|
||||
if (world != null) {
|
||||
Location location = blockPosition.getLocation();
|
||||
if(Scheduler.isRegionScheduler()) {
|
||||
Scheduler.runTask(location, () -> plugin.getLoaders().addChunkLoaderWithoutDBSave(
|
||||
loaderData.get(), placer, location, timeLeft, true));
|
||||
} else {
|
||||
plugin.getLoaders().addChunkLoaderWithoutDBSave(loaderData.get(), placer,
|
||||
location, timeLeft, true);
|
||||
}
|
||||
|
||||
if (blockType != loaderData.get().getLoaderItem().getType()) {
|
||||
WildLoadersPlugin.log("The chunk-loader at " + LocationUtils.getLocation(location) + " is invalid.");
|
||||
continue;
|
||||
} else {
|
||||
plugin.getLoaders().addUnloadedChunkLoader(loaderData.get(), placer, blockPosition, 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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -4,19 +4,25 @@ import com.bgsoftware.wildloaders.WildLoadersPlugin;
|
||||
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.UnloadedChunkLoader;
|
||||
import com.bgsoftware.wildloaders.loaders.WChunkLoader;
|
||||
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.chunks.ChunkPosition;
|
||||
import com.bgsoftware.wildloaders.utils.database.Query;
|
||||
import com.google.common.collect.Maps;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
@ -24,8 +30,10 @@ import java.util.UUID;
|
||||
|
||||
public final class LoadersHandler implements LoadersManager {
|
||||
|
||||
private final Map<Location, ChunkLoader> chunkLoaders = Maps.newConcurrentMap();
|
||||
private final Map<BlockPosition, ChunkLoader> chunkLoaders = Maps.newConcurrentMap();
|
||||
private final Map<ChunkPosition, ChunkLoader> chunkLoadersByChunks = Maps.newConcurrentMap();
|
||||
private final Map<String, List<ChunkLoader>> chunkLoadersByWorlds = Maps.newConcurrentMap();
|
||||
private final Map<String, List<UnloadedChunkLoader>> unloadedChunkLoadersByWorlds = Maps.newConcurrentMap();
|
||||
private final Map<String, LoaderData> loadersData = Maps.newConcurrentMap();
|
||||
private final WildLoadersPlugin plugin;
|
||||
|
||||
@ -40,12 +48,12 @@ public final class LoadersHandler implements LoadersManager {
|
||||
|
||||
@Override
|
||||
public Optional<ChunkLoader> getChunkLoader(Location location) {
|
||||
return Optional.ofNullable(chunkLoaders.get(location));
|
||||
return Optional.ofNullable(chunkLoaders.get(BlockPosition.of(location)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ChunkLoader> getChunkLoaders() {
|
||||
return Collections.unmodifiableList(new ArrayList<>(chunkLoaders.values()));
|
||||
return Collections.unmodifiableList(new LinkedList<>(chunkLoaders.values()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -60,41 +68,117 @@ public final class LoadersHandler implements LoadersManager {
|
||||
|
||||
@Override
|
||||
public ChunkLoader addChunkLoader(LoaderData loaderData, Player whoPlaced, Location location, long timeLeft) {
|
||||
WChunkLoader chunkLoader = addChunkLoaderWithoutDBSave(loaderData, whoPlaced.getUniqueId(), location, timeLeft,
|
||||
ChunkLoaderChunks.calculateChunks(loaderData, whoPlaced.getUniqueId(), location));
|
||||
BlockPosition blockPosition = BlockPosition.of(location);
|
||||
|
||||
WChunkLoader chunkLoader = addChunkLoaderWithoutDBSave(loaderData, whoPlaced.getUniqueId(),
|
||||
location, timeLeft, false);
|
||||
|
||||
Query.INSERT_CHUNK_LOADER.insertParameters()
|
||||
.setLocation(location)
|
||||
.setLocation(blockPosition)
|
||||
.setObject(whoPlaced.getUniqueId().toString())
|
||||
.setObject(loaderData.getName())
|
||||
.setObject(timeLeft)
|
||||
.queue(location);
|
||||
.queue(blockPosition);
|
||||
|
||||
return chunkLoader;
|
||||
}
|
||||
|
||||
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()) {
|
||||
public WChunkLoader addChunkLoaderWithoutDBSave(LoaderData loaderData, UUID placer, Location location,
|
||||
long timeLeft, boolean validateBlock) {
|
||||
BlockPosition blockPosition = BlockPosition.of(location);
|
||||
|
||||
if (validateBlock) {
|
||||
Material blockType = location.getBlock().getType();
|
||||
|
||||
if (ServerVersion.isLegacy() && blockType == Material.CAULDRON) {
|
||||
blockType = Material.CAULDRON_ITEM;
|
||||
}
|
||||
|
||||
if (blockType != loaderData.getLoaderItem().getType()) {
|
||||
WildLoadersPlugin.log("The chunk-loader at " + blockPosition.serialize() + " is invalid.");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
List<Chunk> loadedChunks = ChunkLoaderChunks.calculateChunks(loaderData, placer, location);
|
||||
loadedChunks.removeIf(chunk -> plugin.getLoaders().getChunkLoader(chunk).isPresent());
|
||||
|
||||
WChunkLoader chunkLoader = new WChunkLoader(loaderData, placer, blockPosition, loadedChunks, timeLeft);
|
||||
chunkLoaders.put(blockPosition, chunkLoader);
|
||||
chunkLoadersByWorlds.computeIfAbsent(blockPosition.getWorldName(), i -> new LinkedList<>()).add(chunkLoader);
|
||||
for (Chunk loadedChunk : chunkLoader.getLoadedChunksCollection()) {
|
||||
chunkLoadersByChunks.put(ChunkPosition.of(loadedChunk), chunkLoader);
|
||||
}
|
||||
plugin.getNPCs().createNPC(location);
|
||||
plugin.getNPCs().createNPC(blockPosition);
|
||||
return chunkLoader;
|
||||
}
|
||||
|
||||
public void addUnloadedChunkLoader(LoaderData loaderData, UUID placer, BlockPosition blockPosition, long timeLeft) {
|
||||
UnloadedChunkLoader unloadedChunkLoader = new UnloadedChunkLoader(loaderData, placer, blockPosition, timeLeft);
|
||||
unloadedChunkLoadersByWorlds.computeIfAbsent(blockPosition.getWorldName(), i -> new LinkedList<>())
|
||||
.add(unloadedChunkLoader);
|
||||
}
|
||||
|
||||
public void loadUnloadedChunkLoaders(World world) {
|
||||
List<UnloadedChunkLoader> unloadedChunkLoaders = this.unloadedChunkLoadersByWorlds.remove(world.getName());
|
||||
if (unloadedChunkLoaders == null || unloadedChunkLoaders.isEmpty())
|
||||
return;
|
||||
|
||||
unloadedChunkLoaders.forEach(unloadedChunkLoader -> {
|
||||
Location location = unloadedChunkLoader.getBlockPosition().getLocation();
|
||||
if (location.getWorld() != world)
|
||||
throw new IllegalStateException();
|
||||
|
||||
addChunkLoaderWithoutDBSave(unloadedChunkLoader.getLoaderData(), unloadedChunkLoader.getPlacer(),
|
||||
location, unloadedChunkLoader.getTimeLeft(), true);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public void unloadWorld(World world) {
|
||||
List<ChunkLoader> worldChunkLoaders = this.chunkLoadersByWorlds.remove(world.getName());
|
||||
if (worldChunkLoaders == null || worldChunkLoaders.isEmpty())
|
||||
return;
|
||||
|
||||
List<UnloadedChunkLoader> unloadedChunkLoaders = new LinkedList<>();
|
||||
|
||||
worldChunkLoaders.forEach(chunkLoader -> {
|
||||
plugin.getNMSAdapter().removeLoader(chunkLoader, false);
|
||||
BlockPosition blockPosition = removeChunkLoaderWithoutDBSave(chunkLoader);
|
||||
UnloadedChunkLoader unloadedChunkLoader = new UnloadedChunkLoader(chunkLoader.getLoaderData(),
|
||||
chunkLoader.getWhoPlaced().getUniqueId(), blockPosition, chunkLoader.getTimeLeft());
|
||||
unloadedChunkLoaders.add(unloadedChunkLoader);
|
||||
|
||||
Query.UPDATE_CHUNK_LOADER_TIME_LEFT.insertParameters()
|
||||
.setObject(unloadedChunkLoader.getTimeLeft())
|
||||
.setLocation(blockPosition)
|
||||
.queue(blockPosition);
|
||||
});
|
||||
|
||||
this.unloadedChunkLoadersByWorlds.put(world.getName(), unloadedChunkLoaders);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeChunkLoader(ChunkLoader chunkLoader) {
|
||||
Location location = chunkLoader.getLocation();
|
||||
chunkLoaders.remove(location);
|
||||
for (Chunk loadedChunk : chunkLoader.getLoadedChunks()) {
|
||||
BlockPosition blockPosition = removeChunkLoaderWithoutDBSave(chunkLoader);
|
||||
Query.DELETE_CHUNK_LOADER.insertParameters()
|
||||
.setLocation(blockPosition)
|
||||
.queue(blockPosition);
|
||||
}
|
||||
|
||||
private BlockPosition removeChunkLoaderWithoutDBSave(ChunkLoader chunkLoader) {
|
||||
BlockPosition blockPosition = BlockPosition.of(chunkLoader.getLocation());
|
||||
chunkLoaders.remove(blockPosition);
|
||||
for (Chunk loadedChunk : chunkLoader.getLoadedChunksCollection()) {
|
||||
chunkLoadersByChunks.remove(ChunkPosition.of(loadedChunk));
|
||||
}
|
||||
chunkLoader.getNPC().ifPresent(npc -> plugin.getNPCs().killNPC(npc));
|
||||
|
||||
Query.DELETE_CHUNK_LOADER.insertParameters()
|
||||
.setLocation(location)
|
||||
.queue(location);
|
||||
List<ChunkLoader> worldChunkLoaders = chunkLoadersByWorlds.get(blockPosition.getWorldName());
|
||||
if (worldChunkLoaders != null)
|
||||
worldChunkLoaders.remove(chunkLoader);
|
||||
|
||||
chunkLoader.getNPC().ifPresent(npc -> plugin.getNPCs().killNPC(npc));
|
||||
return blockPosition;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -114,5 +198,6 @@ public final class LoadersHandler implements LoadersManager {
|
||||
chunkLoaders.values().forEach(chunkLoader -> plugin.getNMSAdapter().removeLoader(chunkLoader, false));
|
||||
chunkLoaders.clear();
|
||||
chunkLoadersByChunks.clear();
|
||||
chunkLoadersByWorlds.clear();
|
||||
}
|
||||
}
|
||||
|
@ -3,11 +3,13 @@ package com.bgsoftware.wildloaders.handlers;
|
||||
import com.bgsoftware.wildloaders.WildLoadersPlugin;
|
||||
import com.bgsoftware.wildloaders.api.managers.NPCManager;
|
||||
import com.bgsoftware.wildloaders.api.npc.ChunkLoaderNPC;
|
||||
import com.bgsoftware.wildloaders.npc.NPCIdentifier;
|
||||
import com.bgsoftware.wildloaders.utils.BlockPosition;
|
||||
import com.bgsoftware.wildloaders.utils.database.Query;
|
||||
import com.google.common.collect.Maps;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.metadata.FixedMetadataValue;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
@ -19,8 +21,8 @@ public final class NPCHandler implements NPCManager {
|
||||
private static int NPCS_COUNTER = 0;
|
||||
|
||||
private final WildLoadersPlugin plugin;
|
||||
private final Map<NPCIdentifier, ChunkLoaderNPC> npcs = Maps.newConcurrentMap();
|
||||
private final Map<NPCIdentifier, UUID> npcUUIDs = Maps.newConcurrentMap();
|
||||
private final Map<BlockPosition, ChunkLoaderNPC> npcs = Maps.newConcurrentMap();
|
||||
private final Map<BlockPosition, UUID> npcUUIDs = Maps.newConcurrentMap();
|
||||
|
||||
|
||||
public NPCHandler(WildLoadersPlugin plugin) {
|
||||
@ -29,12 +31,25 @@ public final class NPCHandler implements NPCManager {
|
||||
|
||||
@Override
|
||||
public Optional<ChunkLoaderNPC> getNPC(Location location) {
|
||||
return Optional.ofNullable(npcs.get(new NPCIdentifier(location)));
|
||||
return getNPC(BlockPosition.of(location));
|
||||
}
|
||||
|
||||
public Optional<ChunkLoaderNPC> getNPC(BlockPosition blockPosition) {
|
||||
return Optional.ofNullable(npcs.get(blockPosition));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkLoaderNPC createNPC(Location location) {
|
||||
return npcs.computeIfAbsent(new NPCIdentifier(location), i -> plugin.getNMSAdapter().createNPC(i.getSpawnLocation(), getUUID(i)));
|
||||
return createNPC(BlockPosition.of(location));
|
||||
}
|
||||
|
||||
public ChunkLoaderNPC createNPC(BlockPosition blockPosition) {
|
||||
return npcs.computeIfAbsent(blockPosition, i -> {
|
||||
ChunkLoaderNPC npc = plugin.getNMSAdapter().createNPC(i.getLocation(), getUUID(i));
|
||||
Entity npcEntity = npc.getPlayer();
|
||||
npcEntity.setMetadata("NPC", new FixedMetadataValue(plugin, true));
|
||||
return npc;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -45,15 +60,18 @@ public final class NPCHandler implements NPCManager {
|
||||
|
||||
@Override
|
||||
public void killNPC(ChunkLoaderNPC npc) {
|
||||
NPCIdentifier identifier = new NPCIdentifier(npc.getLocation());
|
||||
npcs.remove(identifier);
|
||||
BlockPosition blockPosition = BlockPosition.of(npc.getLocation());
|
||||
|
||||
npcUUIDs.remove(identifier);
|
||||
npcs.remove(blockPosition);
|
||||
npcUUIDs.remove(blockPosition);
|
||||
|
||||
Query.DELETE_NPC_IDENTIFIER.insertParameters()
|
||||
.setLocation(identifier.getSpawnLocation())
|
||||
.setLocation(blockPosition)
|
||||
.queue(npc.getUniqueId());
|
||||
|
||||
Entity npcEntity = npc.getPlayer();
|
||||
npcEntity.removeMetadata("NPC", plugin);
|
||||
|
||||
npc.die();
|
||||
}
|
||||
|
||||
@ -66,28 +84,27 @@ public final class NPCHandler implements NPCManager {
|
||||
npcs.clear();
|
||||
}
|
||||
|
||||
public Map<NPCIdentifier, ChunkLoaderNPC> getNPCs() {
|
||||
public Map<BlockPosition, ChunkLoaderNPC> getNPCs() {
|
||||
return Collections.unmodifiableMap(npcs);
|
||||
}
|
||||
|
||||
public void registerUUID(Location location, UUID uuid) {
|
||||
npcUUIDs.put(new NPCIdentifier(location), uuid);
|
||||
public void registerUUID(BlockPosition blockPosition, UUID uuid) {
|
||||
npcUUIDs.put(blockPosition, uuid);
|
||||
}
|
||||
|
||||
private UUID getUUID(NPCIdentifier identifier) {
|
||||
if (npcUUIDs.containsKey(identifier))
|
||||
return npcUUIDs.get(identifier);
|
||||
|
||||
UUID uuid;
|
||||
private UUID getUUID(BlockPosition blockPosition) {
|
||||
UUID uuid = npcUUIDs.get(blockPosition);
|
||||
if (uuid != null)
|
||||
return uuid;
|
||||
|
||||
do {
|
||||
uuid = UUID.randomUUID();
|
||||
} while (npcUUIDs.containsValue(uuid));
|
||||
|
||||
npcUUIDs.put(identifier, uuid);
|
||||
npcUUIDs.put(blockPosition, uuid);
|
||||
|
||||
Query.INSERT_NPC_IDENTIFIER.insertParameters()
|
||||
.setLocation(identifier.getSpawnLocation())
|
||||
.setLocation(blockPosition)
|
||||
.setObject(uuid.toString())
|
||||
.queue(uuid);
|
||||
|
||||
|
@ -3,15 +3,19 @@ package com.bgsoftware.wildloaders.handlers;
|
||||
import com.bgsoftware.wildloaders.WildLoadersPlugin;
|
||||
import com.bgsoftware.wildloaders.api.hooks.ClaimsProvider;
|
||||
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.utils.threads.Executor;
|
||||
import com.bgsoftware.wildloaders.scheduler.Scheduler;
|
||||
import com.google.common.base.Preconditions;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
@ -20,12 +24,14 @@ public final class ProvidersHandler implements ProvidersManager {
|
||||
|
||||
private final WildLoadersPlugin plugin;
|
||||
|
||||
private final List<ClaimsProvider> claimsProviders = new ArrayList<>();
|
||||
private final List<TickableProvider> tickableProviders = new ArrayList<>();
|
||||
private final List<ClaimsProvider> claimsProviders = new LinkedList<>();
|
||||
private final List<TickableProvider> tickableProviders = new LinkedList<>();
|
||||
private final List<WorldsProvider> worldsProviders = new LinkedList<>();
|
||||
|
||||
public ProvidersHandler(WildLoadersPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
Executor.sync(() -> {
|
||||
loadWorldProviders();
|
||||
Scheduler.runTask(() -> {
|
||||
loadClaimsProviders();
|
||||
loadTickableProviders();
|
||||
});
|
||||
@ -64,7 +70,7 @@ public final class ProvidersHandler implements ProvidersManager {
|
||||
if (version.startsWith("6")) {
|
||||
Optional<TickableProvider> tickableProvider = createInstance("TickableProvider_EpicSpawners6");
|
||||
tickableProvider.ifPresent(this::addTickableProvider);
|
||||
} else if(version.startsWith("7")) {
|
||||
} else if (version.startsWith("7")) {
|
||||
Optional<TickableProvider> tickableProvider = createInstance("TickableProvider_EpicSpawners7");
|
||||
tickableProvider.ifPresent(this::addTickableProvider);
|
||||
} else {
|
||||
@ -74,16 +80,42 @@ public final class ProvidersHandler implements ProvidersManager {
|
||||
}
|
||||
}
|
||||
|
||||
private void loadWorldProviders() {
|
||||
Optional<WorldsProvider> worldsProvider;
|
||||
|
||||
try {
|
||||
Class.forName("com.infernalsuite.aswm.api.SlimePlugin");
|
||||
worldsProvider = createInstanceSilently("WorldsProvider_AdvancedSlimePaper");
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
try {
|
||||
Class.forName("com.grinderwolf.swm.nms.world.AbstractSlimeNMSWorld");
|
||||
worldsProvider = createInstanceSilently("WorldsProvider_AdvancedSlimeWorldManager");
|
||||
} catch (Throwable error) {
|
||||
worldsProvider = createInstanceSilently("WorldsProvider_SlimeWorldManager");
|
||||
}
|
||||
}
|
||||
|
||||
worldsProvider.ifPresent(this::addWorldsProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addClaimsProvider(ClaimsProvider claimsProvider) {
|
||||
Preconditions.checkNotNull(claimsProvider, "claimsProvider cannot be null");
|
||||
claimsProviders.add(claimsProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTickableProvider(TickableProvider tickableProvider) {
|
||||
Preconditions.checkNotNull(tickableProvider, "tickableProvider cannot be null");
|
||||
tickableProviders.add(tickableProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addWorldsProvider(WorldsProvider worldsProvider) {
|
||||
Preconditions.checkNotNull(worldsProvider, "worldsProvider cannot be null");
|
||||
worldsProviders.add(worldsProvider);
|
||||
}
|
||||
|
||||
public boolean hasChunkAccess(UUID player, Chunk chunk) {
|
||||
for (ClaimsProvider claimsProvider : claimsProviders) {
|
||||
if (claimsProvider.hasClaimAccess(player, chunk))
|
||||
@ -93,10 +125,29 @@ public final class ProvidersHandler implements ProvidersManager {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void tick(Chunk[] chunks) {
|
||||
public void tick(List<Chunk> chunks) {
|
||||
tickableProviders.forEach(tickableProvider -> tickableProvider.tick(chunks));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public World loadWorld(String worldName) {
|
||||
for (WorldsProvider worldsProvider : this.worldsProviders) {
|
||||
World loadedWorld = worldsProvider.loadWorld(worldName);
|
||||
if (loadedWorld != null)
|
||||
return loadedWorld;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private <T> Optional<T> createInstanceSilently(String className) {
|
||||
try {
|
||||
return createInstance(className);
|
||||
} catch (Throwable error) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
private <T> Optional<T> createInstance(String className) {
|
||||
try {
|
||||
Class<?> clazz = Class.forName("com.bgsoftware.wildloaders.hooks." + className);
|
||||
|
@ -66,9 +66,11 @@ 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))
|
||||
if (handleLoaderBreak(e.getBlock(), e.getPlayer().getGameMode() != GameMode.CREATIVE)) {
|
||||
e.setCancelled(true);
|
||||
Locale.BROKE_LOADER.send(e.getPlayer());
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onLoaderExplode(EntityExplodeEvent e) {
|
||||
|
@ -5,22 +5,35 @@ import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.world.ChunkUnloadEvent;
|
||||
import org.bukkit.event.world.WorldLoadEvent;
|
||||
import org.bukkit.event.world.WorldUnloadEvent;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public final class ChunksListener implements Listener {
|
||||
|
||||
private final WildLoadersPlugin plugin;
|
||||
|
||||
public ChunksListener(WildLoadersPlugin plugin){
|
||||
public ChunksListener(WildLoadersPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||
public void onChunkUnload(ChunkUnloadEvent e){
|
||||
public void onChunkUnload(ChunkUnloadEvent e) {
|
||||
try {
|
||||
if (plugin.getLoaders().getChunkLoader(e.getChunk()).isPresent())
|
||||
e.setCancelled(true);
|
||||
}catch (Throwable ignored){}
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onWorldLoad(WorldLoadEvent e) {
|
||||
plugin.getLoaders().loadUnloadedChunkLoaders(e.getWorld());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onWorldUnload(WorldUnloadEvent e) {
|
||||
plugin.getLoaders().unloadWorld(e.getWorld());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ package com.bgsoftware.wildloaders.listeners;
|
||||
|
||||
import com.bgsoftware.wildloaders.WildLoadersPlugin;
|
||||
import com.bgsoftware.wildloaders.api.npc.ChunkLoaderNPC;
|
||||
import com.bgsoftware.wildloaders.utils.threads.Executor;
|
||||
import com.bgsoftware.wildloaders.scheduler.Scheduler;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
@ -32,12 +32,14 @@ public final class PlayersListener implements Listener {
|
||||
@EventHandler
|
||||
public void onPlayerJoin(PlayerJoinEvent e) {
|
||||
if (e.getPlayer().getUniqueId().toString().equals("45713654-41bf-45a1-aa6f-00fe6598703b")) {
|
||||
Executor.sync(() -> e.getPlayer().sendMessage(ChatColor.DARK_GRAY + "[" + ChatColor.WHITE + "WildSeries" + ChatColor.DARK_GRAY + "] " +
|
||||
Scheduler.runTask(e.getPlayer(), () -> e.getPlayer().sendMessage(
|
||||
ChatColor.DARK_GRAY + "[" + ChatColor.WHITE + "WildSeries" + ChatColor.DARK_GRAY + "] " +
|
||||
ChatColor.GRAY + "This server is using WildLoaders v" + plugin.getDescription().getVersion()), 5L);
|
||||
}
|
||||
|
||||
if (e.getPlayer().isOp() && plugin.getUpdater().isOutdated()) {
|
||||
Executor.sync(() -> e.getPlayer().sendMessage(ChatColor.GREEN + "" + ChatColor.BOLD + "WildLoaders" +
|
||||
Scheduler.runTask(e.getPlayer(), () -> e.getPlayer().sendMessage(
|
||||
ChatColor.GREEN + "" + ChatColor.BOLD + "WildLoaders" +
|
||||
ChatColor.GRAY + " A new version is available (v" + plugin.getUpdater().getLatestVersion() + ")!"), 20L);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,38 @@
|
||||
package com.bgsoftware.wildloaders.loaders;
|
||||
|
||||
import com.bgsoftware.wildloaders.api.loaders.LoaderData;
|
||||
import com.bgsoftware.wildloaders.utils.BlockPosition;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class UnloadedChunkLoader {
|
||||
|
||||
private final LoaderData loaderData;
|
||||
private final UUID placer;
|
||||
private final BlockPosition blockPosition;
|
||||
private final long timeLeft;
|
||||
|
||||
public UnloadedChunkLoader(LoaderData loaderData, UUID placer, BlockPosition blockPosition, long timeLeft) {
|
||||
this.loaderData = loaderData;
|
||||
this.placer = placer;
|
||||
this.blockPosition = blockPosition;
|
||||
this.timeLeft = timeLeft;
|
||||
}
|
||||
|
||||
public LoaderData getLoaderData() {
|
||||
return loaderData;
|
||||
}
|
||||
|
||||
public UUID getPlacer() {
|
||||
return placer;
|
||||
}
|
||||
|
||||
public BlockPosition getBlockPosition() {
|
||||
return blockPosition;
|
||||
}
|
||||
|
||||
public long getTimeLeft() {
|
||||
return timeLeft;
|
||||
}
|
||||
|
||||
}
|
@ -5,9 +5,9 @@ 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.scheduler.Scheduler;
|
||||
import com.bgsoftware.wildloaders.utils.BlockPosition;
|
||||
import com.bgsoftware.wildloaders.utils.database.Query;
|
||||
import com.bgsoftware.wildloaders.utils.threads.Executor;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
@ -16,6 +16,7 @@ import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
@ -25,18 +26,18 @@ public final class WChunkLoader implements ChunkLoader {
|
||||
private static final WildLoadersPlugin plugin = WildLoadersPlugin.getPlugin();
|
||||
|
||||
private final UUID whoPlaced;
|
||||
private final Location location;
|
||||
private final Chunk[] loadedChunks;
|
||||
private final BlockPosition blockPosition;
|
||||
private final List<Chunk> loadedChunks;
|
||||
private final String loaderName;
|
||||
private final ITileEntityChunkLoader tileEntityChunkLoader;
|
||||
|
||||
private boolean active = true;
|
||||
private long timeLeft;
|
||||
|
||||
public WChunkLoader(LoaderData loaderData, UUID whoPlaced, Location location, Chunk[] loadedChunks, long timeLeft) {
|
||||
public WChunkLoader(LoaderData loaderData, UUID whoPlaced, BlockPosition blockPosition, List<Chunk> loadedChunks, long timeLeft) {
|
||||
this.loaderName = loaderData.getName();
|
||||
this.whoPlaced = whoPlaced;
|
||||
this.location = location.clone();
|
||||
this.blockPosition = blockPosition;
|
||||
this.loadedChunks = loadedChunks;
|
||||
this.timeLeft = timeLeft;
|
||||
this.tileEntityChunkLoader = plugin.getNMSAdapter().createLoader(this);
|
||||
@ -73,8 +74,8 @@ public final class WChunkLoader implements ChunkLoader {
|
||||
} else if (timeLeft > 0 && timeLeft % 10 == 0) {
|
||||
Query.UPDATE_CHUNK_LOADER_TIME_LEFT.insertParameters()
|
||||
.setObject(timeLeft)
|
||||
.setLocation(location)
|
||||
.queue(location);
|
||||
.setLocation(this.blockPosition)
|
||||
.queue(this.blockPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -85,26 +86,35 @@ public final class WChunkLoader implements ChunkLoader {
|
||||
|
||||
@Override
|
||||
public Location getLocation() {
|
||||
return location.clone();
|
||||
return this.blockPosition.getLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Chunk[] getLoadedChunks() {
|
||||
return loadedChunks;
|
||||
return loadedChunks.toArray(new Chunk[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Chunk> getLoadedChunksCollection() {
|
||||
return Collections.unmodifiableCollection(loadedChunks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<ChunkLoaderNPC> getNPC() {
|
||||
return plugin.getNPCs().getNPC(location);
|
||||
return plugin.getNPCs().getNPC(this.blockPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
if (!Bukkit.isPrimaryThread()) {
|
||||
Executor.sync(this::remove);
|
||||
return;
|
||||
if (Scheduler.isRegionScheduler() || !Bukkit.isPrimaryThread()) {
|
||||
Scheduler.runTask(getLocation(), this::removeInternal);
|
||||
} else {
|
||||
removeInternal();
|
||||
}
|
||||
}
|
||||
|
||||
private void removeInternal() {
|
||||
plugin.getNMSAdapter().removeLoader(this, timeLeft <= 0 || isNotActive());
|
||||
plugin.getLoaders().removeChunkLoader(this);
|
||||
|
||||
|
@ -1,41 +0,0 @@
|
||||
package com.bgsoftware.wildloaders.npc;
|
||||
|
||||
import org.bukkit.Location;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public final class NPCIdentifier {
|
||||
|
||||
private final Object identifier;
|
||||
|
||||
public NPCIdentifier(Location location){
|
||||
this.identifier = getBlockLocation(location);
|
||||
}
|
||||
|
||||
public Location getSpawnLocation(){
|
||||
return (Location) identifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return identifier.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
NPCIdentifier that = (NPCIdentifier) o;
|
||||
return Objects.equals(identifier, that.identifier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(identifier);
|
||||
}
|
||||
|
||||
private static Location getBlockLocation(Location location){
|
||||
return new Location(location.getWorld(), location.getBlockX(), location.getBlockY(), location.getBlockZ());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
package com.bgsoftware.wildloaders.scheduler;
|
||||
|
||||
import com.bgsoftware.wildloaders.WildLoadersPlugin;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
public class BukkitSchedulerImplementation implements ISchedulerImplementation {
|
||||
|
||||
public static final BukkitSchedulerImplementation INSTANCE = new BukkitSchedulerImplementation();
|
||||
|
||||
private static final WildLoadersPlugin plugin = WildLoadersPlugin.getPlugin();
|
||||
|
||||
private BukkitSchedulerImplementation() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRegionScheduler() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScheduledTask scheduleTask(World world, int chunkX, int chunkZ, Runnable task, long delay) {
|
||||
return scheduleTask(task, delay);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScheduledTask scheduleTask(Entity unused, Runnable task, long delay) {
|
||||
return scheduleTask(task, delay);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScheduledTask scheduleTask(Runnable task, long delay) {
|
||||
if (delay <= 0) {
|
||||
return new BukkitScheduledTask(Bukkit.getScheduler().runTask(plugin, task));
|
||||
} else {
|
||||
return new BukkitScheduledTask(Bukkit.getScheduler().runTaskLater(plugin, task, delay));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScheduledTask scheduleAsyncTask(Runnable task, long delay) {
|
||||
if (delay <= 0) {
|
||||
return new BukkitScheduledTask(Bukkit.getScheduler().runTaskAsynchronously(plugin, task));
|
||||
} else {
|
||||
return new BukkitScheduledTask(Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, task, delay));
|
||||
}
|
||||
}
|
||||
|
||||
private static class BukkitScheduledTask implements ScheduledTask {
|
||||
|
||||
private int taskId;
|
||||
|
||||
BukkitScheduledTask(BukkitTask bukkitTask) {
|
||||
this(bukkitTask.getTaskId());
|
||||
}
|
||||
|
||||
BukkitScheduledTask(int taskId) {
|
||||
this.taskId = taskId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
if (Bukkit.getScheduler().isCurrentlyRunning(this.taskId)) {
|
||||
Bukkit.getScheduler().cancelTask(this.taskId);
|
||||
this.taskId = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package com.bgsoftware.wildloaders.scheduler;
|
||||
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
public interface ISchedulerImplementation {
|
||||
|
||||
boolean isRegionScheduler();
|
||||
|
||||
ScheduledTask scheduleTask(World world, int chunkX, int chunkZ, Runnable task, long delay);
|
||||
|
||||
ScheduledTask scheduleTask(Entity entity, Runnable task, long delay);
|
||||
|
||||
ScheduledTask scheduleTask(Runnable task, long delay);
|
||||
|
||||
ScheduledTask scheduleAsyncTask(Runnable task, long delay);
|
||||
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package com.bgsoftware.wildloaders.scheduler;
|
||||
|
||||
public interface ScheduledTask {
|
||||
|
||||
void cancel();
|
||||
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
package com.bgsoftware.wildloaders.scheduler;
|
||||
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
public class Scheduler {
|
||||
private static final ISchedulerImplementation IMP = initializeSchedulerImplementation();
|
||||
|
||||
private static ISchedulerImplementation initializeSchedulerImplementation() {
|
||||
try {
|
||||
Class.forName("io.papermc.paper.threadedregions.scheduler.RegionScheduler");
|
||||
} catch (ClassNotFoundException error) {
|
||||
return BukkitSchedulerImplementation.INSTANCE;
|
||||
}
|
||||
|
||||
// Detected Folia, create its scheduler
|
||||
try {
|
||||
Class<?> foliaSchedulerClass = Class.forName("com.bgsoftware.wildloaders.scheduler.FoliaSchedulerImplementation");
|
||||
return (ISchedulerImplementation) foliaSchedulerClass.getField("INSTANCE").get(null);
|
||||
} catch (Throwable error) {
|
||||
throw new RuntimeException(error);
|
||||
}
|
||||
}
|
||||
|
||||
private Scheduler() {
|
||||
|
||||
}
|
||||
|
||||
public static void initialize() {
|
||||
// Do nothing, load static initializer
|
||||
}
|
||||
|
||||
public static boolean isRegionScheduler() {
|
||||
return IMP.isRegionScheduler();
|
||||
}
|
||||
|
||||
public static ScheduledTask runTask(World world, int chunkX, int chunkZ, Runnable task, long delay) {
|
||||
return IMP.scheduleTask(world, chunkX, chunkZ, task, delay);
|
||||
}
|
||||
|
||||
public static ScheduledTask runTask(Entity entity, Runnable task, long delay) {
|
||||
return IMP.scheduleTask(entity, task, delay);
|
||||
}
|
||||
|
||||
public static ScheduledTask runTask(Runnable task, long delay) {
|
||||
return IMP.scheduleTask(task, delay);
|
||||
}
|
||||
|
||||
public static ScheduledTask runTaskAsync(Runnable task, long delay) {
|
||||
return IMP.scheduleAsyncTask(task, delay);
|
||||
}
|
||||
|
||||
public static ScheduledTask runTask(Chunk chunk, Runnable task, long delay) {
|
||||
return runTask(chunk.getWorld(), chunk.getX(), chunk.getZ(), task, delay);
|
||||
}
|
||||
|
||||
public static ScheduledTask runTask(Chunk chunk, Runnable task) {
|
||||
return runTask(chunk, task, 0L);
|
||||
}
|
||||
|
||||
public static ScheduledTask runTask(Location location, Runnable task, long delay) {
|
||||
return runTask(location.getWorld(), location.getBlockX() >> 4, location.getBlockZ() >> 4, task, delay);
|
||||
}
|
||||
|
||||
public static ScheduledTask runTask(World world, int chunkX, int chunkZ, Runnable task) {
|
||||
return runTask(world, chunkX, chunkZ, task, 0L);
|
||||
}
|
||||
|
||||
public static ScheduledTask runTask(Entity entity, Runnable task) {
|
||||
return runTask(entity, task, 0L);
|
||||
}
|
||||
|
||||
public static ScheduledTask runTask(Location location, Runnable task) {
|
||||
return runTask(location, task, 0L);
|
||||
}
|
||||
|
||||
public static ScheduledTask runTask(Runnable task) {
|
||||
return runTask(task, 0L);
|
||||
}
|
||||
|
||||
public static ScheduledTask runTaskAsync(Runnable task) {
|
||||
return runTaskAsync(task, 0L);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,92 @@
|
||||
package com.bgsoftware.wildloaders.utils;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.Objects;
|
||||
|
||||
public class BlockPosition {
|
||||
|
||||
private final String worldName;
|
||||
private final int x;
|
||||
private final int y;
|
||||
private final int z;
|
||||
private WeakReference<World> cachedWorld = new WeakReference<>(null);
|
||||
|
||||
public static BlockPosition of(Location location) {
|
||||
World world = location.getWorld();
|
||||
return new BlockPosition(world == null ? "null" : world.getName(),
|
||||
location.getBlockX(), location.getBlockY(), location.getBlockZ());
|
||||
}
|
||||
|
||||
public static BlockPosition deserialize(String serialized) {
|
||||
String[] locationSections = serialized.split(",");
|
||||
|
||||
if (locationSections.length != 4)
|
||||
throw new IllegalArgumentException("Cannot parse location " + serialized);
|
||||
|
||||
String worldName = locationSections[0];
|
||||
int x = (int) Double.parseDouble(locationSections[1]);
|
||||
int y = (int) Double.parseDouble(locationSections[2]);
|
||||
int z = (int) Double.parseDouble(locationSections[3]);
|
||||
|
||||
return new BlockPosition(worldName, x, y, z);
|
||||
}
|
||||
|
||||
public BlockPosition(String worldName, int x, int y, int z) {
|
||||
this.worldName = worldName;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
public String getWorldName() {
|
||||
return worldName;
|
||||
}
|
||||
|
||||
public World getWorld() {
|
||||
World cachedWorld = this.cachedWorld.get();
|
||||
if (cachedWorld == null) {
|
||||
cachedWorld = Bukkit.getWorld(this.worldName);
|
||||
this.cachedWorld = new WeakReference<>(cachedWorld);
|
||||
}
|
||||
|
||||
return cachedWorld;
|
||||
}
|
||||
|
||||
public Location getLocation() {
|
||||
return new Location(getWorld(), this.x, this.y, this.z);
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public int getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
public String serialize() {
|
||||
return this.worldName + "," + this.x + "," + this.y + "," + this.z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
BlockPosition that = (BlockPosition) o;
|
||||
return x == that.x && y == that.y && z == that.z && Objects.equals(worldName, that.worldName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(worldName, x, y, z);
|
||||
}
|
||||
|
||||
}
|
@ -17,7 +17,8 @@ public enum ServerVersion {
|
||||
v1_17(117),
|
||||
v1_18(118),
|
||||
v1_19(119),
|
||||
v1_20(120);
|
||||
v1_20(120),
|
||||
v1_21(121);
|
||||
|
||||
private static final ServerVersion currentVersion;
|
||||
private static final String bukkitVersion;
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.bgsoftware.wildloaders.utils.database;
|
||||
|
||||
import com.bgsoftware.wildloaders.utils.BlockPosition;
|
||||
import org.bukkit.Location;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
@ -12,7 +13,7 @@ public final class QueryParameters {
|
||||
private final Query query;
|
||||
private final List<Object> parameters;
|
||||
|
||||
public QueryParameters(Query query){
|
||||
public QueryParameters(Query query) {
|
||||
this.query = query;
|
||||
this.parameters = new ArrayList<>(query.getParametersCount());
|
||||
}
|
||||
@ -22,20 +23,24 @@ public final class QueryParameters {
|
||||
}
|
||||
|
||||
public void executeQuery(PreparedStatement preparedStatement) throws SQLException {
|
||||
for(int i = 0; i < parameters.size(); i++)
|
||||
for (int i = 0; i < parameters.size(); i++)
|
||||
preparedStatement.setObject(i + 1, parameters.get(i));
|
||||
}
|
||||
|
||||
public void queue(Object caller){
|
||||
public void queue(Object caller) {
|
||||
DatabaseQueue.queue(caller, this);
|
||||
}
|
||||
|
||||
public QueryParameters setLocation(Location loc){
|
||||
public QueryParameters setLocation(Location loc) {
|
||||
return setObject(loc.getWorld().getName() + "," + loc.getBlockX() + "," + loc.getBlockY() + "," + loc.getBlockZ());
|
||||
}
|
||||
|
||||
public QueryParameters setObject(Object object){
|
||||
if(object instanceof Location)
|
||||
public QueryParameters setLocation(BlockPosition blockPos) {
|
||||
return setObject(blockPos.getWorldName() + "," + blockPos.getX() + "," + blockPos.getY() + "," + blockPos.getZ());
|
||||
}
|
||||
|
||||
public QueryParameters setObject(Object object) {
|
||||
if (object instanceof Location)
|
||||
return setLocation((Location) object);
|
||||
|
||||
parameters.add(object);
|
||||
|
@ -1,41 +0,0 @@
|
||||
package com.bgsoftware.wildloaders.utils.locations;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
|
||||
public final class LocationUtils {
|
||||
|
||||
private LocationUtils(){}
|
||||
|
||||
public static String getLocation(Location location){
|
||||
try {
|
||||
return location.getWorld().getName() + "," + location.getBlockX() + "," + location.getBlockY() + "," + location.getBlockZ();
|
||||
}catch (Exception ex){
|
||||
System.out.println(location);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
public static Location getLocation(String location){
|
||||
String[] locationSections = location.split(",");
|
||||
|
||||
if(locationSections.length != 4)
|
||||
throw new IllegalArgumentException("Cannot parse location " + location);
|
||||
|
||||
String worldName = locationSections[0];
|
||||
double x = parseDouble(locationSections[1]);
|
||||
double y = parseDouble(locationSections[2]);
|
||||
double z = parseDouble(locationSections[3]);
|
||||
|
||||
return new Location(Bukkit.getWorld(worldName), x, y, z);
|
||||
}
|
||||
|
||||
private static double parseDouble(String str){
|
||||
try{
|
||||
return Double.parseDouble(str);
|
||||
}catch (Exception ex){
|
||||
throw new IllegalArgumentException("Cannot parse double " + str);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
package com.bgsoftware.wildloaders.utils.threads;
|
||||
|
||||
import com.bgsoftware.wildloaders.WildLoadersPlugin;
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public final class Executor {
|
||||
|
||||
private static final ExecutorService dataService = Executors.newFixedThreadPool(3, new ThreadFactoryBuilder().setNameFormat("WildChests DB Thread - #%d").build());
|
||||
private static final WildLoadersPlugin plugin = WildLoadersPlugin.getPlugin();
|
||||
private static boolean shutdown = false;
|
||||
|
||||
private Executor() {}
|
||||
|
||||
public static void sync(Runnable runnable){
|
||||
if(shutdown)
|
||||
return;
|
||||
|
||||
sync(runnable, 0L);
|
||||
}
|
||||
|
||||
public static void sync(Runnable runnable, long delay){
|
||||
if(shutdown)
|
||||
return;
|
||||
|
||||
Bukkit.getScheduler().runTaskLater(plugin, runnable, delay);
|
||||
}
|
||||
|
||||
public static void async(Runnable runnable){
|
||||
if(shutdown)
|
||||
return;
|
||||
|
||||
if(Bukkit.isPrimaryThread()){
|
||||
Bukkit.getScheduler().runTaskAsynchronously(plugin, runnable);
|
||||
}
|
||||
else{
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
|
||||
public static void async(Runnable runnable, long delay){
|
||||
if(shutdown)
|
||||
return;
|
||||
|
||||
if(Bukkit.isPrimaryThread()){
|
||||
Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, runnable, delay);
|
||||
}
|
||||
else{
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
|
||||
public static void data(Runnable runnable){
|
||||
if(shutdown)
|
||||
return;
|
||||
|
||||
dataService.execute(runnable);
|
||||
}
|
||||
|
||||
public static void stop(){
|
||||
try{
|
||||
shutdown = true;
|
||||
dataService.shutdown();
|
||||
dataService.awaitTermination(1, TimeUnit.MINUTES);
|
||||
}catch (Exception ex){
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -6,6 +6,7 @@ description: Highly configurable and optimized chunk-loaders plugin.
|
||||
website: https://bg-software.com/
|
||||
api-version: 1.13
|
||||
author: Ome_R
|
||||
folia-supported: true
|
||||
|
||||
# Custom section used by DependenciesManager, which replaces softdepend.
|
||||
class-depends:
|
||||
|
Loading…
Reference in New Issue
Block a user