mirror of
https://github.com/IntellectualSites/PlotSquared.git
synced 2024-11-22 13:16:45 +01:00
Merge branch 'v6' into feature/v6/json. It builds!
# Conflicts: # Bukkit/build.gradle # Bukkit/src/main/java/com/plotsquared/bukkit/BukkitPlatform.java # Bukkit/src/main/java/com/plotsquared/bukkit/generator/DelegatePlotGenerator.java # Bukkit/src/main/java/com/plotsquared/bukkit/inject/BukkitModule.java # Bukkit/src/main/java/com/plotsquared/bukkit/listener/PlayerEvents.java # Bukkit/src/main/java/com/plotsquared/bukkit/queue/ChunkCoordinator.java # Bukkit/src/main/java/com/plotsquared/bukkit/queue/GenChunk.java # Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitUtil.java # Core/src/main/java/com/plotsquared/core/PlotSquared.java # Core/src/main/java/com/plotsquared/core/command/Area.java # Core/src/main/java/com/plotsquared/core/command/Clear.java # Core/src/main/java/com/plotsquared/core/command/Debug.java # Core/src/main/java/com/plotsquared/core/command/DebugRoadRegen.java # Core/src/main/java/com/plotsquared/core/command/Relight.java # Core/src/main/java/com/plotsquared/core/command/Set.java # Core/src/main/java/com/plotsquared/core/command/Template.java # Core/src/main/java/com/plotsquared/core/command/Trim.java # Core/src/main/java/com/plotsquared/core/components/ComponentPresetManager.java # Core/src/main/java/com/plotsquared/core/generator/ClassicPlotManager.java # Core/src/main/java/com/plotsquared/core/generator/HybridPlotManager.java # Core/src/main/java/com/plotsquared/core/plot/Plot.java # Core/src/main/java/com/plotsquared/core/plot/flag/GlobalFlagContainer.java # Core/src/main/java/com/plotsquared/core/queue/AreaBoundDelegateQueueCoordinator.java # Core/src/main/java/com/plotsquared/core/queue/ChunkQueueCoordinator.java # Core/src/main/java/com/plotsquared/core/queue/LocalBlockQueue.java # Core/src/main/java/com/plotsquared/core/util/ChunkUtil.java # Core/src/main/java/com/plotsquared/core/util/EntityUtil.java # Core/src/main/java/com/plotsquared/core/util/RegionManager.java # Core/src/main/java/com/plotsquared/core/util/WorldUtil.java # Core/src/main/java/com/plotsquared/core/uuid/UUIDPipeline.java # build.gradle
This commit is contained in:
commit
7bad242944
@ -2,6 +2,7 @@ plugins {
|
|||||||
id "com.github.johnrengelman.shadow"
|
id "com.github.johnrengelman.shadow"
|
||||||
}
|
}
|
||||||
repositories {
|
repositories {
|
||||||
|
mavenLocal()
|
||||||
maven { url = "https://hub.spigotmc.org/nexus/content/repositories/snapshots/" }
|
maven { url = "https://hub.spigotmc.org/nexus/content/repositories/snapshots/" }
|
||||||
maven { url = "https://oss.sonatype.org/content/repositories/snapshots/" }
|
maven { url = "https://oss.sonatype.org/content/repositories/snapshots/" }
|
||||||
maven { url = "https://jitpack.io" }
|
maven { url = "https://jitpack.io" }
|
||||||
@ -15,7 +16,7 @@ repositories {
|
|||||||
maven { url = "https://mvn.intellectualsites.com/content/repositories/snapshots" }
|
maven { url = "https://mvn.intellectualsites.com/content/repositories/snapshots" }
|
||||||
maven { url = "https://repo.wea-ondara.net/repository/public/" }
|
maven { url = "https://repo.wea-ondara.net/repository/public/" }
|
||||||
maven { url = "https://oss.sonatype.org/content/repositories/snapshots/" }
|
maven { url = "https://oss.sonatype.org/content/repositories/snapshots/" }
|
||||||
mavenLocal()
|
maven { url = "http://repo.mvdw-software.be/content/groups/public/" }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -25,7 +26,7 @@ dependencies {
|
|||||||
compile(project(":PlotSquared-Core"))
|
compile(project(":PlotSquared-Core"))
|
||||||
compile("com.destroystokyo.paper:paper-api:1.16.1-R0.1-SNAPSHOT")
|
compile("com.destroystokyo.paper:paper-api:1.16.1-R0.1-SNAPSHOT")
|
||||||
implementation("org.spigotmc:spigot-api:1.16.1-R0.1-SNAPSHOT")
|
implementation("org.spigotmc:spigot-api:1.16.1-R0.1-SNAPSHOT")
|
||||||
compile(group: "com.sk89q.worldedit", name: "worldedit-bukkit", version: "7.1.0") {
|
compile(group: "com.sk89q.worldedit", name: "worldedit-bukkit", version: "7.2.0-SNAPSHOT") {
|
||||||
exclude(module: "bukkit")
|
exclude(module: "bukkit")
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -44,8 +45,10 @@ dependencies {
|
|||||||
implementation('net.kyori:adventure-text-minimessage:3.0.0-SNAPSHOT')
|
implementation('net.kyori:adventure-text-minimessage:3.0.0-SNAPSHOT')
|
||||||
compile("se.hyperver.hyperverse:Core:0.6.0-SNAPSHOT"){ transitive = false }
|
compile("se.hyperver.hyperverse:Core:0.6.0-SNAPSHOT"){ transitive = false }
|
||||||
compile('com.sk89q:squirrelid:1.0.0-SNAPSHOT'){ transitive = false }
|
compile('com.sk89q:squirrelid:1.0.0-SNAPSHOT'){ transitive = false }
|
||||||
|
compile('be.maximvdw:MVdWPlaceholderAPI:2.1.1-SNAPSHOT'){ transitive = false }
|
||||||
// logging
|
// logging
|
||||||
implementation('org.apache.logging.log4j:log4j-slf4j-impl:2.8.1')
|
implementation('org.apache.logging.log4j:log4j-slf4j-impl:2.8.1')
|
||||||
|
compile('be.maximvdw:MVdWPlaceholderAPI:3.1.1-SNAPSHOT'){ transitive = false }
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceCompatibility = 1.8
|
sourceCompatibility = 1.8
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.plotsquared</groupId>
|
<groupId>com.plotsquared</groupId>
|
||||||
<artifactId>PlotSquared-Core</artifactId>
|
<artifactId>PlotSquared-Core</artifactId>
|
||||||
<version>5.12.5</version>
|
<version>6.0.0-SUPER-SNAPSHOT</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -39,7 +39,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.sk89q.worldedit</groupId>
|
<groupId>com.sk89q.worldedit</groupId>
|
||||||
<artifactId>worldedit-bukkit</artifactId>
|
<artifactId>worldedit-bukkit</artifactId>
|
||||||
<version>7.1.0</version>
|
<version>7.2.0-SNAPSHOT</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
@ -90,10 +90,22 @@
|
|||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>be.maximvdw</groupId>
|
||||||
|
<artifactId>MVdWPlaceholderAPI</artifactId>
|
||||||
|
<version>3.1.1-SNAPSHOT</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<artifactId>*</artifactId>
|
||||||
|
<groupId>*</groupId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.sk89q.worldedit</groupId>
|
<groupId>com.sk89q.worldedit</groupId>
|
||||||
<artifactId>worldedit-core</artifactId>
|
<artifactId>worldedit-core</artifactId>
|
||||||
<version>7.0.0</version>
|
<version>7.2.0-SNAPSHOT</version>
|
||||||
<scope>runtime</scope>
|
<scope>runtime</scope>
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
@ -110,30 +122,6 @@
|
|||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>net.kyori</groupId>
|
|
||||||
<artifactId>text-api</artifactId>
|
|
||||||
<version>3.0.2</version>
|
|
||||||
<scope>runtime</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>net.kyori</groupId>
|
|
||||||
<artifactId>text-serializer-gson</artifactId>
|
|
||||||
<version>3.0.2</version>
|
|
||||||
<scope>runtime</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>net.kyori</groupId>
|
|
||||||
<artifactId>text-serializer-legacy</artifactId>
|
|
||||||
<version>3.0.2</version>
|
|
||||||
<scope>runtime</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>net.kyori</groupId>
|
|
||||||
<artifactId>text-serializer-plain</artifactId>
|
|
||||||
<version>3.0.2</version>
|
|
||||||
<scope>runtime</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.guava</groupId>
|
<groupId>com.google.guava</groupId>
|
||||||
<artifactId>guava</artifactId>
|
<artifactId>guava</artifactId>
|
||||||
@ -182,6 +170,18 @@
|
|||||||
<version>4.0-dev-106</version>
|
<version>4.0-dev-106</version>
|
||||||
<scope>runtime</scope>
|
<scope>runtime</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.kyori</groupId>
|
||||||
|
<artifactId>adventure-platform-bukkit</artifactId>
|
||||||
|
<version>4.0.0-SNAPSHOT</version>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.kyori</groupId>
|
||||||
|
<artifactId>adventure-text-minimessage</artifactId>
|
||||||
|
<version>3.0.0-SNAPSHOT</version>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.logging.log4j</groupId>
|
<groupId>org.apache.logging.log4j</groupId>
|
||||||
<artifactId>log4j-slf4j-impl</artifactId>
|
<artifactId>log4j-slf4j-impl</artifactId>
|
||||||
|
@ -36,15 +36,19 @@ import com.plotsquared.bukkit.inject.BackupModule;
|
|||||||
import com.plotsquared.bukkit.inject.BukkitModule;
|
import com.plotsquared.bukkit.inject.BukkitModule;
|
||||||
import com.plotsquared.bukkit.inject.PermissionModule;
|
import com.plotsquared.bukkit.inject.PermissionModule;
|
||||||
import com.plotsquared.bukkit.inject.WorldManagerModule;
|
import com.plotsquared.bukkit.inject.WorldManagerModule;
|
||||||
|
import com.plotsquared.bukkit.listener.BlockEventListener;
|
||||||
import com.plotsquared.bukkit.listener.ChunkListener;
|
import com.plotsquared.bukkit.listener.ChunkListener;
|
||||||
|
import com.plotsquared.bukkit.listener.EntityEventListener;
|
||||||
import com.plotsquared.bukkit.listener.EntitySpawnListener;
|
import com.plotsquared.bukkit.listener.EntitySpawnListener;
|
||||||
import com.plotsquared.bukkit.listener.PaperListener;
|
import com.plotsquared.bukkit.listener.PaperListener;
|
||||||
import com.plotsquared.bukkit.listener.PlayerEvents;
|
import com.plotsquared.bukkit.listener.PlayerEventListener;
|
||||||
|
import com.plotsquared.bukkit.listener.ProjectileEventListener;
|
||||||
|
import com.plotsquared.bukkit.listener.ServerListener;
|
||||||
import com.plotsquared.bukkit.listener.SingleWorldListener;
|
import com.plotsquared.bukkit.listener.SingleWorldListener;
|
||||||
import com.plotsquared.bukkit.listener.WorldEvents;
|
import com.plotsquared.bukkit.listener.WorldEvents;
|
||||||
import com.plotsquared.bukkit.placeholder.PlaceholderFormatter;
|
import com.plotsquared.bukkit.placeholder.PlaceholderFormatter;
|
||||||
import com.plotsquared.bukkit.placeholder.Placeholders;
|
|
||||||
import com.plotsquared.bukkit.player.BukkitPlayer;
|
import com.plotsquared.bukkit.player.BukkitPlayer;
|
||||||
|
import com.plotsquared.bukkit.placeholder.PAPIPlaceholders;
|
||||||
import com.plotsquared.bukkit.player.BukkitPlayerManager;
|
import com.plotsquared.bukkit.player.BukkitPlayerManager;
|
||||||
import com.plotsquared.bukkit.util.task.BukkitTaskManager;
|
import com.plotsquared.bukkit.util.task.BukkitTaskManager;
|
||||||
import com.plotsquared.bukkit.util.BukkitUtil;
|
import com.plotsquared.bukkit.util.BukkitUtil;
|
||||||
@ -94,7 +98,6 @@ import com.plotsquared.core.plot.flag.implementations.ServerPlotFlag;
|
|||||||
import com.plotsquared.core.plot.world.PlotAreaManager;
|
import com.plotsquared.core.plot.world.PlotAreaManager;
|
||||||
import com.plotsquared.core.plot.world.SinglePlotArea;
|
import com.plotsquared.core.plot.world.SinglePlotArea;
|
||||||
import com.plotsquared.core.plot.world.SinglePlotAreaManager;
|
import com.plotsquared.core.plot.world.SinglePlotAreaManager;
|
||||||
import com.plotsquared.core.queue.GlobalBlockQueue;
|
|
||||||
import com.plotsquared.core.setup.PlotAreaBuilder;
|
import com.plotsquared.core.setup.PlotAreaBuilder;
|
||||||
import com.plotsquared.core.setup.SettingsNodesWrapper;
|
import com.plotsquared.core.setup.SettingsNodesWrapper;
|
||||||
import com.plotsquared.core.util.ConsoleColors;
|
import com.plotsquared.core.util.ConsoleColors;
|
||||||
@ -160,7 +163,8 @@ import static com.plotsquared.core.util.PremiumVerification.getResourceID;
|
|||||||
import static com.plotsquared.core.util.PremiumVerification.getUserID;
|
import static com.plotsquared.core.util.PremiumVerification.getUserID;
|
||||||
import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
|
import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
|
||||||
|
|
||||||
@SuppressWarnings("unused") public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPlatform<Player> {
|
@SuppressWarnings("unused")
|
||||||
|
public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPlatform<Player> {
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger("P2/" + BukkitPlatform.class.getSimpleName());
|
private static final Logger logger = LoggerFactory.getLogger("P2/" + BukkitPlatform.class.getSimpleName());
|
||||||
private static final int BSTATS_ID = 1404;
|
private static final int BSTATS_ID = 1404;
|
||||||
@ -233,10 +237,8 @@ import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
|
|||||||
final PlotSquared plotSquared = new PlotSquared(this, "Bukkit");
|
final PlotSquared plotSquared = new PlotSquared(this, "Bukkit");
|
||||||
|
|
||||||
if (PlotSquared.platform().getServerVersion()[1] < 13) {
|
if (PlotSquared.platform().getServerVersion()[1] < 13) {
|
||||||
System.out.println(
|
System.out.println("You can't use this version of PlotSquared on a server less than Minecraft 1.13.2.");
|
||||||
"You can't use this version of PlotSquared on a server less than Minecraft 1.13.2.");
|
System.out.println("Please check the download page for the link to the legacy versions.");
|
||||||
System.out
|
|
||||||
.println("Please check the download page for the link to the legacy versions.");
|
|
||||||
System.out.println("The server will now be shutdown to prevent any corruption.");
|
System.out.println("The server will now be shutdown to prevent any corruption.");
|
||||||
Bukkit.shutdown();
|
Bukkit.shutdown();
|
||||||
return;
|
return;
|
||||||
@ -244,10 +246,8 @@ import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
|
|||||||
|
|
||||||
// We create the injector after PlotSquared has been initialized, so that we have access
|
// We create the injector after PlotSquared has been initialized, so that we have access
|
||||||
// to generated instances and settings
|
// to generated instances and settings
|
||||||
this.injector = Guice.createInjector(Stage.PRODUCTION, new PermissionModule(),
|
this.injector = Guice
|
||||||
new WorldManagerModule(),
|
.createInjector(Stage.PRODUCTION, new PermissionModule(), new WorldManagerModule(), new PlotSquaredModule(), new BukkitModule(this),
|
||||||
new PlotSquaredModule(),
|
|
||||||
new BukkitModule(this),
|
|
||||||
new BackupModule());
|
new BackupModule());
|
||||||
this.injector.injectMembers(this);
|
this.injector.injectMembers(this);
|
||||||
|
|
||||||
@ -292,8 +292,7 @@ import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
|
|||||||
|
|
||||||
// Do stuff that was previously done in PlotSquared
|
// Do stuff that was previously done in PlotSquared
|
||||||
// Kill entities
|
// Kill entities
|
||||||
if (Settings.Enabled_Components.KILL_ROAD_MOBS
|
if (Settings.Enabled_Components.KILL_ROAD_MOBS || Settings.Enabled_Components.KILL_ROAD_VEHICLES) {
|
||||||
|| Settings.Enabled_Components.KILL_ROAD_VEHICLES) {
|
|
||||||
this.runEntityTask();
|
this.runEntityTask();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,7 +310,11 @@ import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Settings.Enabled_Components.EVENTS) {
|
if (Settings.Enabled_Components.EVENTS) {
|
||||||
getServer().getPluginManager().registerEvents(getInjector().getInstance(PlayerEvents.class), this);
|
getServer().getPluginManager().registerEvents(getInjector().getInstance(PlayerEventListener.class), this);
|
||||||
|
getServer().getPluginManager().registerEvents(getInjector().getInstance(BlockEventListener.class), this);
|
||||||
|
getServer().getPluginManager().registerEvents(getInjector().getInstance(EntityEventListener.class), this);
|
||||||
|
getServer().getPluginManager().registerEvents(getInjector().getInstance(ProjectileEventListener.class), this);
|
||||||
|
getServer().getPluginManager().registerEvents(getInjector().getInstance(ServerListener.class), this);
|
||||||
getServer().getPluginManager().registerEvents(getInjector().getInstance(EntitySpawnListener.class), this);
|
getServer().getPluginManager().registerEvents(getInjector().getInstance(EntitySpawnListener.class), this);
|
||||||
if (PaperLib.isPaper() && Settings.Paper_Components.PAPER_LISTENERS) {
|
if (PaperLib.isPaper() && Settings.Paper_Components.PAPER_LISTENERS) {
|
||||||
getServer().getPluginManager().registerEvents(getInjector().getInstance(PaperListener.class), this);
|
getServer().getPluginManager().registerEvents(getInjector().getInstance(PaperListener.class), this);
|
||||||
@ -325,10 +328,6 @@ import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
|
|||||||
getServer().getPluginManager().registerEvents(getInjector().getInstance(ChunkListener.class), this);
|
getServer().getPluginManager().registerEvents(getInjector().getInstance(ChunkListener.class), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start the global block queue
|
|
||||||
final GlobalBlockQueue globalBlockQueue = this.injector.getInstance(GlobalBlockQueue.class);
|
|
||||||
globalBlockQueue.runTask();
|
|
||||||
|
|
||||||
// Commands
|
// Commands
|
||||||
if (Settings.Enabled_Components.COMMANDS) {
|
if (Settings.Enabled_Components.COMMANDS) {
|
||||||
this.registerCommands();
|
this.registerCommands();
|
||||||
@ -372,9 +371,9 @@ import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!worldUtil.isWorld(world) && !world.equals("*")) {
|
if (!worldUtil.isWorld(world) && !world.equals("*")) {
|
||||||
logger.warn("[P2] `{}` was not properly loaded - {} will now try to load it properly",
|
logger.warn("[P2] `{}` was not properly loaded - {} will now try to load it properly", world, this.getPluginName());
|
||||||
world, this.getPluginName());
|
logger.warn(
|
||||||
logger.warn("[P2] - Are you trying to delete this world? Remember to remove it from the worlds.yml, bukkit.yml and multiverse worlds.yml");
|
"[P2] - Are you trying to delete this world? Remember to remove it from the worlds.yml, bukkit.yml and multiverse worlds.yml");
|
||||||
logger.warn("[P2] - Your world management plugin may be faulty (or non existent)");
|
logger.warn("[P2] - Your world management plugin may be faulty (or non existent)");
|
||||||
logger.warn("[P2] This message may also be a false positive and could be ignored.");
|
logger.warn("[P2] This message may also be a false positive and could be ignored.");
|
||||||
this.setGenerator(world);
|
this.setGenerator(world);
|
||||||
@ -408,16 +407,14 @@ import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
|
|||||||
final SQLiteUUIDService sqLiteUUIDService = new SQLiteUUIDService("user_cache.db");
|
final SQLiteUUIDService sqLiteUUIDService = new SQLiteUUIDService("user_cache.db");
|
||||||
|
|
||||||
final SQLiteUUIDService legacyUUIDService;
|
final SQLiteUUIDService legacyUUIDService;
|
||||||
if (Settings.UUID.LEGACY_DATABASE_SUPPORT &&
|
if (Settings.UUID.LEGACY_DATABASE_SUPPORT && FileUtils.getFile(PlotSquared.platform().getDirectory(), "usercache.db").exists()) {
|
||||||
FileUtils.getFile(PlotSquared.platform().getDirectory(), "usercache.db").exists()) {
|
|
||||||
legacyUUIDService = new SQLiteUUIDService("usercache.db");
|
legacyUUIDService = new SQLiteUUIDService("usercache.db");
|
||||||
} else {
|
} else {
|
||||||
legacyUUIDService = null;
|
legacyUUIDService = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final LuckPermsUUIDService luckPermsUUIDService;
|
final LuckPermsUUIDService luckPermsUUIDService;
|
||||||
if (Settings.UUID.SERVICE_LUCKPERMS &&
|
if (Settings.UUID.SERVICE_LUCKPERMS && Bukkit.getPluginManager().getPlugin("LuckPerms") != null) {
|
||||||
Bukkit.getPluginManager().getPlugin("LuckPerms") != null) {
|
|
||||||
luckPermsUUIDService = new LuckPermsUUIDService();
|
luckPermsUUIDService = new LuckPermsUUIDService();
|
||||||
logger.info("[P2] (UUID) Using LuckPerms as a complementary UUID service");
|
logger.info("[P2] (UUID) Using LuckPerms as a complementary UUID service");
|
||||||
} else {
|
} else {
|
||||||
@ -425,8 +422,7 @@ import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
|
|||||||
}
|
}
|
||||||
|
|
||||||
final BungeePermsUUIDService bungeePermsUUIDService;
|
final BungeePermsUUIDService bungeePermsUUIDService;
|
||||||
if (Settings.UUID.SERVICE_BUNGEE_PERMS &&
|
if (Settings.UUID.SERVICE_BUNGEE_PERMS && Bukkit.getPluginManager().getPlugin("BungeePerms") != null) {
|
||||||
Bukkit.getPluginManager().getPlugin("BungeePerms") != null) {
|
|
||||||
bungeePermsUUIDService = new BungeePermsUUIDService();
|
bungeePermsUUIDService = new BungeePermsUUIDService();
|
||||||
logger.info("[P2] (UUID) Using BungeePerms as a complementary UUID service");
|
logger.info("[P2] (UUID) Using BungeePerms as a complementary UUID service");
|
||||||
} else {
|
} else {
|
||||||
@ -474,11 +470,9 @@ import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
|
|||||||
this.backgroundPipeline.registerService(essentialsUUIDService);
|
this.backgroundPipeline.registerService(essentialsUUIDService);
|
||||||
}
|
}
|
||||||
|
|
||||||
final SquirrelIdUUIDService impromptuMojangService =
|
final SquirrelIdUUIDService impromptuMojangService = new SquirrelIdUUIDService(Settings.UUID.IMPROMPTU_LIMIT);
|
||||||
new SquirrelIdUUIDService(Settings.UUID.IMPROMPTU_LIMIT);
|
|
||||||
this.impromptuPipeline.registerService(impromptuMojangService);
|
this.impromptuPipeline.registerService(impromptuMojangService);
|
||||||
final SquirrelIdUUIDService backgroundMojangService =
|
final SquirrelIdUUIDService backgroundMojangService = new SquirrelIdUUIDService(Settings.UUID.BACKGROUND_LIMIT);
|
||||||
new SquirrelIdUUIDService(Settings.UUID.BACKGROUND_LIMIT);
|
|
||||||
this.backgroundPipeline.registerService(backgroundMojangService);
|
this.backgroundPipeline.registerService(backgroundMojangService);
|
||||||
} else {
|
} else {
|
||||||
this.impromptuPipeline.registerService(sqLiteUUIDService);
|
this.impromptuPipeline.registerService(sqLiteUUIDService);
|
||||||
@ -499,7 +493,7 @@ import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) {
|
if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) {
|
||||||
injector.getInstance(Placeholders.class).register();
|
injector.getInstance(PAPIPlaceholders.class).register();
|
||||||
if (Settings.Enabled_Components.EXTERNAL_PLACEHOLDERS) {
|
if (Settings.Enabled_Components.EXTERNAL_PLACEHOLDERS) {
|
||||||
ChatFormatter.formatters.add(getInjector().getInstance(PlaceholderFormatter.class));
|
ChatFormatter.formatters.add(getInjector().getInstance(PlaceholderFormatter.class));
|
||||||
}
|
}
|
||||||
@ -537,8 +531,7 @@ import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
|
|||||||
this.methodUnloadSetup = true;
|
this.methodUnloadSetup = true;
|
||||||
try {
|
try {
|
||||||
ReflectionUtils.RefClass classCraftWorld = getRefClass("{cb}.CraftWorld");
|
ReflectionUtils.RefClass classCraftWorld = getRefClass("{cb}.CraftWorld");
|
||||||
this.methodUnloadChunk0 = classCraftWorld.getRealClass()
|
this.methodUnloadChunk0 = classCraftWorld.getRealClass().getDeclaredMethod("unloadChunk0", int.class, int.class, boolean.class);
|
||||||
.getDeclaredMethod("unloadChunk0", int.class, int.class, boolean.class);
|
|
||||||
this.methodUnloadChunk0.setAccessible(true);
|
this.methodUnloadChunk0.setAccessible(true);
|
||||||
} catch (Throwable event) {
|
} catch (Throwable event) {
|
||||||
event.printStackTrace();
|
event.printStackTrace();
|
||||||
@ -569,8 +562,7 @@ import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
|
|||||||
}
|
}
|
||||||
final Plot plot = area.getOwnedPlot(id);
|
final Plot plot = area.getOwnedPlot(id);
|
||||||
if (plot != null) {
|
if (plot != null) {
|
||||||
if (!plot.getFlag(ServerPlotFlag.class) || PlotSquared.platform().getPlayerManager()
|
if (!plot.getFlag(ServerPlotFlag.class) || PlotSquared.platform().getPlayerManager().getPlayerIfExists(plot.getOwner()) == null) {
|
||||||
.getPlayerIfExists(plot.getOwner()) == null) {
|
|
||||||
if (world.getKeepSpawnInMemory()) {
|
if (world.getKeepSpawnInMemory()) {
|
||||||
world.setKeepSpawnInMemory(false);
|
world.setKeepSpawnInMemory(false);
|
||||||
return;
|
return;
|
||||||
@ -588,8 +580,7 @@ import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
|
|||||||
boolean result;
|
boolean result;
|
||||||
if (methodUnloadChunk0 != null) {
|
if (methodUnloadChunk0 != null) {
|
||||||
try {
|
try {
|
||||||
result = (boolean) methodUnloadChunk0
|
result = (boolean) methodUnloadChunk0.invoke(world, chunkI.getX(), chunkI.getZ(), true);
|
||||||
.invoke(world, chunkI.getX(), chunkI.getZ(), true);
|
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
methodUnloadChunk0 = null;
|
methodUnloadChunk0 = null;
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@ -612,8 +603,7 @@ import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startUuidCaching(@Nonnull final SQLiteUUIDService sqLiteUUIDService,
|
private void startUuidCaching(@Nonnull final SQLiteUUIDService sqLiteUUIDService, @Nonnull final CacheUUIDService cacheUUIDService) {
|
||||||
@Nonnull final CacheUUIDService cacheUUIDService) {
|
|
||||||
// Load all uuids into a big chunky boi queue
|
// Load all uuids into a big chunky boi queue
|
||||||
final Queue<UUID> uuidQueue = new LinkedBlockingQueue<>();
|
final Queue<UUID> uuidQueue = new LinkedBlockingQueue<>();
|
||||||
PlotSquared.get().forEachPlotRaw(plot -> {
|
PlotSquared.get().forEachPlotRaw(plot -> {
|
||||||
@ -653,8 +643,7 @@ import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
|
|||||||
// fresh batch
|
// fresh batch
|
||||||
secondRun = false;
|
secondRun = false;
|
||||||
// Populate the request list
|
// Populate the request list
|
||||||
for (int i = 0;
|
for (int i = 0; i < Settings.UUID.BACKGROUND_LIMIT && !uuidQueue.isEmpty(); i++) {
|
||||||
i < Settings.UUID.BACKGROUND_LIMIT && !uuidQueue.isEmpty(); i++) {
|
|
||||||
uuidList.add(uuidQueue.poll());
|
uuidList.add(uuidQueue.poll());
|
||||||
read++;
|
read++;
|
||||||
}
|
}
|
||||||
@ -760,8 +749,7 @@ import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
|
|||||||
case "MINECART_TNT":
|
case "MINECART_TNT":
|
||||||
case "BOAT":
|
case "BOAT":
|
||||||
if (Settings.Enabled_Components.KILL_ROAD_VEHICLES) {
|
if (Settings.Enabled_Components.KILL_ROAD_VEHICLES) {
|
||||||
com.plotsquared.core.location.Location location =
|
com.plotsquared.core.location.Location location = BukkitUtil.adapt(entity.getLocation());
|
||||||
BukkitUtil.adapt(entity.getLocation());
|
|
||||||
Plot plot = location.getPlot();
|
Plot plot = location.getPlot();
|
||||||
if (plot == null) {
|
if (plot == null) {
|
||||||
if (location.isPlotArea()) {
|
if (location.isPlotArea()) {
|
||||||
@ -791,9 +779,8 @@ import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
|
|||||||
case "FIREBALL":
|
case "FIREBALL":
|
||||||
case "DRAGON_FIREBALL":
|
case "DRAGON_FIREBALL":
|
||||||
case "DROPPED_ITEM":
|
case "DROPPED_ITEM":
|
||||||
if (Settings.Enabled_Components.KILL_ROAD_ITEMS && plotArea
|
if (Settings.Enabled_Components.KILL_ROAD_ITEMS
|
||||||
.getOwnedPlotAbs(BukkitUtil.adapt(entity.getLocation()))
|
&& plotArea.getOwnedPlotAbs(BukkitUtil.adapt(entity.getLocation())) == null) {
|
||||||
== null) {
|
|
||||||
entity.remove();
|
entity.remove();
|
||||||
}
|
}
|
||||||
// dropped item
|
// dropped item
|
||||||
@ -817,14 +804,11 @@ import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
|
|||||||
|
|
||||||
PlotId originalPlotId = (PlotId) meta.get(0).value();
|
PlotId originalPlotId = (PlotId) meta.get(0).value();
|
||||||
if (originalPlotId != null) {
|
if (originalPlotId != null) {
|
||||||
com.plotsquared.core.location.Location pLoc =
|
com.plotsquared.core.location.Location pLoc = BukkitUtil.adapt(entity.getLocation());
|
||||||
BukkitUtil.adapt(entity.getLocation());
|
|
||||||
PlotArea area = pLoc.getPlotArea();
|
PlotArea area = pLoc.getPlotArea();
|
||||||
if (area != null) {
|
if (area != null) {
|
||||||
PlotId currentPlotId = area.getPlotAbs(pLoc).getId();
|
PlotId currentPlotId = area.getPlotAbs(pLoc).getId();
|
||||||
if (!originalPlotId.equals(currentPlotId) && (
|
if (!originalPlotId.equals(currentPlotId) && (currentPlotId == null || !area.getPlot(originalPlotId)
|
||||||
currentPlotId == null || !area
|
|
||||||
.getPlot(originalPlotId)
|
|
||||||
.equals(area.getPlot(currentPlotId)))) {
|
.equals(area.getPlot(currentPlotId)))) {
|
||||||
if (entity.hasMetadata("ps-tmp-teleport")) {
|
if (entity.hasMetadata("ps-tmp-teleport")) {
|
||||||
continue;
|
continue;
|
||||||
@ -836,15 +820,12 @@ import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//This is to apply the metadata to already spawned shulkers (see EntitySpawnListener.java)
|
//This is to apply the metadata to already spawned shulkers (see EntitySpawnListener.java)
|
||||||
com.plotsquared.core.location.Location pLoc =
|
com.plotsquared.core.location.Location pLoc = BukkitUtil.adapt(entity.getLocation());
|
||||||
BukkitUtil.adapt(entity.getLocation());
|
|
||||||
PlotArea area = pLoc.getPlotArea();
|
PlotArea area = pLoc.getPlotArea();
|
||||||
if (area != null) {
|
if (area != null) {
|
||||||
PlotId currentPlotId = area.getPlotAbs(pLoc).getId();
|
PlotId currentPlotId = area.getPlotAbs(pLoc).getId();
|
||||||
if (currentPlotId != null) {
|
if (currentPlotId != null) {
|
||||||
entity.setMetadata("shulkerPlot",
|
entity.setMetadata("shulkerPlot", new FixedMetadataValue((Plugin) PlotSquared.platform(), currentPlotId));
|
||||||
new FixedMetadataValue(
|
|
||||||
(Plugin) PlotSquared.platform(), currentPlotId));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -925,11 +906,9 @@ import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
|
|||||||
if (BukkitUtil.adapt(location).isPlotRoad()) {
|
if (BukkitUtil.adapt(location).isPlotRoad()) {
|
||||||
if (entity instanceof LivingEntity) {
|
if (entity instanceof LivingEntity) {
|
||||||
LivingEntity livingEntity = (LivingEntity) entity;
|
LivingEntity livingEntity = (LivingEntity) entity;
|
||||||
if (!livingEntity.isLeashed() || !entity
|
if (!livingEntity.isLeashed() || !entity.hasMetadata("keep")) {
|
||||||
.hasMetadata("keep")) {
|
|
||||||
Entity passenger = entity.getPassenger();
|
Entity passenger = entity.getPassenger();
|
||||||
if (!(passenger instanceof Player) && entity
|
if (!(passenger instanceof Player) && entity.getMetadata("keep").isEmpty()) {
|
||||||
.getMetadata("keep").isEmpty()) {
|
|
||||||
if (entity.hasMetadata("ps-tmp-teleport")) {
|
if (entity.hasMetadata("ps-tmp-teleport")) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -940,8 +919,7 @@ import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Entity passenger = entity.getPassenger();
|
Entity passenger = entity.getPassenger();
|
||||||
if (!(passenger instanceof Player) && entity
|
if (!(passenger instanceof Player) && entity.getMetadata("keep").isEmpty()) {
|
||||||
.getMetadata("keep").isEmpty()) {
|
|
||||||
if (entity.hasMetadata("ps-tmp-teleport")) {
|
if (entity.hasMetadata("ps-tmp-teleport")) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -962,9 +940,7 @@ import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
|
|||||||
}), TaskTime.seconds(1L));
|
}), TaskTime.seconds(1L));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override @Nullable
|
@Override @Nullable public final ChunkGenerator getDefaultWorldGenerator(@Nonnull final String worldName, final String id) {
|
||||||
public final ChunkGenerator getDefaultWorldGenerator(@Nonnull final String worldName,
|
|
||||||
final String id) {
|
|
||||||
final IndependentPlotGenerator result;
|
final IndependentPlotGenerator result;
|
||||||
if (id != null && id.equalsIgnoreCase("single")) {
|
if (id != null && id.equalsIgnoreCase("single")) {
|
||||||
result = getInjector().getInstance(SingleWorldGenerator.class);
|
result = getInjector().getInstance(SingleWorldGenerator.class);
|
||||||
@ -977,8 +953,7 @@ import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
|
|||||||
return (ChunkGenerator) result.specify(worldName);
|
return (ChunkGenerator) result.specify(worldName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override @Nullable public GeneratorWrapper<?> getGenerator(@Nonnull final String world,
|
@Override @Nullable public GeneratorWrapper<?> getGenerator(@Nonnull final String world, @Nullable final String name) {
|
||||||
@Nullable final String name) {
|
|
||||||
if (name == null) {
|
if (name == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -990,8 +965,8 @@ import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
|
|||||||
}
|
}
|
||||||
return new BukkitPlotGenerator(world, gen, this.plotAreaManager);
|
return new BukkitPlotGenerator(world, gen, this.plotAreaManager);
|
||||||
} else {
|
} else {
|
||||||
return new BukkitPlotGenerator(world, getInjector()
|
return new BukkitPlotGenerator(world, getInjector().getInstance(Key.get(IndependentPlotGenerator.class, DefaultGenerator.class)),
|
||||||
.getInstance(Key.get(IndependentPlotGenerator.class, DefaultGenerator.class)), this.plotAreaManager);
|
this.plotAreaManager);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1011,19 +986,14 @@ import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
|
|||||||
map.put(plotAreaType.name().toLowerCase(), terrainTypes);
|
map.put(plotAreaType.name().toLowerCase(), terrainTypes);
|
||||||
}
|
}
|
||||||
for (final PlotArea plotArea : this.plotAreaManager.getAllPlotAreas()) {
|
for (final PlotArea plotArea : this.plotAreaManager.getAllPlotAreas()) {
|
||||||
final Map<String, Integer> terrainTypeMap =
|
final Map<String, Integer> terrainTypeMap = map.get(plotArea.getType().name().toLowerCase());
|
||||||
map.get(plotArea.getType().name().toLowerCase());
|
terrainTypeMap.put(plotArea.getTerrain().name().toLowerCase(), terrainTypeMap.get(plotArea.getTerrain().name().toLowerCase()) + 1);
|
||||||
terrainTypeMap.put(plotArea.getTerrain().name().toLowerCase(),
|
|
||||||
terrainTypeMap.get(plotArea.getTerrain().name().toLowerCase()) + 1);
|
|
||||||
}
|
}
|
||||||
return map;
|
return map;
|
||||||
}));
|
}));
|
||||||
metrics.addCustomChart(new Metrics.SimplePie("premium",
|
metrics.addCustomChart(new Metrics.SimplePie("premium", () -> PremiumVerification.isPremium() ? "Premium" : "Non-Premium"));
|
||||||
() -> PremiumVerification.isPremium() ? "Premium" : "Non-Premium"));
|
|
||||||
metrics.addCustomChart(new Metrics.SimplePie("worldedit_implementation",
|
metrics.addCustomChart(new Metrics.SimplePie("worldedit_implementation",
|
||||||
() -> Bukkit.getPluginManager().getPlugin("FastAsyncWorldEdit") != null ?
|
() -> Bukkit.getPluginManager().getPlugin("FastAsyncWorldEdit") != null ? "FastAsyncWorldEdit" : "WorldEdit"));
|
||||||
"FastAsyncWorldEdit" :
|
|
||||||
"WorldEdit"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void unregister(@Nonnull final PlotPlayer<?> player) {
|
@Override public void unregister(@Nonnull final PlotPlayer<?> player) {
|
||||||
@ -1036,12 +1006,10 @@ import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
|
|||||||
// create world
|
// create world
|
||||||
ConfigurationSection worldConfig = this.worldConfiguration.getConfigurationSection("worlds." + worldName);
|
ConfigurationSection worldConfig = this.worldConfiguration.getConfigurationSection("worlds." + worldName);
|
||||||
String manager = worldConfig.getString("generator.plugin", getPluginName());
|
String manager = worldConfig.getString("generator.plugin", getPluginName());
|
||||||
PlotAreaBuilder builder = PlotAreaBuilder.newBuilder().plotManager(manager)
|
PlotAreaBuilder builder =
|
||||||
.generatorName(worldConfig.getString("generator.init", manager))
|
PlotAreaBuilder.newBuilder().plotManager(manager).generatorName(worldConfig.getString("generator.init", manager))
|
||||||
.plotAreaType(ConfigurationUtil.getType(worldConfig))
|
.plotAreaType(ConfigurationUtil.getType(worldConfig)).terrainType(ConfigurationUtil.getTerrain(worldConfig))
|
||||||
.terrainType(ConfigurationUtil.getTerrain(worldConfig))
|
.settingsNodesWrapper(new SettingsNodesWrapper(new ConfigurationNode[0], null)).worldName(worldName);
|
||||||
.settingsNodesWrapper(new SettingsNodesWrapper(new ConfigurationNode[0], null))
|
|
||||||
.worldName(worldName);
|
|
||||||
getInjector().getInstance(SetupUtils.class).setupWorld(builder);
|
getInjector().getInstance(SetupUtils.class).setupWorld(builder);
|
||||||
world = Bukkit.getWorld(worldName);
|
world = Bukkit.getWorld(worldName);
|
||||||
} else {
|
} else {
|
||||||
@ -1071,16 +1039,14 @@ import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
|
|||||||
return name.substring(name.lastIndexOf('.') + 1);
|
return name.substring(name.lastIndexOf('.') + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public GeneratorWrapper<?> wrapPlotGenerator(@Nullable final String world,
|
@Override public GeneratorWrapper<?> wrapPlotGenerator(@Nullable final String world, @Nonnull final IndependentPlotGenerator generator) {
|
||||||
@Nonnull final IndependentPlotGenerator generator) {
|
|
||||||
return new BukkitPlotGenerator(world, generator, this.plotAreaManager);
|
return new BukkitPlotGenerator(world, generator, this.plotAreaManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public List<Map.Entry<Map.Entry<String, String>, Boolean>> getPluginIds() {
|
@Override public List<Map.Entry<Map.Entry<String, String>, Boolean>> getPluginIds() {
|
||||||
List<Map.Entry<Map.Entry<String, String>, Boolean>> names = new ArrayList<>();
|
List<Map.Entry<Map.Entry<String, String>, Boolean>> names = new ArrayList<>();
|
||||||
for (final Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
|
for (final Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
|
||||||
Map.Entry<String, String> id = new AbstractMap.SimpleEntry<>(plugin.getName(),
|
Map.Entry<String, String> id = new AbstractMap.SimpleEntry<>(plugin.getName(), plugin.getDescription().getVersion());
|
||||||
plugin.getDescription().getVersion());
|
|
||||||
names.add(new AbstractMap.SimpleEntry<>(id, plugin.isEnabled()));
|
names.add(new AbstractMap.SimpleEntry<>(id, plugin.isEnabled()));
|
||||||
}
|
}
|
||||||
return names;
|
return names;
|
||||||
@ -1115,11 +1081,11 @@ import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override @Nonnull public PlatformWorldManager<?> getWorldManager() {
|
@Override @Nonnull public PlatformWorldManager<?> getWorldManager() {
|
||||||
return getInjector().getInstance(Key.get(new TypeLiteral<PlatformWorldManager<World>>() {}));
|
return getInjector().getInstance(Key.get(new TypeLiteral<PlatformWorldManager<World>>() {
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override @Nonnull @SuppressWarnings("ALL")
|
@Override @Nonnull @SuppressWarnings("ALL") public PlayerManager<? extends PlotPlayer<Player>, ? extends Player> getPlayerManager() {
|
||||||
public PlayerManager<? extends PlotPlayer<Player>, ? extends Player> getPlayerManager() {
|
|
||||||
return (PlayerManager<BukkitPlayer, Player>) getInjector().getInstance(PlayerManager.class);
|
return (PlayerManager<BukkitPlayer, Player>) getInjector().getInstance(PlayerManager.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,8 +30,9 @@ import com.plotsquared.core.generator.IndependentPlotGenerator;
|
|||||||
import com.plotsquared.core.location.ChunkWrapper;
|
import com.plotsquared.core.location.ChunkWrapper;
|
||||||
import com.plotsquared.core.plot.PlotArea;
|
import com.plotsquared.core.plot.PlotArea;
|
||||||
import com.plotsquared.core.plot.world.PlotAreaManager;
|
import com.plotsquared.core.plot.world.PlotAreaManager;
|
||||||
import com.plotsquared.core.queue.LocalBlockQueue;
|
import com.plotsquared.core.queue.QueueCoordinator;
|
||||||
import com.plotsquared.core.queue.ScopedLocalBlockQueue;
|
import com.plotsquared.core.queue.ScopedQueueCoordinator;
|
||||||
|
import com.sk89q.worldedit.bukkit.BukkitWorld;
|
||||||
import org.bukkit.Chunk;
|
import org.bukkit.Chunk;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.generator.BlockPopulator;
|
import org.bukkit.generator.BlockPopulator;
|
||||||
@ -44,30 +45,25 @@ final class BlockStatePopulator extends BlockPopulator {
|
|||||||
private final IndependentPlotGenerator plotGenerator;
|
private final IndependentPlotGenerator plotGenerator;
|
||||||
private final PlotAreaManager plotAreaManager;
|
private final PlotAreaManager plotAreaManager;
|
||||||
|
|
||||||
private LocalBlockQueue queue;
|
private QueueCoordinator queue;
|
||||||
|
|
||||||
public BlockStatePopulator(@Nonnull final IndependentPlotGenerator plotGenerator,
|
public BlockStatePopulator(@Nonnull final IndependentPlotGenerator plotGenerator, @Nonnull final PlotAreaManager plotAreaManager) {
|
||||||
@Nonnull final PlotAreaManager plotAreaManager) {
|
|
||||||
this.plotGenerator = plotGenerator;
|
this.plotGenerator = plotGenerator;
|
||||||
this.plotAreaManager = plotAreaManager;
|
this.plotAreaManager = plotAreaManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override public void populate(@Nonnull final World world, @Nonnull final Random random, @Nonnull final Chunk source) {
|
||||||
public void populate(@Nonnull final World world, @Nonnull final Random random,
|
|
||||||
@Nonnull final Chunk source) {
|
|
||||||
if (this.queue == null) {
|
if (this.queue == null) {
|
||||||
this.queue = PlotSquared.platform().getGlobalBlockQueue()
|
this.queue = PlotSquared.platform().getGlobalBlockQueue().getNewQueue(new BukkitWorld(world));
|
||||||
.getNewQueue(world.getName(), false);
|
|
||||||
}
|
}
|
||||||
final PlotArea area = this.plotAreaManager.getPlotArea(world.getName(), null);
|
final PlotArea area = this.plotAreaManager.getPlotArea(world.getName(), null);
|
||||||
if (area == null) {
|
if (area == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final ChunkWrapper wrap =
|
final ChunkWrapper wrap = new ChunkWrapper(area.getWorldName(), source.getX(), source.getZ());
|
||||||
new ChunkWrapper(area.getWorldName(), source.getX(), source.getZ());
|
final ScopedQueueCoordinator chunk = this.queue.getForChunk(wrap.x, wrap.z);
|
||||||
final ScopedLocalBlockQueue chunk = this.queue.getForChunk(wrap.x, wrap.z);
|
|
||||||
if (this.plotGenerator.populateChunk(chunk, area)) {
|
if (this.plotGenerator.populateChunk(chunk, area)) {
|
||||||
this.queue.flush();
|
this.queue.enqueue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ import com.plotsquared.core.generator.SingleWorldGenerator;
|
|||||||
import com.plotsquared.core.location.ChunkWrapper;
|
import com.plotsquared.core.location.ChunkWrapper;
|
||||||
import com.plotsquared.core.plot.PlotArea;
|
import com.plotsquared.core.plot.PlotArea;
|
||||||
import com.plotsquared.core.plot.world.PlotAreaManager;
|
import com.plotsquared.core.plot.world.PlotAreaManager;
|
||||||
import com.plotsquared.core.queue.ScopedLocalBlockQueue;
|
import com.plotsquared.core.queue.ScopedQueueCoordinator;
|
||||||
import com.plotsquared.core.util.ChunkManager;
|
import com.plotsquared.core.util.ChunkManager;
|
||||||
import com.sk89q.worldedit.math.BlockVector2;
|
import com.sk89q.worldedit.math.BlockVector2;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
@ -186,7 +186,7 @@ public class BukkitPlotGenerator extends ChunkGenerator
|
|||||||
return result.getChunkData();
|
return result.getChunkData();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generate(BlockVector2 loc, World world, ScopedLocalBlockQueue result) {
|
private void generate(BlockVector2 loc, World world, ScopedQueueCoordinator result) {
|
||||||
// Load if improperly loaded
|
// Load if improperly loaded
|
||||||
if (!this.loaded) {
|
if (!this.loaded) {
|
||||||
String name = world.getName();
|
String name = world.getName();
|
||||||
|
@ -31,7 +31,7 @@ import com.plotsquared.core.generator.IndependentPlotGenerator;
|
|||||||
import com.plotsquared.core.location.Location;
|
import com.plotsquared.core.location.Location;
|
||||||
import com.plotsquared.core.plot.PlotArea;
|
import com.plotsquared.core.plot.PlotArea;
|
||||||
import com.plotsquared.core.plot.PlotId;
|
import com.plotsquared.core.plot.PlotId;
|
||||||
import com.plotsquared.core.queue.ScopedLocalBlockQueue;
|
import com.plotsquared.core.queue.ScopedQueueCoordinator;
|
||||||
import com.plotsquared.core.util.MathMan;
|
import com.plotsquared.core.util.MathMan;
|
||||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
@ -63,7 +63,7 @@ final class DelegatePlotGenerator extends IndependentPlotGenerator {
|
|||||||
return PlotSquared.platform().getDefaultGenerator().getNewPlotArea(world, id, min, max);
|
return PlotSquared.platform().getDefaultGenerator().getNewPlotArea(world, id, min, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void generateChunk(final ScopedLocalBlockQueue result, PlotArea settings) {
|
@Override public void generateChunk(final ScopedQueueCoordinator result, PlotArea settings) {
|
||||||
World world = BukkitUtil.getWorld(this.world);
|
World world = BukkitUtil.getWorld(this.world);
|
||||||
Location min = result.getMin();
|
Location min = result.getMin();
|
||||||
int chunkX = min.getX() >> 4;
|
int chunkX = min.getX() >> 4;
|
||||||
@ -71,11 +71,7 @@ final class DelegatePlotGenerator extends IndependentPlotGenerator {
|
|||||||
Random random = new Random(MathMan.pair((short) chunkX, (short) chunkZ));
|
Random random = new Random(MathMan.pair((short) chunkX, (short) chunkZ));
|
||||||
try {
|
try {
|
||||||
ChunkGenerator.BiomeGrid grid = new ChunkGenerator.BiomeGrid() {
|
ChunkGenerator.BiomeGrid grid = new ChunkGenerator.BiomeGrid() {
|
||||||
@Override
|
@Override public void setBiome(int x, int z, @Nonnull Biome biome) {
|
||||||
public void setBiome(
|
|
||||||
final int x,
|
|
||||||
final int z,
|
|
||||||
@Nonnull final Biome biome) {
|
|
||||||
result.setBiome(x, z, BukkitAdapter.adapt(biome));
|
result.setBiome(x, z, BukkitAdapter.adapt(biome));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,8 @@ import com.google.inject.Singleton;
|
|||||||
import com.google.inject.assistedinject.FactoryModuleBuilder;
|
import com.google.inject.assistedinject.FactoryModuleBuilder;
|
||||||
import com.plotsquared.bukkit.BukkitPlatform;
|
import com.plotsquared.bukkit.BukkitPlatform;
|
||||||
import com.plotsquared.bukkit.player.BukkitPlayerManager;
|
import com.plotsquared.bukkit.player.BukkitPlayerManager;
|
||||||
import com.plotsquared.bukkit.queue.BukkitLocalQueue;
|
import com.plotsquared.bukkit.queue.BukkitChunkCoordinator;
|
||||||
|
import com.plotsquared.bukkit.queue.BukkitQueueCoordinator;
|
||||||
import com.plotsquared.bukkit.schematic.BukkitSchematicHandler;
|
import com.plotsquared.bukkit.schematic.BukkitSchematicHandler;
|
||||||
import com.plotsquared.bukkit.util.BukkitChunkManager;
|
import com.plotsquared.bukkit.util.BukkitChunkManager;
|
||||||
import com.plotsquared.bukkit.util.BukkitEconHandler;
|
import com.plotsquared.bukkit.util.BukkitEconHandler;
|
||||||
@ -45,10 +46,13 @@ import com.plotsquared.core.generator.HybridGen;
|
|||||||
import com.plotsquared.core.generator.IndependentPlotGenerator;
|
import com.plotsquared.core.generator.IndependentPlotGenerator;
|
||||||
import com.plotsquared.core.inject.annotations.ConsoleActor;
|
import com.plotsquared.core.inject.annotations.ConsoleActor;
|
||||||
import com.plotsquared.core.inject.annotations.DefaultGenerator;
|
import com.plotsquared.core.inject.annotations.DefaultGenerator;
|
||||||
|
import com.plotsquared.core.inject.factory.ChunkCoordinatorBuilderFactory;
|
||||||
|
import com.plotsquared.core.inject.factory.ChunkCoordinatorFactory;
|
||||||
import com.plotsquared.core.inject.factory.HybridPlotWorldFactory;
|
import com.plotsquared.core.inject.factory.HybridPlotWorldFactory;
|
||||||
import com.plotsquared.core.plot.world.DefaultPlotAreaManager;
|
import com.plotsquared.core.plot.world.DefaultPlotAreaManager;
|
||||||
import com.plotsquared.core.plot.world.PlotAreaManager;
|
import com.plotsquared.core.plot.world.PlotAreaManager;
|
||||||
import com.plotsquared.core.plot.world.SinglePlotAreaManager;
|
import com.plotsquared.core.plot.world.SinglePlotAreaManager;
|
||||||
|
import com.plotsquared.core.queue.ChunkCoordinator;
|
||||||
import com.plotsquared.core.queue.GlobalBlockQueue;
|
import com.plotsquared.core.queue.GlobalBlockQueue;
|
||||||
import com.plotsquared.core.queue.QueueProvider;
|
import com.plotsquared.core.queue.QueueProvider;
|
||||||
import com.plotsquared.core.util.ChunkManager;
|
import com.plotsquared.core.util.ChunkManager;
|
||||||
@ -88,8 +92,7 @@ public class BukkitModule extends AbstractModule {
|
|||||||
bind(InventoryUtil.class).to(BukkitInventoryUtil.class);
|
bind(InventoryUtil.class).to(BukkitInventoryUtil.class);
|
||||||
bind(SetupUtils.class).to(BukkitSetupUtils.class);
|
bind(SetupUtils.class).to(BukkitSetupUtils.class);
|
||||||
bind(WorldUtil.class).to(BukkitUtil.class);
|
bind(WorldUtil.class).to(BukkitUtil.class);
|
||||||
bind(GlobalBlockQueue.class).toInstance(new GlobalBlockQueue(
|
bind(GlobalBlockQueue.class).toInstance(new GlobalBlockQueue(QueueProvider.of(BukkitQueueCoordinator.class)));
|
||||||
QueueProvider.of(BukkitLocalQueue.class, BukkitLocalQueue.class), 1, Settings.QUEUE.TARGET_TIME));
|
|
||||||
bind(ChunkManager.class).to(BukkitChunkManager.class);
|
bind(ChunkManager.class).to(BukkitChunkManager.class);
|
||||||
bind(RegionManager.class).to(BukkitRegionManager.class);
|
bind(RegionManager.class).to(BukkitRegionManager.class);
|
||||||
bind(SchematicHandler.class).to(BukkitSchematicHandler.class);
|
bind(SchematicHandler.class).to(BukkitSchematicHandler.class);
|
||||||
@ -99,6 +102,8 @@ public class BukkitModule extends AbstractModule {
|
|||||||
bind(PlotAreaManager.class).to(DefaultPlotAreaManager.class);
|
bind(PlotAreaManager.class).to(DefaultPlotAreaManager.class);
|
||||||
}
|
}
|
||||||
install(new FactoryModuleBuilder().build(HybridPlotWorldFactory.class));
|
install(new FactoryModuleBuilder().build(HybridPlotWorldFactory.class));
|
||||||
|
install(new FactoryModuleBuilder().implement(ChunkCoordinator.class, BukkitChunkCoordinator.class).build(ChunkCoordinatorFactory.class));
|
||||||
|
install(new FactoryModuleBuilder().build(ChunkCoordinatorBuilderFactory.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides @Singleton @Nullable EconHandler provideEconHandler() {
|
@Provides @Singleton @Nullable EconHandler provideEconHandler() {
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,330 @@
|
|||||||
|
/*
|
||||||
|
* _____ _ _ _____ _
|
||||||
|
* | __ \| | | | / ____| | |
|
||||||
|
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
||||||
|
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
||||||
|
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
||||||
|
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
||||||
|
* | |
|
||||||
|
* |_|
|
||||||
|
* PlotSquared plot management system for Minecraft
|
||||||
|
* Copyright (C) 2020 IntellectualSites
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.plotsquared.bukkit.listener;
|
||||||
|
|
||||||
|
import com.plotsquared.bukkit.util.BukkitEntityUtil;
|
||||||
|
import com.plotsquared.bukkit.util.BukkitUtil;
|
||||||
|
import com.plotsquared.core.PlotSquared;
|
||||||
|
import com.plotsquared.core.configuration.Settings;
|
||||||
|
import com.plotsquared.core.location.Location;
|
||||||
|
import com.plotsquared.core.plot.Plot;
|
||||||
|
import com.plotsquared.core.plot.PlotArea;
|
||||||
|
import com.plotsquared.core.plot.flag.implementations.DisablePhysicsFlag;
|
||||||
|
import com.plotsquared.core.plot.flag.implementations.ExplosionFlag;
|
||||||
|
import com.plotsquared.core.plot.flag.implementations.InvincibleFlag;
|
||||||
|
import com.plotsquared.core.plot.flag.implementations.MobPlaceFlag;
|
||||||
|
import com.plotsquared.core.plot.world.PlotAreaManager;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.entity.Ageable;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
|
import org.bukkit.entity.FallingBlock;
|
||||||
|
import org.bukkit.entity.TNTPrimed;
|
||||||
|
import org.bukkit.entity.Vehicle;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||||
|
import org.bukkit.event.entity.EntityChangeBlockEvent;
|
||||||
|
import org.bukkit.event.entity.EntityCombustByEntityEvent;
|
||||||
|
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||||
|
import org.bukkit.event.entity.EntityDamageEvent;
|
||||||
|
import org.bukkit.event.entity.EntityExplodeEvent;
|
||||||
|
import org.bukkit.event.entity.ExplosionPrimeEvent;
|
||||||
|
import org.bukkit.event.vehicle.VehicleCreateEvent;
|
||||||
|
import org.bukkit.metadata.FixedMetadataValue;
|
||||||
|
import org.bukkit.metadata.MetadataValue;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public class EntityEventListener implements Listener {
|
||||||
|
|
||||||
|
private final PlotAreaManager plotAreaManager;
|
||||||
|
private float lastRadius;
|
||||||
|
|
||||||
|
@Inject public EntityEventListener(@Nonnull final PlotAreaManager plotAreaManager) {
|
||||||
|
this.plotAreaManager = plotAreaManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST) public void onEntityCombustByEntity(EntityCombustByEntityEvent event) {
|
||||||
|
EntityDamageByEntityEvent eventChange =
|
||||||
|
new EntityDamageByEntityEvent(event.getCombuster(), event.getEntity(), EntityDamageEvent.DamageCause.FIRE_TICK, event.getDuration());
|
||||||
|
onEntityDamageByEntityEvent(eventChange);
|
||||||
|
if (eventChange.isCancelled()) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST) public void onEntityDamageByEntityEvent(EntityDamageByEntityEvent event) {
|
||||||
|
Entity damager = event.getDamager();
|
||||||
|
Location location = BukkitUtil.adapt(damager.getLocation());
|
||||||
|
if (!this.plotAreaManager.hasPlotArea(location.getWorldName())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Entity victim = event.getEntity();
|
||||||
|
/*
|
||||||
|
if (victim.getType().equals(EntityType.ITEM_FRAME)) {
|
||||||
|
Plot plot = BukkitUtil.getLocation(victim).getPlot();
|
||||||
|
if (plot != null && !plot.isAdded(damager.getUniqueId())) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
if (!BukkitEntityUtil.entityDamage(damager, victim, event.getCause())) {
|
||||||
|
if (event.isCancelled()) {
|
||||||
|
if (victim instanceof Ageable) {
|
||||||
|
Ageable ageable = (Ageable) victim;
|
||||||
|
if (ageable.getAge() == -24000) {
|
||||||
|
ageable.setAge(0);
|
||||||
|
ageable.setAdult();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void creatureSpawnEvent(CreatureSpawnEvent event) {
|
||||||
|
Entity entity = event.getEntity();
|
||||||
|
Location location = BukkitUtil.adapt(entity.getLocation());
|
||||||
|
PlotArea area = location.getPlotArea();
|
||||||
|
if (area == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
CreatureSpawnEvent.SpawnReason reason = event.getSpawnReason();
|
||||||
|
switch (reason.toString()) {
|
||||||
|
case "DISPENSE_EGG":
|
||||||
|
case "EGG":
|
||||||
|
case "OCELOT_BABY":
|
||||||
|
case "SPAWNER_EGG":
|
||||||
|
if (!area.isSpawnEggs()) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "REINFORCEMENTS":
|
||||||
|
case "NATURAL":
|
||||||
|
case "MOUNT":
|
||||||
|
case "PATROL":
|
||||||
|
case "RAID":
|
||||||
|
case "SHEARED":
|
||||||
|
case "SHOULDER_ENTITY":
|
||||||
|
case "SILVERFISH_BLOCK":
|
||||||
|
case "TRAP":
|
||||||
|
case "VILLAGE_DEFENSE":
|
||||||
|
case "VILLAGE_INVASION":
|
||||||
|
case "BEEHIVE":
|
||||||
|
case "CHUNK_GEN":
|
||||||
|
if (!area.isMobSpawning()) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case "BREEDING":
|
||||||
|
if (!area.isSpawnBreeding()) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "BUILD_IRONGOLEM":
|
||||||
|
case "BUILD_SNOWMAN":
|
||||||
|
case "BUILD_WITHER":
|
||||||
|
case "CUSTOM":
|
||||||
|
if (!area.isSpawnCustom() && entity.getType() != EntityType.ARMOR_STAND) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "SPAWNER":
|
||||||
|
if (!area.isMobSpawnerSpawning()) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Plot plot = area.getOwnedPlotAbs(location);
|
||||||
|
if (plot == null) {
|
||||||
|
if (!area.isMobSpawning()) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (BukkitEntityUtil.checkEntity(entity, plot)) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) public void onEntityFall(EntityChangeBlockEvent event) {
|
||||||
|
if (event.getEntityType() != EntityType.FALLING_BLOCK) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Block block = event.getBlock();
|
||||||
|
World world = block.getWorld();
|
||||||
|
String worldName = world.getName();
|
||||||
|
if (!this.plotAreaManager.hasPlotArea(worldName)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Location location = BukkitUtil.adapt(block.getLocation());
|
||||||
|
PlotArea area = location.getPlotArea();
|
||||||
|
if (area == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Plot plot = area.getOwnedPlotAbs(location);
|
||||||
|
if (plot == null || plot.getFlag(DisablePhysicsFlag.class)) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
plot.debug("Falling block event was cancelled because disable-physics = true");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (event.getTo().hasGravity()) {
|
||||||
|
Entity entity = event.getEntity();
|
||||||
|
List<MetadataValue> meta = entity.getMetadata("plot");
|
||||||
|
if (meta.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Plot origin = (Plot) meta.get(0).value();
|
||||||
|
if (origin != null && !origin.equals(plot)) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
entity.remove();
|
||||||
|
}
|
||||||
|
} else if (event.getTo() == Material.AIR) {
|
||||||
|
event.getEntity().setMetadata("plot", new FixedMetadataValue((Plugin) PlotSquared.platform(), plot));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGH) public void onDamage(EntityDamageEvent event) {
|
||||||
|
if (event.getEntityType() != EntityType.PLAYER) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Location location = BukkitUtil.adapt(event.getEntity().getLocation());
|
||||||
|
PlotArea area = location.getPlotArea();
|
||||||
|
if (area == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Plot plot = location.getOwnedPlot();
|
||||||
|
if (plot == null) {
|
||||||
|
if (area.isRoadFlags() && area.getRoadFlag(InvincibleFlag.class)) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (plot.getFlag(InvincibleFlag.class)) {
|
||||||
|
plot.debug(event.getEntity().getName() + " could not take damage because invincible = true");
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onBigBoom(EntityExplodeEvent event) {
|
||||||
|
Location location = BukkitUtil.adapt(event.getLocation());
|
||||||
|
PlotArea area = location.getPlotArea();
|
||||||
|
boolean plotArea = location.isPlotArea();
|
||||||
|
if (!plotArea) {
|
||||||
|
if (!this.plotAreaManager.hasPlotArea(location.getWorldName())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Plot plot = area.getOwnedPlot(location);
|
||||||
|
if (plot != null) {
|
||||||
|
if (plot.getFlag(ExplosionFlag.class)) {
|
||||||
|
List<MetadataValue> meta = event.getEntity().getMetadata("plot");
|
||||||
|
Plot origin;
|
||||||
|
if (meta.isEmpty()) {
|
||||||
|
origin = plot;
|
||||||
|
} else {
|
||||||
|
origin = (Plot) meta.get(0).value();
|
||||||
|
}
|
||||||
|
if (this.lastRadius != 0) {
|
||||||
|
List<Entity> nearby = event.getEntity().getNearbyEntities(this.lastRadius, this.lastRadius, this.lastRadius);
|
||||||
|
for (Entity near : nearby) {
|
||||||
|
if (near instanceof TNTPrimed || near.getType().equals(EntityType.MINECART_TNT)) {
|
||||||
|
if (!near.hasMetadata("plot")) {
|
||||||
|
near.setMetadata("plot", new FixedMetadataValue((Plugin) PlotSquared.platform(), plot));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.lastRadius = 0;
|
||||||
|
}
|
||||||
|
Iterator<Block> iterator = event.blockList().iterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
Block block = iterator.next();
|
||||||
|
location = BukkitUtil.adapt(block.getLocation());
|
||||||
|
if (!area.contains(location.getX(), location.getZ()) || !origin.equals(area.getOwnedPlot(location))) {
|
||||||
|
iterator.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
plot.debug("Explosion was cancelled because explosion = false");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
public void onPeskyMobsChangeTheWorldLikeWTFEvent(EntityChangeBlockEvent event) {
|
||||||
|
Entity e = event.getEntity();
|
||||||
|
if (!(e instanceof FallingBlock)) {
|
||||||
|
Location location = BukkitUtil.adapt(event.getBlock().getLocation());
|
||||||
|
PlotArea area = location.getPlotArea();
|
||||||
|
if (area != null) {
|
||||||
|
Plot plot = area.getOwnedPlot(location);
|
||||||
|
if (plot != null && plot.getFlag(MobPlaceFlag.class)) {
|
||||||
|
plot.debug(e.getType() + " could not change block because mob-place = false");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler public void onPrime(ExplosionPrimeEvent event) {
|
||||||
|
this.lastRadius = event.getRadius() + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onVehicleCreate(VehicleCreateEvent event) {
|
||||||
|
Vehicle entity = event.getVehicle();
|
||||||
|
Location location = BukkitUtil.adapt(entity.getLocation());
|
||||||
|
PlotArea area = location.getPlotArea();
|
||||||
|
if (area == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Plot plot = area.getOwnedPlotAbs(location);
|
||||||
|
if (plot == null || BukkitEntityUtil.checkEntity(entity, plot)) {
|
||||||
|
entity.remove();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Settings.Enabled_Components.KILL_ROAD_VEHICLES) {
|
||||||
|
entity.setMetadata("plot", new FixedMetadataValue((Plugin) PlotSquared.platform(), plot));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -25,6 +25,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.plotsquared.bukkit.listener;
|
package com.plotsquared.bukkit.listener;
|
||||||
|
|
||||||
|
import com.plotsquared.bukkit.util.BukkitEntityUtil;
|
||||||
import com.plotsquared.bukkit.util.BukkitUtil;
|
import com.plotsquared.bukkit.util.BukkitUtil;
|
||||||
import com.plotsquared.core.PlotSquared;
|
import com.plotsquared.core.PlotSquared;
|
||||||
import com.plotsquared.core.configuration.Settings;
|
import com.plotsquared.core.configuration.Settings;
|
||||||
@ -66,8 +67,7 @@ public class EntitySpawnListener implements Listener {
|
|||||||
|
|
||||||
public static void testNether(final Entity entity) {
|
public static void testNether(final Entity entity) {
|
||||||
@Nonnull World world = entity.getWorld();
|
@Nonnull World world = entity.getWorld();
|
||||||
if (world.getEnvironment() != World.Environment.NETHER
|
if (world.getEnvironment() != World.Environment.NETHER && world.getEnvironment() != World.Environment.THE_END) {
|
||||||
&& world.getEnvironment() != World.Environment.THE_END) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
test(entity);
|
test(entity);
|
||||||
@ -91,8 +91,7 @@ public class EntitySpawnListener implements Listener {
|
|||||||
List<MetadataValue> meta = entity.getMetadata(KEY);
|
List<MetadataValue> meta = entity.getMetadata(KEY);
|
||||||
if (meta.isEmpty()) {
|
if (meta.isEmpty()) {
|
||||||
if (PlotSquared.get().getPlotAreaManager().hasPlotArea(world.getName())) {
|
if (PlotSquared.get().getPlotAreaManager().hasPlotArea(world.getName())) {
|
||||||
entity.setMetadata(KEY,
|
entity.setMetadata(KEY, new FixedMetadataValue((Plugin) PlotSquared.platform(), entity.getLocation()));
|
||||||
new FixedMetadataValue((Plugin) PlotSquared.platform(), entity.getLocation()));
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
org.bukkit.Location origin = (org.bukkit.Location) meta.get(0).value();
|
org.bukkit.Location origin = (org.bukkit.Location) meta.get(0).value();
|
||||||
@ -123,8 +122,7 @@ public class EntitySpawnListener implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void creatureSpawnEvent(EntitySpawnEvent event) {
|
||||||
public void creatureSpawnEvent(EntitySpawnEvent event) {
|
|
||||||
Entity entity = event.getEntity();
|
Entity entity = event.getEntity();
|
||||||
Location location = BukkitUtil.adapt(entity.getLocation());
|
Location location = BukkitUtil.adapt(entity.getLocation());
|
||||||
PlotArea area = location.getPlotArea();
|
PlotArea area = location.getPlotArea();
|
||||||
@ -155,13 +153,12 @@ public class EntitySpawnListener implements Listener {
|
|||||||
}
|
}
|
||||||
switch (entity.getType()) {
|
switch (entity.getType()) {
|
||||||
case ENDER_CRYSTAL:
|
case ENDER_CRYSTAL:
|
||||||
if (PlayerEvents.checkEntity(entity, plot)) {
|
if (BukkitEntityUtil.checkEntity(entity, plot)) {
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
}
|
}
|
||||||
case SHULKER:
|
case SHULKER:
|
||||||
if (!entity.hasMetadata("shulkerPlot")) {
|
if (!entity.hasMetadata("shulkerPlot")) {
|
||||||
entity.setMetadata("shulkerPlot",
|
entity.setMetadata("shulkerPlot", new FixedMetadataValue((Plugin) PlotSquared.platform(), plot.getId()));
|
||||||
new FixedMetadataValue((Plugin) PlotSquared.platform(), plot.getId()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -192,8 +189,7 @@ public class EntitySpawnListener implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void vehicleMove(VehicleMoveEvent event) {
|
||||||
public void vehicleMove(VehicleMoveEvent event) {
|
|
||||||
testNether(event.getVehicle());
|
testNether(event.getVehicle());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,163 @@
|
|||||||
|
/*
|
||||||
|
* _____ _ _ _____ _
|
||||||
|
* | __ \| | | | / ____| | |
|
||||||
|
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
||||||
|
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
||||||
|
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
||||||
|
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
||||||
|
* | |
|
||||||
|
* |_|
|
||||||
|
* PlotSquared plot management system for Minecraft
|
||||||
|
* Copyright (C) 2020 IntellectualSites
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.plotsquared.bukkit.listener;
|
||||||
|
|
||||||
|
import com.plotsquared.bukkit.util.BukkitEntityUtil;
|
||||||
|
import com.plotsquared.bukkit.util.BukkitUtil;
|
||||||
|
import com.plotsquared.core.location.Location;
|
||||||
|
import com.plotsquared.core.permissions.Permission;
|
||||||
|
import com.plotsquared.core.player.PlotPlayer;
|
||||||
|
import com.plotsquared.core.plot.Plot;
|
||||||
|
import com.plotsquared.core.plot.PlotArea;
|
||||||
|
import com.plotsquared.core.plot.PlotHandler;
|
||||||
|
import com.plotsquared.core.plot.world.PlotAreaManager;
|
||||||
|
import com.plotsquared.core.util.Permissions;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.LivingEntity;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.entity.Projectile;
|
||||||
|
import org.bukkit.entity.ThrownPotion;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.entity.LingeringPotionSplashEvent;
|
||||||
|
import org.bukkit.event.entity.PotionSplashEvent;
|
||||||
|
import org.bukkit.event.entity.ProjectileHitEvent;
|
||||||
|
import org.bukkit.event.entity.ProjectileLaunchEvent;
|
||||||
|
import org.bukkit.projectiles.BlockProjectileSource;
|
||||||
|
import org.bukkit.projectiles.ProjectileSource;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public class ProjectileEventListener implements Listener {
|
||||||
|
|
||||||
|
private final PlotAreaManager plotAreaManager;
|
||||||
|
|
||||||
|
@Inject public ProjectileEventListener(@Nonnull final PlotAreaManager plotAreaManager) {
|
||||||
|
this.plotAreaManager = plotAreaManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onPotionSplash(LingeringPotionSplashEvent event) {
|
||||||
|
Projectile entity = event.getEntity();
|
||||||
|
Location location = BukkitUtil.adapt(entity.getLocation());
|
||||||
|
if (!this.plotAreaManager.hasPlotArea(location.getWorldName())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!this.onProjectileHit(event)) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onPotionSplash(PotionSplashEvent event) {
|
||||||
|
ThrownPotion damager = event.getPotion();
|
||||||
|
Location location = BukkitUtil.adapt(damager.getLocation());
|
||||||
|
if (!this.plotAreaManager.hasPlotArea(location.getWorldName())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int count = 0;
|
||||||
|
for (LivingEntity victim : event.getAffectedEntities()) {
|
||||||
|
if (!BukkitEntityUtil.entityDamage(damager, victim)) {
|
||||||
|
event.setIntensity(victim, 0);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((count > 0 && count == event.getAffectedEntities().size()) || !onProjectileHit(event)) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler public void onProjectileLaunch(ProjectileLaunchEvent event) {
|
||||||
|
Projectile entity = event.getEntity();
|
||||||
|
if (!(entity instanceof ThrownPotion)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ProjectileSource shooter = entity.getShooter();
|
||||||
|
if (!(shooter instanceof Player)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Location location = BukkitUtil.adapt(entity.getLocation());
|
||||||
|
if (!this.plotAreaManager.hasPlotArea(location.getWorldName())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PlotPlayer<Player> pp = BukkitUtil.adapt((Player) shooter);
|
||||||
|
Plot plot = location.getOwnedPlot();
|
||||||
|
if (plot != null && !plot.isAdded(pp.getUUID())) {
|
||||||
|
entity.remove();
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({"BooleanMethodIsAlwaysInverted", "cos it's not... dum IntelliJ"}) @EventHandler
|
||||||
|
public boolean onProjectileHit(ProjectileHitEvent event) {
|
||||||
|
Projectile entity = event.getEntity();
|
||||||
|
Location location = BukkitUtil.adapt(entity.getLocation());
|
||||||
|
if (!this.plotAreaManager.hasPlotArea(location.getWorldName())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
PlotArea area = location.getPlotArea();
|
||||||
|
if (area == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Plot plot = area.getPlot(location);
|
||||||
|
ProjectileSource shooter = entity.getShooter();
|
||||||
|
if (shooter instanceof Player) {
|
||||||
|
PlotPlayer<?> pp = BukkitUtil.adapt((Player) shooter);
|
||||||
|
if (plot == null) {
|
||||||
|
if (!Permissions.hasPermission(pp, Permission.PERMISSION_PROJECTILE_UNOWNED)) {
|
||||||
|
entity.remove();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (plot.isAdded(pp.getUUID()) || Permissions
|
||||||
|
.hasPermission(pp, Permission.PERMISSION_PROJECTILE_OTHER)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
entity.remove();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!(shooter instanceof Entity) && shooter != null) {
|
||||||
|
if (plot == null) {
|
||||||
|
entity.remove();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Location sLoc =
|
||||||
|
BukkitUtil.adapt(((BlockProjectileSource) shooter).getBlock().getLocation());
|
||||||
|
if (!area.contains(sLoc.getX(), sLoc.getZ())) {
|
||||||
|
entity.remove();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Plot sPlot = area.getOwnedPlotAbs(sLoc);
|
||||||
|
if (sPlot == null || !PlotHandler.sameOwners(plot, sPlot)) {
|
||||||
|
entity.remove();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* _____ _ _ _____ _
|
||||||
|
* | __ \| | | | / ____| | |
|
||||||
|
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
||||||
|
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
||||||
|
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
||||||
|
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
||||||
|
* | |
|
||||||
|
* |_|
|
||||||
|
* PlotSquared plot management system for Minecraft
|
||||||
|
* Copyright (C) 2020 IntellectualSites
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.plotsquared.bukkit.listener;
|
||||||
|
|
||||||
|
import com.plotsquared.bukkit.BukkitPlatform;
|
||||||
|
import com.plotsquared.bukkit.placeholder.MVdWPlaceholders;
|
||||||
|
import com.plotsquared.core.PlotSquared;
|
||||||
|
import com.plotsquared.core.configuration.caption.TranslatableCaption;
|
||||||
|
import com.plotsquared.core.player.ConsolePlayer;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.server.ServerLoadEvent;
|
||||||
|
|
||||||
|
public class ServerListener implements Listener {
|
||||||
|
|
||||||
|
private final BukkitPlatform plugin;
|
||||||
|
|
||||||
|
public ServerListener(BukkitPlatform plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler public void onServerLoad(ServerLoadEvent event) {
|
||||||
|
if (Bukkit.getPluginManager().getPlugin("MVdWPlaceholderAPI") != null) {
|
||||||
|
new MVdWPlaceholders(this.plugin, PlotSquared.get().getPlaceholderRegistry());
|
||||||
|
ConsolePlayer.getConsole().sendMessage(TranslatableCaption.of("placeholder.hooked"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* _____ _ _ _____ _
|
||||||
|
* | __ \| | | | / ____| | |
|
||||||
|
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
||||||
|
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
||||||
|
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
||||||
|
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
||||||
|
* | |
|
||||||
|
* |_|
|
||||||
|
* PlotSquared plot management system for Minecraft
|
||||||
|
* Copyright (C) 2020 IntellectualSites
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.plotsquared.bukkit.placeholder;
|
||||||
|
|
||||||
|
import be.maximvdw.placeholderapi.PlaceholderAPI;
|
||||||
|
import com.google.common.eventbus.Subscribe;
|
||||||
|
import com.plotsquared.bukkit.util.BukkitUtil;
|
||||||
|
import com.plotsquared.core.PlotSquared;
|
||||||
|
import com.plotsquared.core.player.PlotPlayer;
|
||||||
|
import com.plotsquared.core.util.placeholders.Placeholder;
|
||||||
|
import com.plotsquared.core.util.placeholders.PlaceholderRegistry;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Placeholder support for MVdWPlaceholderAPI
|
||||||
|
*/
|
||||||
|
public class MVdWPlaceholders {
|
||||||
|
|
||||||
|
private static final String PREFIX = "plotsquared_";
|
||||||
|
private final Plugin plugin;
|
||||||
|
private final PlaceholderRegistry registry;
|
||||||
|
|
||||||
|
public MVdWPlaceholders(@Nonnull final Plugin plugin, @Nonnull final PlaceholderRegistry registry) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
this.registry = registry;
|
||||||
|
for (final Placeholder placeholder : registry.getPlaceholders()) {
|
||||||
|
this.addPlaceholder(placeholder);
|
||||||
|
}
|
||||||
|
PlotSquared.get().getEventDispatcher().registerListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe public void onNewPlaceholder(@Nonnull final PlaceholderRegistry.PlaceholderAddedEvent event) {
|
||||||
|
this.addPlaceholder(event.getPlaceholder());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addPlaceholder(@Nonnull final Placeholder placeholder) {
|
||||||
|
PlaceholderAPI.registerPlaceholder(plugin, PREFIX + String.format("%s", placeholder.getKey()), placeholderReplaceEvent -> {
|
||||||
|
if (!placeholderReplaceEvent.isOnline() || placeholderReplaceEvent.getPlayer() == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
final PlotPlayer<Player> player = BukkitUtil.adapt(placeholderReplaceEvent.getPlayer());
|
||||||
|
String key = placeholderReplaceEvent.getPlaceholder().substring(PREFIX.length());
|
||||||
|
return registry.getPlaceholderValue(key, player);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
* _____ _ _ _____ _
|
||||||
|
* | __ \| | | | / ____| | |
|
||||||
|
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
||||||
|
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
||||||
|
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
||||||
|
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
||||||
|
* | |
|
||||||
|
* |_|
|
||||||
|
* PlotSquared plot management system for Minecraft
|
||||||
|
* Copyright (C) 2020 IntellectualSites
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.plotsquared.bukkit.placeholder;
|
||||||
|
|
||||||
|
import com.plotsquared.core.PlotSquared;
|
||||||
|
import com.plotsquared.core.player.PlotPlayer;
|
||||||
|
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||||
|
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
public class PAPIPlaceholders extends PlaceholderExpansion {
|
||||||
|
|
||||||
|
public PAPIPlaceholders() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean persist() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean canRegister() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public String getAuthor() {
|
||||||
|
return "IntellectualSites";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public String getIdentifier() {
|
||||||
|
return "plotsquared";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public String getVersion() {
|
||||||
|
return "3";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public String onPlaceholderRequest(Player p, String identifier) {
|
||||||
|
final PlotPlayer<?> pl = PlotSquared.platform().getPlayerManager().getPlayerIfExists(p.getUniqueId());
|
||||||
|
|
||||||
|
if (pl == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// PAPI specific ones that don't translate well over into other placeholder APIs
|
||||||
|
if (identifier.startsWith("has_plot_")) {
|
||||||
|
identifier = identifier.substring("has_plot_".length());
|
||||||
|
if (identifier.isEmpty())
|
||||||
|
return "";
|
||||||
|
|
||||||
|
return pl.getPlotCount(identifier) > 0 ?
|
||||||
|
PlaceholderAPIPlugin.booleanTrue() :
|
||||||
|
PlaceholderAPIPlugin.booleanFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (identifier.startsWith("plot_count_")) {
|
||||||
|
identifier = identifier.substring("plot_count_".length());
|
||||||
|
if (identifier.isEmpty())
|
||||||
|
return "";
|
||||||
|
|
||||||
|
return String.valueOf(pl.getPlotCount(identifier));
|
||||||
|
}
|
||||||
|
|
||||||
|
// PlotSquared placeholders
|
||||||
|
return PlotSquared.get().getPlaceholderRegistry().getPlaceholderValue(identifier, pl);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,213 +0,0 @@
|
|||||||
/*
|
|
||||||
* _____ _ _ _____ _
|
|
||||||
* | __ \| | | | / ____| | |
|
|
||||||
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
|
||||||
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
|
||||||
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
|
||||||
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
|
||||||
* | |
|
|
||||||
* |_|
|
|
||||||
* PlotSquared plot management system for Minecraft
|
|
||||||
* Copyright (C) 2020 IntellectualSites
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package com.plotsquared.bukkit.placeholder;
|
|
||||||
|
|
||||||
import com.plotsquared.core.PlotSquared;
|
|
||||||
import com.plotsquared.core.player.PlotPlayer;
|
|
||||||
import com.plotsquared.core.plot.Plot;
|
|
||||||
import com.plotsquared.core.plot.flag.GlobalFlagContainer;
|
|
||||||
import com.plotsquared.core.plot.flag.PlotFlag;
|
|
||||||
import com.plotsquared.core.util.PlayerManager;
|
|
||||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
|
||||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class Placeholders extends PlaceholderExpansion {
|
|
||||||
|
|
||||||
public Placeholders() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public boolean persist() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public boolean canRegister() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public String getAuthor() {
|
|
||||||
return "NotMyFault";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public String getIdentifier() {
|
|
||||||
return "plotsquared";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public String getVersion() {
|
|
||||||
return "2.5";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public String onPlaceholderRequest(Player p, String identifier) {
|
|
||||||
final PlotPlayer pl = PlotSquared.platform().getPlayerManager().getPlayerIfExists(p.getUniqueId());
|
|
||||||
|
|
||||||
if (pl == null) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (identifier.startsWith("has_plot_")) {
|
|
||||||
identifier = identifier.substring("has_plot_".length());
|
|
||||||
if (identifier.isEmpty())
|
|
||||||
return "";
|
|
||||||
|
|
||||||
return pl.getPlotCount(identifier) > 0 ?
|
|
||||||
PlaceholderAPIPlugin.booleanTrue() :
|
|
||||||
PlaceholderAPIPlugin.booleanFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (identifier.startsWith("plot_count_")) {
|
|
||||||
identifier = identifier.substring("plot_count_".length());
|
|
||||||
if (identifier.isEmpty())
|
|
||||||
return "";
|
|
||||||
|
|
||||||
return String.valueOf(pl.getPlotCount(identifier));
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (identifier) {
|
|
||||||
case "currentplot_world": {
|
|
||||||
return p.getWorld().getName();
|
|
||||||
}
|
|
||||||
case "has_plot": {
|
|
||||||
return (pl.getPlotCount() > 0) ?
|
|
||||||
PlaceholderAPIPlugin.booleanTrue() :
|
|
||||||
PlaceholderAPIPlugin.booleanFalse();
|
|
||||||
}
|
|
||||||
case "allowed_plot_count": {
|
|
||||||
return String.valueOf(pl.getAllowedPlots());
|
|
||||||
}
|
|
||||||
case "plot_count": {
|
|
||||||
return String.valueOf(pl.getPlotCount());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Plot plot = pl.getCurrentPlot();
|
|
||||||
|
|
||||||
if (plot == null) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (identifier) {
|
|
||||||
case "currentplot_alias": {
|
|
||||||
return plot.getAlias();
|
|
||||||
}
|
|
||||||
case "currentplot_owner": {
|
|
||||||
final UUID plotOwner = plot.getOwnerAbs();
|
|
||||||
if (plotOwner == null) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
return PlayerManager.getName(plotOwner, false);
|
|
||||||
} catch (final Exception ignored) {}
|
|
||||||
|
|
||||||
final String name = Bukkit.getOfflinePlayer(plotOwner).getName();
|
|
||||||
return name != null ? name : "unknown";
|
|
||||||
}
|
|
||||||
case "currentplot_members": {
|
|
||||||
if (plot.getMembers() == null && plot.getTrusted() == null) {
|
|
||||||
return "0";
|
|
||||||
}
|
|
||||||
return String.valueOf(plot.getMembers().size() + plot.getTrusted().size());
|
|
||||||
}
|
|
||||||
case "currentplot_members_added": {
|
|
||||||
if (plot.getMembers() == null) {
|
|
||||||
return "0";
|
|
||||||
}
|
|
||||||
return String.valueOf(plot.getMembers().size());
|
|
||||||
}
|
|
||||||
case "currentplot_members_trusted": {
|
|
||||||
if (plot.getTrusted() == null) {
|
|
||||||
return "0";
|
|
||||||
}
|
|
||||||
return String.valueOf(plot.getTrusted().size());
|
|
||||||
}
|
|
||||||
case "currentplot_members_denied": {
|
|
||||||
if (plot.getDenied() == null) {
|
|
||||||
return "0";
|
|
||||||
}
|
|
||||||
return String.valueOf(plot.getDenied().size());
|
|
||||||
}
|
|
||||||
case "has_build_rights": {
|
|
||||||
return plot.isAdded(pl.getUUID()) ?
|
|
||||||
PlaceholderAPIPlugin.booleanTrue() :
|
|
||||||
PlaceholderAPIPlugin.booleanFalse();
|
|
||||||
}
|
|
||||||
case "currentplot_x": {
|
|
||||||
return String.valueOf(plot.getId().getX());
|
|
||||||
}
|
|
||||||
case "currentplot_y": {
|
|
||||||
return String.valueOf(plot.getId().getY());
|
|
||||||
}
|
|
||||||
case "currentplot_xy": {
|
|
||||||
return plot.getId().getX() + ";" + plot.getId().getY();
|
|
||||||
}
|
|
||||||
case "currentplot_rating": {
|
|
||||||
return String.valueOf(plot.getAverageRating());
|
|
||||||
}
|
|
||||||
case "currentplot_biome": {
|
|
||||||
return plot.getBiomeSynchronous() + "";
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (identifier.startsWith("currentplot_localflag_")) {
|
|
||||||
return getFlagValue(plot, identifier.substring("currentplot_localflag_".length()),
|
|
||||||
false);
|
|
||||||
}
|
|
||||||
if (identifier.startsWith("currentplot_flag_")) {
|
|
||||||
return getFlagValue(plot, identifier.substring("currentplot_flag_".length()), true);
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the flag value from its name on the current plot.
|
|
||||||
* If the flag doesn't exist it returns an empty string.
|
|
||||||
* If the flag exists but it is not set on current plot and the parameter inherit is set to true,
|
|
||||||
* it returns the default value.
|
|
||||||
*
|
|
||||||
* @param plot Current plot where the player is
|
|
||||||
* @param flagName Name of flag to get from current plot
|
|
||||||
* @param inherit Define if it returns only the flag set on currentplot or also inherited flag
|
|
||||||
* @return The value of flag serialized in string
|
|
||||||
*/
|
|
||||||
private String getFlagValue(final Plot plot, final String flagName, final boolean inherit) {
|
|
||||||
if (flagName.isEmpty())
|
|
||||||
return "";
|
|
||||||
final PlotFlag<?, ?> flag = GlobalFlagContainer.getInstance().getFlagFromString(flagName);
|
|
||||||
if (flag == null)
|
|
||||||
return "";
|
|
||||||
|
|
||||||
if (inherit) {
|
|
||||||
return plot.getFlag(flag).toString();
|
|
||||||
} else {
|
|
||||||
final PlotFlag<?, ?> plotFlag = plot.getFlagContainer().queryLocal(flag.getClass());
|
|
||||||
return (plotFlag != null) ? plotFlag.getValue().toString() : "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -73,10 +73,7 @@ public class BukkitPlayer extends PlotPlayer<Player> {
|
|||||||
|
|
||||||
private static boolean CHECK_EFFECTIVE = true;
|
private static boolean CHECK_EFFECTIVE = true;
|
||||||
public final Player player;
|
public final Player player;
|
||||||
private final EconHandler econHandler;
|
|
||||||
private String name;
|
private String name;
|
||||||
private String lastMessage = "";
|
|
||||||
private long lastMessageTime = 0L;
|
|
||||||
/**
|
/**
|
||||||
* <p>Please do not use this method. Instead use
|
* <p>Please do not use this method. Instead use
|
||||||
* BukkitUtil.getPlayer(Player), as it caches player objects.</p>
|
* BukkitUtil.getPlayer(Player), as it caches player objects.</p>
|
||||||
@ -94,7 +91,6 @@ public class BukkitPlayer extends PlotPlayer<Player> {
|
|||||||
@Nonnull final PermissionHandler permissionHandler) {
|
@Nonnull final PermissionHandler permissionHandler) {
|
||||||
super(plotAreaManager, eventDispatcher, econHandler, permissionHandler);
|
super(plotAreaManager, eventDispatcher, econHandler, permissionHandler);
|
||||||
this.player = player;
|
this.player = player;
|
||||||
this.econHandler = econHandler;
|
|
||||||
this.setupPermissionProfile();
|
this.setupPermissionProfile();
|
||||||
if (realPlayer) {
|
if (realPlayer) {
|
||||||
super.populatePersistentMetaMap();
|
super.populatePersistentMetaMap();
|
||||||
@ -153,13 +149,6 @@ public class BukkitPlayer extends PlotPlayer<Player> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean hasPermission(@Nonnull final String permission) {
|
|
||||||
if (this.offline && this.econHandler != null) {
|
|
||||||
return this.econHandler.hasPermission(getName(), permission);
|
|
||||||
}
|
|
||||||
return this.player.hasPermission(permission);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override @Nonnegative public int hasPermissionRange(@Nonnull final String stub,
|
@Override @Nonnegative public int hasPermissionRange(@Nonnull final String stub,
|
||||||
@Nonnegative final int range) {
|
@Nonnegative final int range) {
|
||||||
if (hasPermission(Permission.PERMISSION_ADMIN.toString())) {
|
if (hasPermission(Permission.PERMISSION_ADMIN.toString())) {
|
||||||
|
@ -0,0 +1,225 @@
|
|||||||
|
/*
|
||||||
|
* _____ _ _ _____ _
|
||||||
|
* | __ \| | | | / ____| | |
|
||||||
|
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
||||||
|
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
||||||
|
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
||||||
|
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
||||||
|
* | |
|
||||||
|
* |_|
|
||||||
|
* PlotSquared plot management system for Minecraft
|
||||||
|
* Copyright (C) 2020 IntellectualSites
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.plotsquared.bukkit.queue;
|
||||||
|
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.google.inject.assistedinject.Assisted;
|
||||||
|
import com.plotsquared.bukkit.BukkitPlatform;
|
||||||
|
import com.plotsquared.core.queue.ChunkCoordinator;
|
||||||
|
import com.plotsquared.core.util.task.TaskManager;
|
||||||
|
import com.plotsquared.core.util.task.TaskTime;
|
||||||
|
import com.sk89q.worldedit.math.BlockVector2;
|
||||||
|
import com.sk89q.worldedit.world.World;
|
||||||
|
import io.papermc.lib.PaperLib;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Chunk;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Queue;
|
||||||
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility that allows for the loading and coordination of chunk actions
|
||||||
|
* <p>
|
||||||
|
* The coordinator takes in collection of chunk coordinates, loads them
|
||||||
|
* and allows the caller to specify a sink for the loaded chunks. The
|
||||||
|
* coordinator will prevent the chunks from being unloaded until the sink
|
||||||
|
* has fully consumed the chunk
|
||||||
|
* <p>
|
||||||
|
**/
|
||||||
|
public final class BukkitChunkCoordinator extends ChunkCoordinator {
|
||||||
|
|
||||||
|
private final List<ProgressSubscriber> progressSubscribers = new LinkedList<>();
|
||||||
|
|
||||||
|
private final Queue<BlockVector2> requestedChunks;
|
||||||
|
private final Queue<Chunk> availableChunks;
|
||||||
|
private final long maxIterationTime;
|
||||||
|
private final Plugin plugin;
|
||||||
|
private final Consumer<BlockVector2> chunkConsumer;
|
||||||
|
private final org.bukkit.World bukkitWorld;
|
||||||
|
private final Runnable whenDone;
|
||||||
|
private final Consumer<Throwable> throwableConsumer;
|
||||||
|
private final boolean unloadAfter;
|
||||||
|
private final int totalSize;
|
||||||
|
|
||||||
|
private final AtomicInteger expectedSize;
|
||||||
|
private int batchSize;
|
||||||
|
|
||||||
|
@Inject private BukkitChunkCoordinator(@Assisted final long maxIterationTime,
|
||||||
|
@Assisted final int initialBatchSize,
|
||||||
|
@Assisted @Nonnull final Consumer<BlockVector2> chunkConsumer,
|
||||||
|
@Assisted @Nonnull final World world,
|
||||||
|
@Assisted @Nonnull final Collection<BlockVector2> requestedChunks,
|
||||||
|
@Assisted @Nonnull final Runnable whenDone,
|
||||||
|
@Assisted @Nonnull final Consumer<Throwable> throwableConsumer,
|
||||||
|
@Assisted final boolean unloadAfter) {
|
||||||
|
this.requestedChunks = new LinkedBlockingQueue<>(requestedChunks);
|
||||||
|
this.availableChunks = new LinkedBlockingQueue<>();
|
||||||
|
this.totalSize = requestedChunks.size();
|
||||||
|
this.expectedSize = new AtomicInteger(this.totalSize);
|
||||||
|
this.batchSize = initialBatchSize;
|
||||||
|
this.chunkConsumer = chunkConsumer;
|
||||||
|
this.maxIterationTime = maxIterationTime;
|
||||||
|
this.whenDone = whenDone;
|
||||||
|
this.throwableConsumer = throwableConsumer;
|
||||||
|
this.unloadAfter = unloadAfter;
|
||||||
|
this.plugin = JavaPlugin.getPlugin(BukkitPlatform.class);
|
||||||
|
this.bukkitWorld = Bukkit.getWorld(world.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void start() {
|
||||||
|
// Request initial batch
|
||||||
|
this.requestBatch();
|
||||||
|
// Wait until next tick to give the chunks a chance to be loaded
|
||||||
|
TaskManager.runTaskLater(() -> TaskManager.runTaskRepeat(this, TaskTime.ticks(1)), TaskTime.ticks(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void runTask() {
|
||||||
|
Chunk chunk = this.availableChunks.poll();
|
||||||
|
if (chunk == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
long iterationTime;
|
||||||
|
int processedChunks = 0;
|
||||||
|
do {
|
||||||
|
final long start = System.currentTimeMillis();
|
||||||
|
try {
|
||||||
|
this.chunkConsumer.accept(BlockVector2.at(chunk.getX(), chunk.getZ()));
|
||||||
|
} catch (final Throwable throwable) {
|
||||||
|
this.throwableConsumer.accept(throwable);
|
||||||
|
}
|
||||||
|
if (unloadAfter) {
|
||||||
|
this.freeChunk(chunk);
|
||||||
|
}
|
||||||
|
processedChunks++;
|
||||||
|
final long end = System.currentTimeMillis();
|
||||||
|
// Update iteration time
|
||||||
|
iterationTime = end - start;
|
||||||
|
} while (2 * iterationTime /* last chunk + next chunk */ < this.maxIterationTime && (chunk = availableChunks.poll()) != null);
|
||||||
|
if (processedChunks < this.batchSize) {
|
||||||
|
// Adjust batch size based on the amount of processed chunks per tick
|
||||||
|
this.batchSize = processedChunks;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int expected = this.expectedSize.addAndGet(-processedChunks);
|
||||||
|
|
||||||
|
final float progress = ((float) totalSize - (float) expected) / (float) totalSize;
|
||||||
|
for (final ProgressSubscriber subscriber : this.progressSubscribers) {
|
||||||
|
subscriber.notifyProgress(this, progress);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expected <= 0) {
|
||||||
|
try {
|
||||||
|
this.whenDone.run();
|
||||||
|
} catch (final Throwable throwable) {
|
||||||
|
this.throwableConsumer.accept(throwable);
|
||||||
|
}
|
||||||
|
this.cancel();
|
||||||
|
} else {
|
||||||
|
if (this.availableChunks.size() < processedChunks) {
|
||||||
|
this.requestBatch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requests a batch of chunks to be loaded
|
||||||
|
*/
|
||||||
|
private void requestBatch() {
|
||||||
|
BlockVector2 chunk;
|
||||||
|
for (int i = 0; i < this.batchSize && (chunk = this.requestedChunks.poll()) != null; i++) {
|
||||||
|
// This required PaperLib to be bumped to version 1.0.4 to mark the request as urgent
|
||||||
|
PaperLib.getChunkAtAsync(this.bukkitWorld, chunk.getX(), chunk.getZ(), true, true).whenComplete((chunkObject, throwable) -> {
|
||||||
|
if (throwable != null) {
|
||||||
|
throwable.printStackTrace();
|
||||||
|
// We want one less because this couldn't be processed
|
||||||
|
this.expectedSize.decrementAndGet();
|
||||||
|
} else {
|
||||||
|
this.processChunk(chunkObject);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Once a chunk has been loaded, process it (add a plugin ticket and add to available chunks list)
|
||||||
|
*/
|
||||||
|
private void processChunk(@Nonnull final Chunk chunk) {
|
||||||
|
if (!chunk.isLoaded()) {
|
||||||
|
throw new IllegalArgumentException(String.format("Chunk %d;%d is is not loaded", chunk.getX(), chunk.getZ()));
|
||||||
|
}
|
||||||
|
chunk.addPluginChunkTicket(this.plugin);
|
||||||
|
this.availableChunks.add(chunk);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Once a chunk has been used, free it up for unload by removing the plugin ticket
|
||||||
|
*/
|
||||||
|
private void freeChunk(@Nonnull final Chunk chunk) {
|
||||||
|
if (!chunk.isLoaded()) {
|
||||||
|
throw new IllegalArgumentException(String.format("Chunk %d;%d is is not loaded", chunk.getX(), chunk.getZ()));
|
||||||
|
}
|
||||||
|
chunk.removePluginChunkTicket(this.plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public int getRemainingChunks() {
|
||||||
|
return this.expectedSize.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public int getTotalChunks() {
|
||||||
|
return this.totalSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subscribe to coordinator progress updates
|
||||||
|
*
|
||||||
|
* @param subscriber Subscriber
|
||||||
|
*/
|
||||||
|
public void subscribeToProgress(@Nonnull final BukkitChunkCoordinator.ProgressSubscriber subscriber) {
|
||||||
|
this.progressSubscribers.add(subscriber);
|
||||||
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface ProgressSubscriber {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify about a progress update in the coordinator
|
||||||
|
*
|
||||||
|
* @param coordinator Coordinator instance that triggered the notification
|
||||||
|
* @param progress Progress in the range [0, 1]
|
||||||
|
*/
|
||||||
|
void notifyProgress(@Nonnull final BukkitChunkCoordinator coordinator, final float progress);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,239 +0,0 @@
|
|||||||
/*
|
|
||||||
* _____ _ _ _____ _
|
|
||||||
* | __ \| | | | / ____| | |
|
|
||||||
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
|
||||||
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
|
||||||
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
|
||||||
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
|
||||||
* | |
|
|
||||||
* |_|
|
|
||||||
* PlotSquared plot management system for Minecraft
|
|
||||||
* Copyright (C) 2020 IntellectualSites
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package com.plotsquared.bukkit.queue;
|
|
||||||
|
|
||||||
import com.plotsquared.bukkit.schematic.StateWrapper;
|
|
||||||
import com.plotsquared.bukkit.util.BukkitBlockUtil;
|
|
||||||
import com.plotsquared.core.queue.BasicLocalBlockQueue;
|
|
||||||
import com.plotsquared.core.util.BlockUtil;
|
|
||||||
import com.plotsquared.core.util.ChunkUtil;
|
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
|
||||||
import com.sk89q.worldedit.EditSession;
|
|
||||||
import com.sk89q.worldedit.WorldEdit;
|
|
||||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
|
||||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
|
||||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
|
||||||
import io.papermc.lib.PaperLib;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Chunk;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.block.Biome;
|
|
||||||
import org.bukkit.block.Block;
|
|
||||||
import org.bukkit.block.Container;
|
|
||||||
import org.bukkit.block.data.BlockData;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
public class BukkitLocalQueue extends BasicLocalBlockQueue {
|
|
||||||
|
|
||||||
public BukkitLocalQueue(String world) {
|
|
||||||
super(world);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public LocalChunk getLocalChunk(int x, int z) {
|
|
||||||
return new BasicLocalChunk(this, x, z) {
|
|
||||||
// Custom stuff?
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public void optimize() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public BlockState getBlock(int x, int y, int z) {
|
|
||||||
World worldObj = Bukkit.getWorld(getWorld());
|
|
||||||
if (worldObj != null) {
|
|
||||||
Block block = worldObj.getBlockAt(x, y, z);
|
|
||||||
return BukkitBlockUtil.get(block);
|
|
||||||
} else {
|
|
||||||
return BlockUtil.get(0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public void refreshChunk(int x, int z) {
|
|
||||||
World worldObj = Bukkit.getWorld(getWorld());
|
|
||||||
if (worldObj != null) {
|
|
||||||
worldObj.refreshChunk(x, z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public void fixChunkLighting(int x, int z) {
|
|
||||||
// Do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public final void regenChunk(int x, int z) {
|
|
||||||
World worldObj = Bukkit.getWorld(getWorld());
|
|
||||||
if (worldObj != null) {
|
|
||||||
try {
|
|
||||||
worldObj.regenerateChunk(x, z);
|
|
||||||
} catch (UnsupportedOperationException e) {
|
|
||||||
com.sk89q.worldedit.world.World world = BukkitAdapter.adapt(worldObj);
|
|
||||||
try (EditSession editSession = WorldEdit.getInstance().getEditSessionFactory()
|
|
||||||
.getEditSession(world, -1);) {
|
|
||||||
CuboidRegion region =
|
|
||||||
new CuboidRegion(world, BlockVector3.at((x << 4), 0, (z << 4)),
|
|
||||||
BlockVector3.at((x << 4) + 15, 255, (z << 4) + 15));
|
|
||||||
world.regenerate(region, editSession);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public final void setComponents(LocalChunk lc)
|
|
||||||
throws ExecutionException, InterruptedException {
|
|
||||||
setBaseBlocks(lc);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBaseBlocks(LocalChunk localChunk) {
|
|
||||||
World worldObj = Bukkit.getWorld(getWorld());
|
|
||||||
if (worldObj == null) {
|
|
||||||
throw new NullPointerException("World cannot be null.");
|
|
||||||
}
|
|
||||||
final Consumer<Chunk> chunkConsumer = chunk -> {
|
|
||||||
for (int layer = 0; layer < localChunk.baseblocks.length; layer++) {
|
|
||||||
BaseBlock[] blocksLayer = localChunk.baseblocks[layer];
|
|
||||||
if (blocksLayer != null) {
|
|
||||||
for (int j = 0; j < blocksLayer.length; j++) {
|
|
||||||
if (blocksLayer[j] != null) {
|
|
||||||
BaseBlock block = blocksLayer[j];
|
|
||||||
int x = ChunkUtil.getX(j);
|
|
||||||
int y = ChunkUtil.getY(layer, j);
|
|
||||||
int z = ChunkUtil.getZ(j);
|
|
||||||
|
|
||||||
BlockData blockData = BukkitAdapter.adapt(block);
|
|
||||||
|
|
||||||
Block existing = chunk.getBlock(x, y, z);
|
|
||||||
final BlockState existingBaseBlock =
|
|
||||||
BukkitAdapter.adapt(existing.getBlockData());
|
|
||||||
if (BukkitBlockUtil.get(existing).equals(existingBaseBlock) && existing
|
|
||||||
.getBlockData().matches(blockData)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (existing.getState() instanceof Container) {
|
|
||||||
((Container) existing.getState()).getInventory().clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
existing.setType(BukkitAdapter.adapt(block.getBlockType()), false);
|
|
||||||
existing.setBlockData(blockData, false);
|
|
||||||
if (block.hasNbtData()) {
|
|
||||||
CompoundTag tag = block.getNbtData();
|
|
||||||
StateWrapper sw = new StateWrapper(tag);
|
|
||||||
|
|
||||||
sw.restoreTag(worldObj.getName(), existing.getX(), existing.getY(),
|
|
||||||
existing.getZ());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (setBiome() && localChunk.biomes != null) {
|
|
||||||
for (int x = 0; x < localChunk.biomes.length; x++) {
|
|
||||||
BiomeType[] biomeZ = localChunk.biomes[x];
|
|
||||||
if (biomeZ != null) {
|
|
||||||
for (int z = 0; z < biomeZ.length; z++) {
|
|
||||||
if (biomeZ[z] != null) {
|
|
||||||
BiomeType biomeType = biomeZ[z];
|
|
||||||
|
|
||||||
Biome biome = BukkitAdapter.adapt(biomeType);
|
|
||||||
worldObj.setBiome((chunk.getX() << 4) + x, (chunk.getZ() << 4) + z,
|
|
||||||
biome);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (isForceSync()) {
|
|
||||||
chunkConsumer.accept(getChunk(worldObj, localChunk));
|
|
||||||
} else {
|
|
||||||
PaperLib.getChunkAtAsync(worldObj, localChunk.getX(), localChunk.getZ(), true)
|
|
||||||
.thenAccept(chunkConsumer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Chunk getChunk(final World world, final LocalChunk localChunk) {
|
|
||||||
Chunk chunk = null;
|
|
||||||
if (this.getChunkObject() != null && this.getChunkObject() instanceof Chunk) {
|
|
||||||
chunk = (Chunk) this.getChunkObject();
|
|
||||||
}
|
|
||||||
if (chunk == null) {
|
|
||||||
chunk = world.getChunkAt(localChunk.getX(), localChunk.getZ());
|
|
||||||
}
|
|
||||||
if (!chunk.isLoaded()) {
|
|
||||||
chunk.load(true);
|
|
||||||
}
|
|
||||||
return chunk;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setMaterial(@Nonnull final BlockState plotBlock, @Nonnull final Block block) {
|
|
||||||
Material material = BukkitAdapter.adapt(plotBlock.getBlockType());
|
|
||||||
block.setType(material, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean equals(@Nonnull final BlockState plotBlock, @Nonnull final Block block) {
|
|
||||||
return plotBlock.equals(BukkitBlockUtil.get(block));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBiomes(LocalChunk lc) {
|
|
||||||
World worldObj = Bukkit.getWorld(getWorld());
|
|
||||||
if (worldObj == null) {
|
|
||||||
throw new NullPointerException("World cannot be null.");
|
|
||||||
}
|
|
||||||
if (lc.biomes == null) {
|
|
||||||
throw new NullPointerException("Biomes cannot be null.");
|
|
||||||
}
|
|
||||||
final Consumer<Chunk> chunkConsumer = chunk -> {
|
|
||||||
for (int x = 0; x < lc.biomes.length; x++) {
|
|
||||||
BiomeType[] biomeZ = lc.biomes[x];
|
|
||||||
if (biomeZ != null) {
|
|
||||||
for (int z = 0; z < biomeZ.length; z++) {
|
|
||||||
if (biomeZ[z] != null) {
|
|
||||||
BiomeType biomeType = biomeZ[z];
|
|
||||||
|
|
||||||
Biome biome = BukkitAdapter.adapt(biomeType);
|
|
||||||
worldObj
|
|
||||||
.setBiome((chunk.getX() << 4) + x, (chunk.getZ() << 4) + z, biome);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (this.isForceSync()) {
|
|
||||||
chunkConsumer.accept(getChunk(worldObj, lc));
|
|
||||||
} else {
|
|
||||||
PaperLib.getChunkAtAsync(worldObj, lc.getX(), lc.getZ(), true)
|
|
||||||
.thenAccept(chunkConsumer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,241 @@
|
|||||||
|
/*
|
||||||
|
* _____ _ _ _____ _
|
||||||
|
* | __ \| | | | / ____| | |
|
||||||
|
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
||||||
|
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
||||||
|
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
||||||
|
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
||||||
|
* | |
|
||||||
|
* |_|
|
||||||
|
* PlotSquared plot management system for Minecraft
|
||||||
|
* Copyright (C) 2020 IntellectualSites
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.plotsquared.bukkit.queue;
|
||||||
|
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.plotsquared.bukkit.schematic.StateWrapper;
|
||||||
|
import com.plotsquared.bukkit.util.BukkitBlockUtil;
|
||||||
|
import com.plotsquared.core.inject.factory.ChunkCoordinatorBuilderFactory;
|
||||||
|
import com.plotsquared.core.inject.factory.ChunkCoordinatorFactory;
|
||||||
|
import com.plotsquared.core.queue.BasicQueueCoordinator;
|
||||||
|
import com.plotsquared.core.queue.ChunkCoordinator;
|
||||||
|
import com.plotsquared.core.queue.LocalChunk;
|
||||||
|
import com.plotsquared.core.util.BlockUtil;
|
||||||
|
import com.plotsquared.core.util.ChunkUtil;
|
||||||
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
|
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||||
|
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
||||||
|
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||||
|
import com.sk89q.worldedit.math.BlockVector2;
|
||||||
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
|
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||||
|
import com.sk89q.worldedit.regions.Region;
|
||||||
|
import com.sk89q.worldedit.util.SideEffect;
|
||||||
|
import com.sk89q.worldedit.util.SideEffectSet;
|
||||||
|
import com.sk89q.worldedit.world.World;
|
||||||
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Chunk;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.block.Container;
|
||||||
|
import org.bukkit.block.data.BlockData;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
public class BukkitQueueCoordinator extends BasicQueueCoordinator {
|
||||||
|
|
||||||
|
private final SideEffectSet sideEffectSet;
|
||||||
|
private org.bukkit.World bukkitWorld;
|
||||||
|
@Inject private ChunkCoordinatorBuilderFactory chunkCoordinatorBuilderFactory;
|
||||||
|
@Inject private ChunkCoordinatorFactory chunkCoordinatorFactory;
|
||||||
|
private ChunkCoordinator chunkCoordinator;
|
||||||
|
|
||||||
|
@Inject public BukkitQueueCoordinator(@Nonnull World world) {
|
||||||
|
super(world);
|
||||||
|
sideEffectSet = SideEffectSet.none().with(SideEffect.LIGHTING, SideEffect.State.OFF).with(SideEffect.NEIGHBORS, SideEffect.State.OFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public BlockState getBlock(int x, int y, int z) {
|
||||||
|
org.bukkit.World worldObj = BukkitAdapter.adapt(getWorld());
|
||||||
|
if (worldObj != null) {
|
||||||
|
Block block = worldObj.getBlockAt(x, y, z);
|
||||||
|
return BukkitBlockUtil.get(block);
|
||||||
|
} else {
|
||||||
|
return BlockUtil.get(0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void start() {
|
||||||
|
chunkCoordinator.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: implement cancellation
|
||||||
|
@Override public void cancel() {
|
||||||
|
chunkCoordinator.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean enqueue() {
|
||||||
|
final Clipboard regenClipboard;
|
||||||
|
if (isRegen()) {
|
||||||
|
BlockVector3 start = BlockVector3.at(getRegenStart()[0] << 4, 0, getRegenStart()[1] << 4);
|
||||||
|
BlockVector3 end = BlockVector3.at((getRegenEnd()[0] << 4) + 15, 255, (getRegenEnd()[1] << 4) + 15);
|
||||||
|
Region region = new CuboidRegion(start, end);
|
||||||
|
regenClipboard = new BlockArrayClipboard(region);
|
||||||
|
regenClipboard.setOrigin(start);
|
||||||
|
getWorld().regenerate(region, regenClipboard);
|
||||||
|
} else if (getRegenRegion() != null) {
|
||||||
|
regenClipboard = new BlockArrayClipboard(getRegenRegion());
|
||||||
|
regenClipboard.setOrigin(getRegenRegion().getMinimumPoint());
|
||||||
|
getWorld().regenerate(getRegenRegion(), regenClipboard);
|
||||||
|
} else {
|
||||||
|
regenClipboard = null;
|
||||||
|
}
|
||||||
|
Consumer<BlockVector2> consumer = getChunkConsumer();
|
||||||
|
if (consumer == null) {
|
||||||
|
consumer = blockVector2 -> {
|
||||||
|
LocalChunk localChunk = getBlockChunks().get(blockVector2);
|
||||||
|
boolean isRegenChunk =
|
||||||
|
regenClipboard != null && blockVector2.getBlockX() > getRegenStart()[0] && blockVector2.getBlockZ() > getRegenStart()[1]
|
||||||
|
&& blockVector2.getBlockX() < getRegenEnd()[0] && blockVector2.getBlockZ() < getRegenEnd()[1];
|
||||||
|
if (isRegenChunk) {
|
||||||
|
for (int layer = 0; layer < 16; layer++) {
|
||||||
|
for (int y = layer << 4; y < 16; y++) {
|
||||||
|
for (int x = 0; x < 16; x++) {
|
||||||
|
for (int z = 0; z < 16; z++) {
|
||||||
|
BaseBlock block = regenClipboard.getFullBlock(BlockVector3.at(x, y, z));
|
||||||
|
if (block != null) {
|
||||||
|
setWorldBlock(x, y, z, block, blockVector2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Allow regen and then blocks to be placed (plot schematic etc)
|
||||||
|
if (localChunk == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int sx = blockVector2.getX() << 4;
|
||||||
|
int sz = blockVector2.getZ() << 4;
|
||||||
|
for (int layer = 0; layer < localChunk.getBaseblocks().length; layer++) {
|
||||||
|
BaseBlock[] blocksLayer = localChunk.getBaseblocks()[layer];
|
||||||
|
if (blocksLayer == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (int j = 0; j < blocksLayer.length; j++) {
|
||||||
|
if (blocksLayer[j] == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
BaseBlock block = blocksLayer[j];
|
||||||
|
|
||||||
|
if (block != null) {
|
||||||
|
int x = sx + ChunkUtil.getX(j);
|
||||||
|
int y = ChunkUtil.getY(layer, j);
|
||||||
|
int z = sz + ChunkUtil.getZ(j);
|
||||||
|
setWorldBlock(x, y, z, block, blockVector2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int layer = 0; layer < localChunk.getBaseblocks().length; layer++) {
|
||||||
|
BiomeType[] biomesLayer = localChunk.getBiomes()[layer];
|
||||||
|
if (biomesLayer == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (int j = 0; j < biomesLayer.length; j++) {
|
||||||
|
if (biomesLayer[j] == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
BiomeType biome = biomesLayer[j];
|
||||||
|
if (biome != null) {
|
||||||
|
int x = sx + ChunkUtil.getX(j);
|
||||||
|
int y = ChunkUtil.getY(layer, j);
|
||||||
|
int z = sz + ChunkUtil.getZ(j);
|
||||||
|
getWorld().setBiome(BlockVector3.at(x, y, z), biome);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (localChunk.getTiles().size() > 0) {
|
||||||
|
localChunk.getTiles().forEach(((blockVector3, tag) -> {
|
||||||
|
try {
|
||||||
|
BaseBlock block = getWorld().getBlock(blockVector3).toBaseBlock(tag);
|
||||||
|
getWorld().setBlock(blockVector3, block, sideEffectSet);
|
||||||
|
} catch (WorldEditException ignored) {
|
||||||
|
StateWrapper sw = new StateWrapper(tag);
|
||||||
|
sw.restoreTag(getWorld().getName(), blockVector3.getX(), blockVector3.getY(), blockVector3.getZ());
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
if (localChunk.getEntities().size() > 0) {
|
||||||
|
localChunk.getEntities().forEach((location, entity) -> {
|
||||||
|
getWorld().createEntity(location, entity);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Collection<BlockVector2> read = new ArrayList<>();
|
||||||
|
if (getReadChunks().size() > 0) {
|
||||||
|
read.addAll(getReadChunks());
|
||||||
|
}
|
||||||
|
chunkCoordinator =
|
||||||
|
chunkCoordinatorBuilderFactory.create(chunkCoordinatorFactory).inWorld(getWorld()).withChunks(getBlockChunks().keySet()).withChunks(read)
|
||||||
|
.withInitialBatchSize(3).withMaxIterationTime(40).withThrowableConsumer(Throwable::printStackTrace).withFinalAction(getCompleteTask())
|
||||||
|
.withConsumer(consumer).unloadAfter(isUnloadAfter()).build();
|
||||||
|
return super.enqueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a block to the world. First tries WNA but defaults to normal block setting methods if that fails
|
||||||
|
*/
|
||||||
|
private void setWorldBlock(int x, int y, int z, @Nonnull BaseBlock block, @Nonnull BlockVector2 blockVector2) {
|
||||||
|
try {
|
||||||
|
getWorld().setBlock(BlockVector3.at(x, y, z), block, sideEffectSet);
|
||||||
|
} catch (WorldEditException ignored) {
|
||||||
|
// Fallback to not so nice method
|
||||||
|
BlockData blockData = BukkitAdapter.adapt(block);
|
||||||
|
|
||||||
|
if (bukkitWorld == null) {
|
||||||
|
bukkitWorld = Bukkit.getWorld(getWorld().getName());
|
||||||
|
}
|
||||||
|
Chunk chunk = bukkitWorld.getChunkAt(blockVector2.getX(), blockVector2.getZ());
|
||||||
|
|
||||||
|
Block existing = chunk.getBlock(x, y, z);
|
||||||
|
final BlockState existingBaseBlock = BukkitAdapter.adapt(existing.getBlockData());
|
||||||
|
if (BukkitBlockUtil.get(existing).equals(existingBaseBlock) && existing.getBlockData().matches(blockData)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (existing.getState() instanceof Container) {
|
||||||
|
((Container) existing.getState()).getInventory().clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
existing.setType(BukkitAdapter.adapt(block.getBlockType()), false);
|
||||||
|
existing.setBlockData(blockData, false);
|
||||||
|
if (block.hasNbtData()) {
|
||||||
|
CompoundTag tag = block.getNbtData();
|
||||||
|
StateWrapper sw = new StateWrapper(tag);
|
||||||
|
|
||||||
|
sw.restoreTag(getWorld().getName(), existing.getX(), existing.getY(), existing.getZ());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -30,7 +30,7 @@ import com.plotsquared.bukkit.util.BukkitBlockUtil;
|
|||||||
import com.plotsquared.bukkit.util.BukkitUtil;
|
import com.plotsquared.bukkit.util.BukkitUtil;
|
||||||
import com.plotsquared.core.location.ChunkWrapper;
|
import com.plotsquared.core.location.ChunkWrapper;
|
||||||
import com.plotsquared.core.location.Location;
|
import com.plotsquared.core.location.Location;
|
||||||
import com.plotsquared.core.queue.ScopedLocalBlockQueue;
|
import com.plotsquared.core.queue.ScopedQueueCoordinator;
|
||||||
import com.plotsquared.core.util.ChunkUtil;
|
import com.plotsquared.core.util.ChunkUtil;
|
||||||
import com.plotsquared.core.util.PatternUtil;
|
import com.plotsquared.core.util.PatternUtil;
|
||||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||||
@ -39,16 +39,17 @@ import com.sk89q.worldedit.world.biome.BiomeType;
|
|||||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Chunk;
|
import org.bukkit.Chunk;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.block.Biome;
|
import org.bukkit.block.Biome;
|
||||||
import org.bukkit.generator.ChunkGenerator.BiomeGrid;
|
import org.bukkit.generator.ChunkGenerator.BiomeGrid;
|
||||||
import org.bukkit.generator.ChunkGenerator.ChunkData;
|
import org.bukkit.generator.ChunkGenerator.ChunkData;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
public class GenChunk extends ScopedLocalBlockQueue {
|
public class GenChunk extends ScopedQueueCoordinator {
|
||||||
|
|
||||||
public final Biome[] biomes;
|
public final Biome[] biomes;
|
||||||
public BlockState[][] result;
|
public BlockState[][] result;
|
||||||
@ -64,7 +65,18 @@ public class GenChunk extends ScopedLocalBlockQueue {
|
|||||||
this.biomes = Biome.values();
|
this.biomes = Biome.values();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Chunk getChunk() {
|
@Nullable public ChunkData getChunkData() {
|
||||||
|
return this.chunkData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the internal Bukkit chunk data
|
||||||
|
*/
|
||||||
|
public void setChunkData(@Nonnull ChunkData chunkData) {
|
||||||
|
this.chunkData = chunkData;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull public Chunk getChunk() {
|
||||||
if (chunk == null) {
|
if (chunk == null) {
|
||||||
World worldObj = BukkitUtil.getWorld(world);
|
World worldObj = BukkitUtil.getWorld(world);
|
||||||
if (worldObj != null) {
|
if (worldObj != null) {
|
||||||
@ -74,32 +86,40 @@ public class GenChunk extends ScopedLocalBlockQueue {
|
|||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setChunk(Chunk chunk) {
|
/**
|
||||||
|
* Set the chunk being represented
|
||||||
|
*/
|
||||||
|
public void setChunk(@Nonnull Chunk chunk) {
|
||||||
this.chunk = chunk;
|
this.chunk = chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setChunk(ChunkWrapper wrap) {
|
|
||||||
|
/**
|
||||||
|
* Set the world and XZ of the chunk being represented via {@link ChunkWrapper}
|
||||||
|
*/
|
||||||
|
public void setChunk(@Nonnull ChunkWrapper wrap) {
|
||||||
chunk = null;
|
chunk = null;
|
||||||
world = wrap.world;
|
world = wrap.world;
|
||||||
chunkX = wrap.x;
|
chunkX = wrap.x;
|
||||||
chunkZ = wrap.z;
|
chunkZ = wrap.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void fillBiome(BiomeType biomeType) {
|
@Override public void fillBiome(@Nonnull BiomeType biomeType) {
|
||||||
if (biomeGrid == null) {
|
if (biomeGrid == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Biome biome = BukkitAdapter.adapt(biomeType);
|
Biome biome = BukkitAdapter.adapt(biomeType);
|
||||||
|
for (int y = 0; y < 256; y++) {
|
||||||
for (int x = 0; x < 16; x++) {
|
for (int x = 0; x < 16; x++) {
|
||||||
for (int z = 0; z < 16; z++) {
|
for (int z = 0; z < 16; z++) {
|
||||||
this.biomeGrid.setBiome(x, z, biome);
|
this.biomeGrid.setBiome(x, y, z, biome);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void setCuboid(Location pos1, Location pos2, BlockState block) {
|
@Override public void setCuboid(@Nonnull Location pos1, @Nonnull Location pos2, @Nonnull BlockState block) {
|
||||||
if (result != null && pos1.getX() == 0 && pos1.getZ() == 0 && pos2.getX() == 15
|
if (result != null && pos1.getX() == 0 && pos1.getZ() == 0 && pos2.getX() == 15 && pos2.getZ() == 15) {
|
||||||
&& pos2.getZ() == 15) {
|
|
||||||
for (int y = pos1.getY(); y <= pos2.getY(); y++) {
|
for (int y = pos1.getY(); y <= pos2.getY(); y++) {
|
||||||
int layer = y >> 4;
|
int layer = y >> 4;
|
||||||
BlockState[] data = result[layer];
|
BlockState[] data = result[layer];
|
||||||
@ -117,28 +137,39 @@ public class GenChunk extends ScopedLocalBlockQueue {
|
|||||||
int maxX = Math.max(pos1.getX(), pos2.getX());
|
int maxX = Math.max(pos1.getX(), pos2.getX());
|
||||||
int maxY = Math.max(pos1.getY(), pos2.getY());
|
int maxY = Math.max(pos1.getY(), pos2.getY());
|
||||||
int maxZ = Math.max(pos1.getZ(), pos2.getZ());
|
int maxZ = Math.max(pos1.getZ(), pos2.getZ());
|
||||||
chunkData
|
chunkData.setRegion(minX, minY, minZ, maxX + 1, maxY + 1, maxZ + 1, BukkitAdapter.adapt(block));
|
||||||
.setRegion(minX, minY, minZ, maxX + 1, maxY + 1, maxZ + 1, BukkitAdapter.adapt(block));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean setBiome(int x, int z, BiomeType biomeType) {
|
@Override public boolean setBiome(int x, int z, @Nonnull BiomeType biomeType) {
|
||||||
return setBiome(x, z, BukkitAdapter.adapt(biomeType));
|
return setBiome(x, z, BukkitAdapter.adapt(biomeType));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean setBiome(int x, int z, Biome biome) {
|
/**
|
||||||
|
* Set the in the whole column of XZ
|
||||||
|
*/
|
||||||
|
public boolean setBiome(int x, int z, @Nonnull Biome biome) {
|
||||||
if (this.biomeGrid != null) {
|
if (this.biomeGrid != null) {
|
||||||
this.biomeGrid.setBiome(x, z, biome);
|
for (int y = 0; y < 256; y++) {
|
||||||
|
this.setBiome(x, y, z, biome);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean setBiome(int x, int y, int z, @Nonnull Biome biome) {
|
||||||
|
if (this.biomeGrid != null) {
|
||||||
|
this.biomeGrid.setBiome(x, y, z, biome);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean setBlock(int x, int y, int z, @Nonnull Pattern pattern) {
|
@Override public boolean setBlock(int x, int y, int z, @Nonnull Pattern pattern) {
|
||||||
return setBlock(x, y, z, PatternUtil
|
return setBlock(x, y, z, PatternUtil.apply(Preconditions.checkNotNull(pattern, "Pattern may not be null"), x, y, z));
|
||||||
.apply(Preconditions.checkNotNull(pattern, "Pattern may not be null"), x, y, z));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean setBlock(int x, int y, int z, BlockState id) {
|
@Override public boolean setBlock(int x, int y, int z, @Nonnull BlockState id) {
|
||||||
if (this.result == null) {
|
if (this.result == null) {
|
||||||
this.chunkData.setBlock(x, y, z, BukkitAdapter.adapt(id));
|
this.chunkData.setBlock(x, y, z, BukkitAdapter.adapt(id));
|
||||||
return true;
|
return true;
|
||||||
@ -148,7 +179,7 @@ public class GenChunk extends ScopedLocalBlockQueue {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void storeCache(final int x, final int y, final int z, final BlockState id) {
|
private void storeCache(final int x, final int y, final int z, @Nonnull final BlockState id) {
|
||||||
int i = y >> 4;
|
int i = y >> 4;
|
||||||
BlockState[] v = this.result[i];
|
BlockState[] v = this.result[i];
|
||||||
if (v == null) {
|
if (v == null) {
|
||||||
@ -158,7 +189,7 @@ public class GenChunk extends ScopedLocalBlockQueue {
|
|||||||
v[j] = id;
|
v[j] = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean setBlock(int x, int y, int z, BaseBlock id) {
|
@Override public boolean setBlock(int x, int y, int z, @Nonnull BaseBlock id) {
|
||||||
if (this.result == null) {
|
if (this.result == null) {
|
||||||
this.chunkData.setBlock(x, y, z, BukkitAdapter.adapt(id));
|
this.chunkData.setBlock(x, y, z, BukkitAdapter.adapt(id));
|
||||||
return true;
|
return true;
|
||||||
@ -168,7 +199,7 @@ public class GenChunk extends ScopedLocalBlockQueue {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public BlockState getBlock(int x, int y, int z) {
|
@Override @Nullable public BlockState getBlock(int x, int y, int z) {
|
||||||
int i = y >> 4;
|
int i = y >> 4;
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
return BukkitBlockUtil.get(chunkData.getType(x, y, z));
|
return BukkitBlockUtil.get(chunkData.getType(x, y, z));
|
||||||
@ -189,19 +220,19 @@ public class GenChunk extends ScopedLocalBlockQueue {
|
|||||||
return chunk == null ? chunkZ : chunk.getZ();
|
return chunk == null ? chunkZ : chunk.getZ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public String getWorld() {
|
@Override @Nonnull public com.sk89q.worldedit.world.World getWorld() {
|
||||||
return chunk == null ? world : chunk.getWorld().getName();
|
return chunk == null ? BukkitAdapter.adapt(Bukkit.getWorld(world)) : BukkitAdapter.adapt(chunk.getWorld());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public Location getMax() {
|
@Override @Nonnull public Location getMax() {
|
||||||
return Location.at(getWorld(), 15 + (getX() << 4), 255, 15 + (getZ() << 4));
|
return Location.at(getWorld().getName(), 15 + (getX() << 4), 255, 15 + (getZ() << 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public Location getMin() {
|
@Override @Nonnull public Location getMin() {
|
||||||
return Location.at(getWorld(), getX() << 4, 0, getZ() << 4);
|
return Location.at(getWorld().getName(), getX() << 4, 0, getZ() << 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GenChunk clone() {
|
@Nonnull public GenChunk clone() {
|
||||||
GenChunk toReturn = new GenChunk();
|
GenChunk toReturn = new GenChunk();
|
||||||
if (this.result != null) {
|
if (this.result != null) {
|
||||||
for (int i = 0; i < this.result.length; i++) {
|
for (int i = 0; i < this.result.length; i++) {
|
||||||
@ -215,12 +246,4 @@ public class GenChunk extends ScopedLocalBlockQueue {
|
|||||||
toReturn.chunkData = this.chunkData;
|
toReturn.chunkData = this.chunkData;
|
||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChunkData getChunkData() {
|
|
||||||
return this.chunkData;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setChunkData(ChunkData chunkData) {
|
|
||||||
this.chunkData = chunkData;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ package com.plotsquared.bukkit.schematic;
|
|||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Singleton;
|
import com.google.inject.Singleton;
|
||||||
import com.plotsquared.core.queue.LocalBlockQueue;
|
import com.plotsquared.core.queue.QueueCoordinator;
|
||||||
import com.plotsquared.core.util.SchematicHandler;
|
import com.plotsquared.core.util.SchematicHandler;
|
||||||
import com.plotsquared.core.util.WorldUtil;
|
import com.plotsquared.core.util.WorldUtil;
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
@ -44,7 +44,7 @@ import javax.annotation.Nonnull;
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean restoreTile(LocalBlockQueue queue, CompoundTag ct, int x, int y, int z) {
|
public boolean restoreTile(QueueCoordinator queue, CompoundTag ct, int x, int y, int z) {
|
||||||
return new StateWrapper(ct).restoreTag(queue.getWorld(), x, y, z);
|
return new StateWrapper(ct).restoreTag(queue.getWorld().getName(), x, y, z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,140 +26,23 @@
|
|||||||
package com.plotsquared.bukkit.util;
|
package com.plotsquared.bukkit.util;
|
||||||
|
|
||||||
import com.google.inject.Singleton;
|
import com.google.inject.Singleton;
|
||||||
import com.plotsquared.core.PlotSquared;
|
|
||||||
import com.plotsquared.core.listener.WEExtent;
|
|
||||||
import com.plotsquared.core.queue.LocalBlockQueue;
|
|
||||||
import com.plotsquared.core.util.ChunkManager;
|
import com.plotsquared.core.util.ChunkManager;
|
||||||
import com.plotsquared.core.util.entity.EntityCategories;
|
|
||||||
import com.plotsquared.core.util.task.TaskManager;
|
|
||||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
|
||||||
import com.sk89q.worldedit.bukkit.BukkitWorld;
|
|
||||||
import com.sk89q.worldedit.math.BlockVector2;
|
import com.sk89q.worldedit.math.BlockVector2;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
|
||||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
|
||||||
import io.papermc.lib.PaperLib;
|
import io.papermc.lib.PaperLib;
|
||||||
import org.bukkit.Chunk;
|
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.block.Block;
|
|
||||||
import org.bukkit.block.data.BlockData;
|
|
||||||
import org.bukkit.entity.Entity;
|
|
||||||
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
import static com.plotsquared.core.util.entity.EntityCategories.CAP_ANIMAL;
|
@Singleton
|
||||||
import static com.plotsquared.core.util.entity.EntityCategories.CAP_ENTITY;
|
public class BukkitChunkManager extends ChunkManager {
|
||||||
import static com.plotsquared.core.util.entity.EntityCategories.CAP_MISC;
|
|
||||||
import static com.plotsquared.core.util.entity.EntityCategories.CAP_MOB;
|
|
||||||
import static com.plotsquared.core.util.entity.EntityCategories.CAP_MONSTER;
|
|
||||||
import static com.plotsquared.core.util.entity.EntityCategories.CAP_VEHICLE;
|
|
||||||
|
|
||||||
@Singleton public class BukkitChunkManager extends ChunkManager {
|
|
||||||
|
|
||||||
public static boolean isIn(CuboidRegion region, int x, int z) {
|
public static boolean isIn(CuboidRegion region, int x, int z) {
|
||||||
return x >= region.getMinimumPoint().getX() && x <= region.getMaximumPoint().getX()
|
return x >= region.getMinimumPoint().getX() && x <= region.getMaximumPoint().getX() && z >= region.getMinimumPoint().getZ() && z <= region
|
||||||
&& z >= region.getMinimumPoint().getZ() && z <= region.getMaximumPoint().getZ();
|
.getMaximumPoint().getZ();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ContentMap swapChunk(World world1, World world2, Chunk pos1, Chunk pos2,
|
@Override public CompletableFuture<?> loadChunk(String world, BlockVector2 chunkLoc, boolean force) {
|
||||||
CuboidRegion r1, CuboidRegion r2) {
|
return PaperLib.getChunkAtAsync(BukkitUtil.getWorld(world), chunkLoc.getX(), chunkLoc.getZ(), force);
|
||||||
ContentMap map = new ContentMap();
|
|
||||||
int relX = r2.getMinimumPoint().getX() - r1.getMinimumPoint().getX();
|
|
||||||
int relZ = r2.getMinimumPoint().getZ() - r1.getMinimumPoint().getZ();
|
|
||||||
|
|
||||||
map.saveEntitiesIn(pos1, r1, relX, relZ, true);
|
|
||||||
map.saveEntitiesIn(pos2, r2, -relX, -relZ, true);
|
|
||||||
|
|
||||||
int sx = pos1.getX() << 4;
|
|
||||||
int sz = pos1.getZ() << 4;
|
|
||||||
|
|
||||||
String worldName1 = world1.getName();
|
|
||||||
String worldName2 = world2.getName();
|
|
||||||
|
|
||||||
BukkitWorld bukkitWorld1 = new BukkitWorld(world1);
|
|
||||||
BukkitWorld bukkitWorld2 = new BukkitWorld(world2);
|
|
||||||
|
|
||||||
LocalBlockQueue queue1 = PlotSquared.platform().getGlobalBlockQueue().getNewQueue(worldName1, false);
|
|
||||||
LocalBlockQueue queue2 = PlotSquared.platform().getGlobalBlockQueue().getNewQueue(worldName2, false);
|
|
||||||
|
|
||||||
for (int x = Math.max(r1.getMinimumPoint().getX(), sx);
|
|
||||||
x <= Math.min(r1.getMaximumPoint().getX(), sx + 15); x++) {
|
|
||||||
for (int z = Math.max(r1.getMinimumPoint().getZ(), sz);
|
|
||||||
z <= Math.min(r1.getMaximumPoint().getZ(), sz + 15); z++) {
|
|
||||||
for (int y = 0; y < 256; y++) {
|
|
||||||
Block block1 = world1.getBlockAt(x, y, z);
|
|
||||||
BaseBlock baseBlock1 = bukkitWorld1.getFullBlock(BlockVector3.at(x, y, z));
|
|
||||||
BlockData data1 = block1.getBlockData();
|
|
||||||
|
|
||||||
int xx = x + relX;
|
|
||||||
int zz = z + relZ;
|
|
||||||
|
|
||||||
Block block2 = world2.getBlockAt(xx, y, zz);
|
|
||||||
BaseBlock baseBlock2 = bukkitWorld2.getFullBlock(BlockVector3.at(xx, y, zz));
|
|
||||||
BlockData data2 = block2.getBlockData();
|
|
||||||
|
|
||||||
if (block1.isEmpty()) {
|
|
||||||
if (!block2.isEmpty()) {
|
|
||||||
queue1.setBlock(x, y, z, baseBlock2);
|
|
||||||
queue2.setBlock(xx, y, zz, WEExtent.AIRBASE);
|
|
||||||
}
|
}
|
||||||
} else if (block2.isEmpty()) {
|
|
||||||
queue1.setBlock(x, y, z, WEExtent.AIRBASE);
|
|
||||||
queue2.setBlock(xx, y, zz, baseBlock1);
|
|
||||||
} else if (block1.equals(block2)) {
|
|
||||||
if (!data1.matches(data2)) {
|
|
||||||
block1.setBlockData(data2);
|
|
||||||
block2.setBlockData(data1);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
queue1.setBlock(x, y, z, baseBlock2);
|
|
||||||
queue2.setBlock(xx, y, zz, baseBlock1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
queue1.enqueue();
|
|
||||||
queue2.enqueue();
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CompletableFuture<?> loadChunk(String world, BlockVector2 chunkLoc, boolean force) {
|
|
||||||
return PaperLib
|
|
||||||
.getChunkAtAsync(BukkitUtil.getWorld(world), chunkLoc.getX(), chunkLoc.getZ(), force);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void unloadChunk(final String world, final BlockVector2 chunkLoc, final boolean save) {
|
|
||||||
if (!PlotSquared.get().isMainThread(Thread.currentThread())) {
|
|
||||||
TaskManager.runTask(() -> BukkitUtil.getWorld(world)
|
|
||||||
.unloadChunk(chunkLoc.getX(), chunkLoc.getZ(), save));
|
|
||||||
} else {
|
|
||||||
BukkitUtil.getWorld(world).unloadChunk(chunkLoc.getX(), chunkLoc.getZ(), save);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void count(int[] count, Entity entity) {
|
|
||||||
final com.sk89q.worldedit.world.entity.EntityType entityType =
|
|
||||||
BukkitAdapter.adapt(entity.getType());
|
|
||||||
|
|
||||||
if (EntityCategories.PLAYER.contains(entityType)) {
|
|
||||||
return;
|
|
||||||
} else if (EntityCategories.PROJECTILE.contains(entityType) || EntityCategories.OTHER
|
|
||||||
.contains(entityType) || EntityCategories.HANGING.contains(entityType)) {
|
|
||||||
count[CAP_MISC]++;
|
|
||||||
} else if (EntityCategories.ANIMAL.contains(entityType) || EntityCategories.VILLAGER
|
|
||||||
.contains(entityType) || EntityCategories.TAMEABLE.contains(entityType)) {
|
|
||||||
count[CAP_MOB]++;
|
|
||||||
count[CAP_ANIMAL]++;
|
|
||||||
} else if (EntityCategories.VEHICLE.contains(entityType)) {
|
|
||||||
count[CAP_VEHICLE]++;
|
|
||||||
} else if (EntityCategories.HOSTILE.contains(entityType)) {
|
|
||||||
count[CAP_MOB]++;
|
|
||||||
count[CAP_MONSTER]++;
|
|
||||||
}
|
|
||||||
count[CAP_ENTITY]++;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,381 @@
|
|||||||
|
/*
|
||||||
|
* _____ _ _ _____ _
|
||||||
|
* | __ \| | | | / ____| | |
|
||||||
|
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
||||||
|
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
||||||
|
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
||||||
|
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
||||||
|
* | |
|
||||||
|
* |_|
|
||||||
|
* PlotSquared plot management system for Minecraft
|
||||||
|
* Copyright (C) 2020 IntellectualSites
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.plotsquared.bukkit.util;
|
||||||
|
|
||||||
|
import com.plotsquared.bukkit.player.BukkitPlayer;
|
||||||
|
import com.plotsquared.core.configuration.Settings;
|
||||||
|
import com.plotsquared.core.configuration.caption.TranslatableCaption;
|
||||||
|
import com.plotsquared.core.location.Location;
|
||||||
|
import com.plotsquared.core.permissions.Permission;
|
||||||
|
import com.plotsquared.core.plot.Plot;
|
||||||
|
import com.plotsquared.core.plot.PlotArea;
|
||||||
|
import com.plotsquared.core.plot.flag.implementations.AnimalAttackFlag;
|
||||||
|
import com.plotsquared.core.plot.flag.implementations.AnimalCapFlag;
|
||||||
|
import com.plotsquared.core.plot.flag.implementations.DoneFlag;
|
||||||
|
import com.plotsquared.core.plot.flag.implementations.EntityCapFlag;
|
||||||
|
import com.plotsquared.core.plot.flag.implementations.HangingBreakFlag;
|
||||||
|
import com.plotsquared.core.plot.flag.implementations.HostileAttackFlag;
|
||||||
|
import com.plotsquared.core.plot.flag.implementations.HostileCapFlag;
|
||||||
|
import com.plotsquared.core.plot.flag.implementations.MiscBreakFlag;
|
||||||
|
import com.plotsquared.core.plot.flag.implementations.MiscCapFlag;
|
||||||
|
import com.plotsquared.core.plot.flag.implementations.MobCapFlag;
|
||||||
|
import com.plotsquared.core.plot.flag.implementations.PveFlag;
|
||||||
|
import com.plotsquared.core.plot.flag.implementations.PvpFlag;
|
||||||
|
import com.plotsquared.core.plot.flag.implementations.TamedAttackFlag;
|
||||||
|
import com.plotsquared.core.plot.flag.implementations.VehicleCapFlag;
|
||||||
|
import com.plotsquared.core.util.EntityUtil;
|
||||||
|
import com.plotsquared.core.util.Permissions;
|
||||||
|
import com.plotsquared.core.util.entity.EntityCategories;
|
||||||
|
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||||
|
import net.kyori.adventure.text.minimessage.Template;
|
||||||
|
import org.bukkit.entity.Arrow;
|
||||||
|
import org.bukkit.entity.Creature;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.entity.Projectile;
|
||||||
|
import org.bukkit.event.entity.EntityDamageEvent;
|
||||||
|
import org.bukkit.projectiles.BlockProjectileSource;
|
||||||
|
import org.bukkit.projectiles.ProjectileSource;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class BukkitEntityUtil {
|
||||||
|
|
||||||
|
public static final com.sk89q.worldedit.world.entity.EntityType FAKE_ENTITY_TYPE =
|
||||||
|
new com.sk89q.worldedit.world.entity.EntityType("plotsquared:fake");
|
||||||
|
|
||||||
|
public static boolean entityDamage(Entity damager, Entity victim) {
|
||||||
|
return entityDamage(damager, victim, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean entityDamage(Entity damager, Entity victim, EntityDamageEvent.DamageCause cause) {
|
||||||
|
Location dloc = BukkitUtil.adapt(damager.getLocation());
|
||||||
|
Location vloc = BukkitUtil.adapt(victim.getLocation());
|
||||||
|
PlotArea dArea = dloc.getPlotArea();
|
||||||
|
PlotArea vArea;
|
||||||
|
if (dArea != null && dArea.contains(vloc.getX(), vloc.getZ())) {
|
||||||
|
vArea = dArea;
|
||||||
|
} else {
|
||||||
|
vArea = vloc.getPlotArea();
|
||||||
|
}
|
||||||
|
if (dArea == null && vArea == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Plot dplot;
|
||||||
|
if (dArea != null) {
|
||||||
|
dplot = dArea.getPlot(dloc);
|
||||||
|
} else {
|
||||||
|
dplot = null;
|
||||||
|
}
|
||||||
|
Plot vplot;
|
||||||
|
if (vArea != null) {
|
||||||
|
vplot = vArea.getPlot(vloc);
|
||||||
|
} else {
|
||||||
|
vplot = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Plot plot;
|
||||||
|
String stub;
|
||||||
|
boolean isPlot = true;
|
||||||
|
if (dplot == null && vplot == null) {
|
||||||
|
if (dArea == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
plot = null;
|
||||||
|
stub = "road";
|
||||||
|
isPlot = false;
|
||||||
|
} else {
|
||||||
|
// Prioritize plots for close to seamless pvp zones
|
||||||
|
if (victim.getTicksLived() > damager.getTicksLived()) {
|
||||||
|
if (dplot == null || !(victim instanceof Player)) {
|
||||||
|
if (vplot == null) {
|
||||||
|
plot = dplot;
|
||||||
|
} else {
|
||||||
|
plot = vplot;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
plot = dplot;
|
||||||
|
}
|
||||||
|
} else if (dplot == null || !(victim instanceof Player)) {
|
||||||
|
if (vplot == null) {
|
||||||
|
plot = dplot;
|
||||||
|
} else {
|
||||||
|
plot = vplot;
|
||||||
|
}
|
||||||
|
} else if (vplot == null) {
|
||||||
|
plot = dplot;
|
||||||
|
} else {
|
||||||
|
plot = vplot;
|
||||||
|
}
|
||||||
|
if (plot.hasOwner()) {
|
||||||
|
stub = "other";
|
||||||
|
} else {
|
||||||
|
stub = "unowned";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
boolean roadFlags = vArea != null ? vArea.isRoadFlags() : dArea.isRoadFlags();
|
||||||
|
PlotArea area = vArea != null ? vArea : dArea;
|
||||||
|
|
||||||
|
Player player;
|
||||||
|
if (damager instanceof Player) { // attacker is player
|
||||||
|
player = (Player) damager;
|
||||||
|
} else if (damager instanceof Projectile) {
|
||||||
|
Projectile projectile = (Projectile) damager;
|
||||||
|
ProjectileSource shooter = projectile.getShooter();
|
||||||
|
if (shooter instanceof Player) { // shooter is player
|
||||||
|
player = (Player) shooter;
|
||||||
|
} else { // shooter is not player
|
||||||
|
if (shooter instanceof BlockProjectileSource) {
|
||||||
|
Location sLoc = BukkitUtil
|
||||||
|
.adapt(((BlockProjectileSource) shooter).getBlock().getLocation());
|
||||||
|
dplot = dArea.getPlot(sLoc);
|
||||||
|
}
|
||||||
|
player = null;
|
||||||
|
}
|
||||||
|
} else { // Attacker is not player
|
||||||
|
player = null;
|
||||||
|
}
|
||||||
|
if (player != null) {
|
||||||
|
BukkitPlayer plotPlayer = BukkitUtil.adapt(player);
|
||||||
|
|
||||||
|
final com.sk89q.worldedit.world.entity.EntityType entityType;
|
||||||
|
|
||||||
|
// Create a fake entity type if the type does not have a name
|
||||||
|
if (victim.getType().getName() == null) {
|
||||||
|
entityType = FAKE_ENTITY_TYPE;
|
||||||
|
} else {
|
||||||
|
entityType = BukkitAdapter.adapt(victim.getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EntityCategories.HANGING.contains(entityType)) { // hanging
|
||||||
|
if (plot != null && (plot.getFlag(HangingBreakFlag.class) || plot
|
||||||
|
.isAdded(plotPlayer.getUUID()))) {
|
||||||
|
if (Settings.Done.RESTRICT_BUILDING && DoneFlag.isDone(plot)) {
|
||||||
|
if (!Permissions
|
||||||
|
.hasPermission(plotPlayer, Permission.PERMISSION_ADMIN_BUILD_OTHER)) {
|
||||||
|
plotPlayer.sendMessage(
|
||||||
|
TranslatableCaption.of("permission.no_permission_event"),
|
||||||
|
Template.of("node", "plots.admin.build.other")
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!Permissions.hasPermission(plotPlayer, "plots.admin.destroy." + stub)) {
|
||||||
|
plotPlayer.sendMessage(
|
||||||
|
TranslatableCaption.of("permission.no_permission_event"),
|
||||||
|
Template.of("node", "plots.admin.destroy." + stub)
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (victim.getType() == EntityType.ARMOR_STAND) {
|
||||||
|
if (plot != null && (plot.getFlag(MiscBreakFlag.class) || plot
|
||||||
|
.isAdded(plotPlayer.getUUID()))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!Permissions.hasPermission(plotPlayer, "plots.admin.destroy." + stub)) {
|
||||||
|
plotPlayer.sendMessage(
|
||||||
|
TranslatableCaption.of("permission.no_permission_event"),
|
||||||
|
Template.of("node", "plots.admin.destroy." + stub)
|
||||||
|
);
|
||||||
|
if (plot != null) {
|
||||||
|
plot.debug(player.getName()
|
||||||
|
+ " could not break armor stand because misc-break = false");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (EntityCategories.HOSTILE.contains(entityType)) {
|
||||||
|
if (isPlot) {
|
||||||
|
if (plot.getFlag(HostileAttackFlag.class) || plot.getFlag(PveFlag.class) || plot
|
||||||
|
.isAdded(plotPlayer.getUUID())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else if (roadFlags && (area.getRoadFlag(HostileAttackFlag.class) || area
|
||||||
|
.getFlag(PveFlag.class))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!Permissions.hasPermission(plotPlayer, "plots.admin.pve." + stub)) {
|
||||||
|
plotPlayer.sendMessage(
|
||||||
|
TranslatableCaption.of("permission.no_permission_event"),
|
||||||
|
Template.of("node", "plots.admin.pve." + stub)
|
||||||
|
);
|
||||||
|
if (plot != null) {
|
||||||
|
plot.debug(player.getName() + " could not attack " + entityType
|
||||||
|
+ " because pve = false OR hostile-attack = false");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (EntityCategories.TAMEABLE.contains(entityType)) { // victim is tameable
|
||||||
|
if (isPlot) {
|
||||||
|
if (plot.getFlag(TamedAttackFlag.class) || plot.getFlag(PveFlag.class) || plot
|
||||||
|
.isAdded(plotPlayer.getUUID())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else if (roadFlags && (area.getRoadFlag(TamedAttackFlag.class) || area
|
||||||
|
.getFlag(PveFlag.class))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!Permissions.hasPermission(plotPlayer, "plots.admin.pve." + stub)) {
|
||||||
|
plotPlayer.sendMessage(
|
||||||
|
TranslatableCaption.of("permission.no_permission_event"),
|
||||||
|
Template.of("node", "plots.admin.pve." + stub)
|
||||||
|
);
|
||||||
|
if (plot != null) {
|
||||||
|
plot.debug(player.getName() + " could not attack " + entityType
|
||||||
|
+ " because pve = false OR tamed-attack = false");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (EntityCategories.PLAYER.contains(entityType)) {
|
||||||
|
if (isPlot) {
|
||||||
|
if (!plot.getFlag(PvpFlag.class) && !Permissions
|
||||||
|
.hasPermission(plotPlayer, "plots.admin.pvp." + stub)) {
|
||||||
|
plotPlayer.sendMessage(
|
||||||
|
TranslatableCaption.of("permission.no_permission_event"),
|
||||||
|
Template.of("node", "plots.admin.pvp." + stub)
|
||||||
|
);
|
||||||
|
plot.debug(player.getName() + " could not attack " + entityType
|
||||||
|
+ " because pve = false");
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else if (roadFlags && area.getRoadFlag(PvpFlag.class)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!Permissions.hasPermission(plotPlayer, "plots.admin.pvp." + stub)) {
|
||||||
|
plotPlayer.sendMessage(
|
||||||
|
TranslatableCaption.of("permission.no_permission_event"),
|
||||||
|
Template.of("node", "plots.admin.pvp." + stub)
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (EntityCategories.ANIMAL.contains(entityType)) { // victim is animal
|
||||||
|
if (isPlot) {
|
||||||
|
if (plot.getFlag(AnimalAttackFlag.class) || plot.getFlag(PveFlag.class) || plot
|
||||||
|
.isAdded(plotPlayer.getUUID())) {
|
||||||
|
plot.debug(player.getName() + " could not attack " + entityType
|
||||||
|
+ " because pve = false OR animal-attack = false");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else if (roadFlags && (area.getRoadFlag(AnimalAttackFlag.class) || area
|
||||||
|
.getFlag(PveFlag.class))) {
|
||||||
|
if (!Permissions.hasPermission(plotPlayer, "plots.admin.pve." + stub)) {
|
||||||
|
plotPlayer.sendMessage(
|
||||||
|
TranslatableCaption.of("permission.no_permission_event"),
|
||||||
|
Template.of("node", "plots.admin.pve." + stub)
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (EntityCategories.VEHICLE
|
||||||
|
.contains(entityType)) { // Vehicles are managed in vehicle destroy event
|
||||||
|
return true;
|
||||||
|
} else { // victim is something else
|
||||||
|
if (isPlot) {
|
||||||
|
if (plot.getFlag(PveFlag.class) || plot.isAdded(plotPlayer.getUUID())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else if (roadFlags && area.getRoadFlag(PveFlag.class)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!Permissions.hasPermission(plotPlayer, "plots.admin.pve." + stub)) {
|
||||||
|
plotPlayer.sendMessage(
|
||||||
|
TranslatableCaption.of("permission.no_permission_event"),
|
||||||
|
Template.of("node", "plots.admin.pve." + stub)
|
||||||
|
);
|
||||||
|
if (plot != null) {
|
||||||
|
plot.debug(player.getName() + " could not attack " + entityType
|
||||||
|
+ " because pve = false");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} else if (dplot != null && (!dplot.equals(vplot) || Objects
|
||||||
|
.equals(dplot.getOwnerAbs(), vplot.getOwnerAbs()))) {
|
||||||
|
return vplot != null && vplot.getFlag(PveFlag.class);
|
||||||
|
}
|
||||||
|
//disable the firework damage. too much of a headache to support at the moment.
|
||||||
|
if (vplot != null) {
|
||||||
|
if (EntityDamageEvent.DamageCause.ENTITY_EXPLOSION == cause
|
||||||
|
&& damager.getType() == EntityType.FIREWORK) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (vplot == null && roadFlags && area.getRoadFlag(PveFlag.class)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return ((vplot != null && vplot.getFlag(PveFlag.class)) || !(damager instanceof Arrow
|
||||||
|
&& !(victim instanceof Creature)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean checkEntity(Entity entity, Plot plot) {
|
||||||
|
if (plot == null || !plot.hasOwner() || plot.getFlags().isEmpty() && plot.getArea()
|
||||||
|
.getFlagContainer().getFlagMap().isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final com.sk89q.worldedit.world.entity.EntityType entityType =
|
||||||
|
BukkitAdapter.adapt(entity.getType());
|
||||||
|
|
||||||
|
if (EntityCategories.PLAYER.contains(entityType)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EntityCategories.PROJECTILE.contains(entityType) || EntityCategories.OTHER
|
||||||
|
.contains(entityType) || EntityCategories.HANGING.contains(entityType)) {
|
||||||
|
return EntityUtil.checkEntity(plot, EntityCapFlag.ENTITY_CAP_UNLIMITED,
|
||||||
|
MiscCapFlag.MISC_CAP_UNLIMITED);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Has to go go before vehicle as horses are both
|
||||||
|
// animals and vehicles
|
||||||
|
if (EntityCategories.ANIMAL.contains(entityType) || EntityCategories.VILLAGER
|
||||||
|
.contains(entityType) || EntityCategories.TAMEABLE.contains(entityType)) {
|
||||||
|
return EntityUtil
|
||||||
|
.checkEntity(plot, EntityCapFlag.ENTITY_CAP_UNLIMITED, MobCapFlag.MOB_CAP_UNLIMITED,
|
||||||
|
AnimalCapFlag.ANIMAL_CAP_UNLIMITED);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EntityCategories.HOSTILE.contains(entityType)) {
|
||||||
|
return EntityUtil
|
||||||
|
.checkEntity(plot, EntityCapFlag.ENTITY_CAP_UNLIMITED, MobCapFlag.MOB_CAP_UNLIMITED,
|
||||||
|
HostileCapFlag.HOSTILE_CAP_UNLIMITED);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EntityCategories.VEHICLE.contains(entityType)) {
|
||||||
|
return EntityUtil.checkEntity(plot, EntityCapFlag.ENTITY_CAP_UNLIMITED,
|
||||||
|
VehicleCapFlag.VEHICLE_CAP_UNLIMITED);
|
||||||
|
}
|
||||||
|
|
||||||
|
return EntityUtil.checkEntity(plot, EntityCapFlag.ENTITY_CAP_UNLIMITED);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -27,29 +27,24 @@ package com.plotsquared.bukkit.util;
|
|||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Singleton;
|
import com.google.inject.Singleton;
|
||||||
import com.plotsquared.bukkit.BukkitPlatform;
|
|
||||||
import com.plotsquared.core.PlotSquared;
|
|
||||||
import com.plotsquared.core.generator.AugmentedUtils;
|
import com.plotsquared.core.generator.AugmentedUtils;
|
||||||
import com.plotsquared.core.location.Location;
|
import com.plotsquared.core.location.Location;
|
||||||
import com.plotsquared.core.location.PlotLoc;
|
import com.plotsquared.core.location.PlotLoc;
|
||||||
import com.plotsquared.core.plot.Plot;
|
import com.plotsquared.core.plot.Plot;
|
||||||
import com.plotsquared.core.plot.PlotArea;
|
import com.plotsquared.core.plot.PlotArea;
|
||||||
import com.plotsquared.core.plot.PlotManager;
|
import com.plotsquared.core.plot.PlotManager;
|
||||||
import com.plotsquared.core.queue.LocalBlockQueue;
|
import com.plotsquared.core.queue.GlobalBlockQueue;
|
||||||
import com.plotsquared.core.queue.ScopedLocalBlockQueue;
|
import com.plotsquared.core.queue.QueueCoordinator;
|
||||||
|
import com.plotsquared.core.queue.ScopedQueueCoordinator;
|
||||||
import com.plotsquared.core.util.ChunkManager;
|
import com.plotsquared.core.util.ChunkManager;
|
||||||
import com.plotsquared.core.util.RegionManager;
|
import com.plotsquared.core.util.RegionManager;
|
||||||
import com.plotsquared.core.util.RegionUtil;
|
import com.plotsquared.core.util.RegionUtil;
|
||||||
import com.plotsquared.core.util.WorldUtil;
|
import com.plotsquared.core.util.WorldUtil;
|
||||||
import com.plotsquared.core.util.entity.EntityCategories;
|
import com.plotsquared.core.util.entity.EntityCategories;
|
||||||
import com.plotsquared.core.util.task.RunnableVal;
|
import com.plotsquared.core.util.task.RunnableVal;
|
||||||
import com.plotsquared.core.util.task.TaskManager;
|
|
||||||
import com.plotsquared.core.util.task.TaskTime;
|
|
||||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||||
import com.sk89q.worldedit.bukkit.BukkitWorld;
|
import com.sk89q.worldedit.bukkit.BukkitWorld;
|
||||||
import com.sk89q.worldedit.math.BlockVector2;
|
|
||||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
|
||||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||||
import io.papermc.lib.PaperLib;
|
import io.papermc.lib.PaperLib;
|
||||||
@ -62,16 +57,11 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import java.util.ArrayDeque;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.Semaphore;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
import static com.plotsquared.core.util.entity.EntityCategories.CAP_ANIMAL;
|
import static com.plotsquared.core.util.entity.EntityCategories.CAP_ANIMAL;
|
||||||
import static com.plotsquared.core.util.entity.EntityCategories.CAP_ENTITY;
|
import static com.plotsquared.core.util.entity.EntityCategories.CAP_ENTITY;
|
||||||
import static com.plotsquared.core.util.entity.EntityCategories.CAP_MISC;
|
import static com.plotsquared.core.util.entity.EntityCategories.CAP_MISC;
|
||||||
@ -79,44 +69,17 @@ import static com.plotsquared.core.util.entity.EntityCategories.CAP_MOB;
|
|||||||
import static com.plotsquared.core.util.entity.EntityCategories.CAP_MONSTER;
|
import static com.plotsquared.core.util.entity.EntityCategories.CAP_MONSTER;
|
||||||
import static com.plotsquared.core.util.entity.EntityCategories.CAP_VEHICLE;
|
import static com.plotsquared.core.util.entity.EntityCategories.CAP_VEHICLE;
|
||||||
|
|
||||||
@Singleton public class BukkitRegionManager extends RegionManager {
|
@Singleton
|
||||||
|
public class BukkitRegionManager extends RegionManager {
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger("P2/" + BukkitRegionManager.class.getSimpleName());
|
private static final Logger logger =
|
||||||
|
LoggerFactory.getLogger("P2/" + BukkitRegionManager.class.getSimpleName());
|
||||||
|
private final GlobalBlockQueue blockQueue;
|
||||||
|
|
||||||
@Inject public BukkitRegionManager(@Nonnull final ChunkManager chunkManager) {
|
@Inject
|
||||||
super(chunkManager);
|
public BukkitRegionManager(@Nonnull WorldUtil worldUtil, @Nonnull GlobalBlockQueue blockQueue) {
|
||||||
}
|
super(worldUtil, blockQueue);
|
||||||
|
this.blockQueue = blockQueue;
|
||||||
public static boolean isIn(CuboidRegion region, int x, int z) {
|
|
||||||
return x >= region.getMinimumPoint().getX() && x <= region.getMaximumPoint().getX()
|
|
||||||
&& z >= region.getMinimumPoint().getZ() && z <= region.getMaximumPoint().getZ();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public Set<BlockVector2> getChunkChunks(String world) {
|
|
||||||
Set<BlockVector2> chunks = super.getChunkChunks(world);
|
|
||||||
if (Bukkit.isPrimaryThread()) {
|
|
||||||
for (Chunk chunk : Objects.requireNonNull(Bukkit.getWorld(world)).getLoadedChunks()) {
|
|
||||||
BlockVector2 loc = BlockVector2.at(chunk.getX() >> 5, chunk.getZ() >> 5);
|
|
||||||
chunks.add(loc);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
final Semaphore semaphore = new Semaphore(1);
|
|
||||||
try {
|
|
||||||
semaphore.acquire();
|
|
||||||
Bukkit.getScheduler().runTask(BukkitPlatform.getPlugin(BukkitPlatform.class), () -> {
|
|
||||||
for (Chunk chunk : Objects.requireNonNull(Bukkit.getWorld(world))
|
|
||||||
.getLoadedChunks()) {
|
|
||||||
BlockVector2 loc = BlockVector2.at(chunk.getX() >> 5, chunk.getZ() >> 5);
|
|
||||||
chunks.add(loc);
|
|
||||||
}
|
|
||||||
semaphore.release();
|
|
||||||
});
|
|
||||||
semaphore.acquireUninterruptibly();
|
|
||||||
} catch (final Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return chunks;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean handleClear(Plot plot, Runnable whenDone, PlotManager manager) {
|
@Override public boolean handleClear(Plot plot, Runnable whenDone, PlotManager manager) {
|
||||||
@ -131,7 +94,6 @@ import static com.plotsquared.core.util.entity.EntityCategories.CAP_VEHICLE;
|
|||||||
}
|
}
|
||||||
PlotArea area = plot.getArea();
|
PlotArea area = plot.getArea();
|
||||||
World world = BukkitUtil.getWorld(area.getWorldName());
|
World world = BukkitUtil.getWorld(area.getWorldName());
|
||||||
|
|
||||||
Location bot = plot.getBottomAbs();
|
Location bot = plot.getBottomAbs();
|
||||||
Location top = plot.getTopAbs();
|
Location top = plot.getTopAbs();
|
||||||
int bx = bot.getX() >> 4;
|
int bx = bot.getX() >> 4;
|
||||||
@ -199,65 +161,9 @@ import static com.plotsquared.core.util.entity.EntityCategories.CAP_VEHICLE;
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override public boolean regenerateRegion(final Location pos1, final Location pos2,
|
||||||
public boolean copyRegion(Location pos1, Location pos2, Location newPos,
|
|
||||||
final Runnable whenDone) {
|
|
||||||
final int relX = newPos.getX() - pos1.getX();
|
|
||||||
final int relZ = newPos.getZ() - pos1.getZ();
|
|
||||||
|
|
||||||
final CuboidRegion region =
|
|
||||||
RegionUtil.createRegion(pos1.getX(), pos2.getX(), pos1.getZ(), pos2.getZ());
|
|
||||||
final World oldWorld = Bukkit.getWorld(pos1.getWorldName());
|
|
||||||
final BukkitWorld oldBukkitWorld = new BukkitWorld(oldWorld);
|
|
||||||
final World newWorld = Bukkit.getWorld(newPos.getWorldName());
|
|
||||||
assert newWorld != null;
|
|
||||||
assert oldWorld != null;
|
|
||||||
final String newWorldName = newWorld.getName();
|
|
||||||
final ContentMap map = new ContentMap();
|
|
||||||
final LocalBlockQueue queue = PlotSquared.platform().getGlobalBlockQueue().getNewQueue(newWorldName, false);
|
|
||||||
ChunkManager.chunkTask(pos1, pos2, new RunnableVal<int[]>() {
|
|
||||||
@Override public void run(int[] value) {
|
|
||||||
int bx = value[2];
|
|
||||||
int bz = value[3];
|
|
||||||
int tx = value[4];
|
|
||||||
int tz = value[5];
|
|
||||||
BlockVector2 loc = BlockVector2.at(value[0], value[1]);
|
|
||||||
int cxx = loc.getX() << 4;
|
|
||||||
int czz = loc.getZ() << 4;
|
|
||||||
PaperLib.getChunkAtAsync(oldWorld, loc.getX(), loc.getZ())
|
|
||||||
.thenAccept(chunk1 -> map.saveEntitiesIn(chunk1, region)).thenRun(() -> {
|
|
||||||
for (int x = bx & 15; x <= (tx & 15); x++) {
|
|
||||||
for (int z = bz & 15; z <= (tz & 15); z++) {
|
|
||||||
map.saveBlocks(oldBukkitWorld, 256, cxx + x, czz + z, relX, relZ);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, () -> {
|
|
||||||
for (Entry<PlotLoc, BaseBlock[]> entry : map.allBlocks.entrySet()) {
|
|
||||||
PlotLoc loc = entry.getKey();
|
|
||||||
BaseBlock[] blocks = entry.getValue();
|
|
||||||
for (int y = 0; y < blocks.length; y++) {
|
|
||||||
if (blocks[y] != null) {
|
|
||||||
BaseBlock block = blocks[y];
|
|
||||||
queue.setBlock(loc.getX(), y, loc.getZ(), block);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
queue.enqueue();
|
|
||||||
PlotSquared.platform().getGlobalBlockQueue().addEmptyTask(() -> {
|
|
||||||
//map.restoreBlocks(newWorld, 0, 0);
|
|
||||||
map.restoreEntities(newWorld, relX, relZ);
|
|
||||||
TaskManager.runTask(whenDone);
|
|
||||||
});
|
|
||||||
}, 5);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean regenerateRegion(final Location pos1, final Location pos2,
|
|
||||||
final boolean ignoreAugment, final Runnable whenDone) {
|
final boolean ignoreAugment, final Runnable whenDone) {
|
||||||
final String world = pos1.getWorldName();
|
final BukkitWorld world = new BukkitWorld((World) pos1.getWorld());
|
||||||
|
|
||||||
final int p1x = pos1.getX();
|
final int p1x = pos1.getX();
|
||||||
final int p1z = pos1.getZ();
|
final int p1z = pos1.getZ();
|
||||||
@ -268,36 +174,21 @@ import static com.plotsquared.core.util.entity.EntityCategories.CAP_VEHICLE;
|
|||||||
final int tcx = p2x >> 4;
|
final int tcx = p2x >> 4;
|
||||||
final int tcz = p2z >> 4;
|
final int tcz = p2z >> 4;
|
||||||
|
|
||||||
final List<BlockVector2> chunks = new ArrayList<>();
|
final QueueCoordinator queue = blockQueue.getNewQueue(world);
|
||||||
|
final QueueCoordinator regenQueue = blockQueue.getNewQueue(world);
|
||||||
|
queue.addReadChunks(
|
||||||
|
new CuboidRegion(pos1.getBlockVector3(), pos2.getBlockVector3()).getChunks());
|
||||||
|
queue.setChunkConsumer(chunk -> {
|
||||||
|
|
||||||
for (int x = bcx; x <= tcx; x++) {
|
|
||||||
for (int z = bcz; z <= tcz; z++) {
|
|
||||||
chunks.add(BlockVector2.at(x, z));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
final World worldObj = Bukkit.getWorld(world);
|
|
||||||
checkNotNull(worldObj, "Critical error during regeneration.");
|
|
||||||
final BukkitWorld bukkitWorldObj = new BukkitWorld(worldObj);
|
|
||||||
TaskManager.runTask(new Runnable() {
|
|
||||||
@Override public void run() {
|
|
||||||
long start = System.currentTimeMillis();
|
|
||||||
while (!chunks.isEmpty() && System.currentTimeMillis() - start < 5) {
|
|
||||||
final BlockVector2 chunk = chunks.remove(0);
|
|
||||||
int x = chunk.getX();
|
int x = chunk.getX();
|
||||||
int z = chunk.getZ();
|
int z = chunk.getZ();
|
||||||
int xxb = x << 4;
|
int xxb = x << 4;
|
||||||
int zzb = z << 4;
|
int zzb = z << 4;
|
||||||
int xxt = xxb + 15;
|
int xxt = xxb + 15;
|
||||||
int zzt = zzb + 15;
|
int zzt = zzb + 15;
|
||||||
PaperLib.getChunkAtAsync(worldObj, x, z, false).thenAccept(chunkObj -> {
|
|
||||||
if (chunkObj == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final LocalBlockQueue queue = PlotSquared.platform().getGlobalBlockQueue()
|
|
||||||
.getNewQueue(world, false);
|
|
||||||
if (xxb >= p1x && xxt <= p2x && zzb >= p1z && zzt <= p2z) {
|
if (xxb >= p1x && xxt <= p2x && zzb >= p1z && zzt <= p2z) {
|
||||||
AugmentedUtils.bypass(ignoreAugment,
|
AugmentedUtils
|
||||||
() -> queue.regenChunkSafe(chunk.getX(), chunk.getZ()));
|
.bypass(ignoreAugment, () -> regenQueue.regenChunk(chunk.getX(), chunk.getZ()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
boolean checkX1 = false;
|
boolean checkX1 = false;
|
||||||
@ -336,35 +227,36 @@ import static com.plotsquared.core.util.entity.EntityCategories.CAP_VEHICLE;
|
|||||||
}
|
}
|
||||||
final ContentMap map = new ContentMap();
|
final ContentMap map = new ContentMap();
|
||||||
if (checkX1) {
|
if (checkX1) {
|
||||||
map.saveRegion(bukkitWorldObj, xxb, xxb2, zzb2, zzt2); //
|
map.saveRegion(world, xxb, xxb2, zzb2, zzt2); //
|
||||||
}
|
}
|
||||||
if (checkX2) {
|
if (checkX2) {
|
||||||
map.saveRegion(bukkitWorldObj, xxt2, xxt, zzb2, zzt2); //
|
map.saveRegion(world, xxt2, xxt, zzb2, zzt2); //
|
||||||
}
|
}
|
||||||
if (checkZ1) {
|
if (checkZ1) {
|
||||||
map.saveRegion(bukkitWorldObj, xxb2, xxt2, zzb, zzb2); //
|
map.saveRegion(world, xxb2, xxt2, zzb, zzb2); //
|
||||||
}
|
}
|
||||||
if (checkZ2) {
|
if (checkZ2) {
|
||||||
map.saveRegion(bukkitWorldObj, xxb2, xxt2, zzt2, zzt); //
|
map.saveRegion(world, xxb2, xxt2, zzt2, zzt); //
|
||||||
}
|
}
|
||||||
if (checkX1 && checkZ1) {
|
if (checkX1 && checkZ1) {
|
||||||
map.saveRegion(bukkitWorldObj, xxb, xxb2, zzb, zzb2); //
|
map.saveRegion(world, xxb, xxb2, zzb, zzb2); //
|
||||||
}
|
}
|
||||||
if (checkX2 && checkZ1) {
|
if (checkX2 && checkZ1) {
|
||||||
map.saveRegion(bukkitWorldObj, xxt2, xxt, zzb, zzb2); // ?
|
map.saveRegion(world, xxt2, xxt, zzb, zzb2); // ?
|
||||||
}
|
}
|
||||||
if (checkX1 && checkZ2) {
|
if (checkX1 && checkZ2) {
|
||||||
map.saveRegion(bukkitWorldObj, xxb, xxb2, zzt2, zzt); // ?
|
map.saveRegion(world, xxb, xxb2, zzt2, zzt); // ?
|
||||||
}
|
}
|
||||||
if (checkX2 && checkZ2) {
|
if (checkX2 && checkZ2) {
|
||||||
map.saveRegion(bukkitWorldObj, xxt2, xxt, zzt2, zzt); //
|
map.saveRegion(world, xxt2, xxt, zzt2, zzt); //
|
||||||
}
|
}
|
||||||
CuboidRegion currentPlotClear = RegionUtil
|
CuboidRegion currentPlotClear =
|
||||||
.createRegion(pos1.getX(), pos2.getX(), pos1.getZ(), pos2.getZ());
|
RegionUtil.createRegion(pos1.getX(), pos2.getX(), pos1.getZ(), pos2.getZ());
|
||||||
map.saveEntitiesOut(chunkObj, currentPlotClear);
|
map.saveEntitiesOut(Bukkit.getWorld(world.getName()).getChunkAt(x, z),
|
||||||
|
currentPlotClear);
|
||||||
AugmentedUtils.bypass(ignoreAugment, () -> ChunkManager
|
AugmentedUtils.bypass(ignoreAugment, () -> ChunkManager
|
||||||
.setChunkInPlotArea(null, new RunnableVal<ScopedLocalBlockQueue>() {
|
.setChunkInPlotArea(null, new RunnableVal<ScopedQueueCoordinator>() {
|
||||||
@Override public void run(ScopedLocalBlockQueue value) {
|
@Override public void run(ScopedQueueCoordinator value) {
|
||||||
Location min = value.getMin();
|
Location min = value.getMin();
|
||||||
int bx = min.getX();
|
int bx = min.getX();
|
||||||
int bz = min.getZ();
|
int bz = min.getZ();
|
||||||
@ -373,8 +265,7 @@ import static com.plotsquared.core.util.entity.EntityCategories.CAP_VEHICLE;
|
|||||||
PlotLoc plotLoc = new PlotLoc(bx + x1, bz + z1);
|
PlotLoc plotLoc = new PlotLoc(bx + x1, bz + z1);
|
||||||
BaseBlock[] ids = map.allBlocks.get(plotLoc);
|
BaseBlock[] ids = map.allBlocks.get(plotLoc);
|
||||||
if (ids != null) {
|
if (ids != null) {
|
||||||
for (int y = 0;
|
for (int y = 0; y < Math.min(128, ids.length); y++) {
|
||||||
y < Math.min(128, ids.length); y++) {
|
|
||||||
BaseBlock id = ids[y];
|
BaseBlock id = ids[y];
|
||||||
if (id != null) {
|
if (id != null) {
|
||||||
value.setBlock(x1, y, z1, id);
|
value.setBlock(x1, y, z1, id);
|
||||||
@ -383,8 +274,7 @@ import static com.plotsquared.core.util.entity.EntityCategories.CAP_VEHICLE;
|
|||||||
BlockTypes.AIR.getDefaultState());
|
BlockTypes.AIR.getDefaultState());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int y = Math.min(128, ids.length);
|
for (int y = Math.min(128, ids.length); y < ids.length; y++) {
|
||||||
y < ids.length; y++) {
|
|
||||||
BaseBlock id = ids[y];
|
BaseBlock id = ids[y];
|
||||||
if (id != null) {
|
if (id != null) {
|
||||||
value.setBlock(x1, y, z1, id);
|
value.setBlock(x1, y, z1, id);
|
||||||
@ -394,18 +284,13 @@ import static com.plotsquared.core.util.entity.EntityCategories.CAP_VEHICLE;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, world, chunk));
|
}, world.getName(), chunk));
|
||||||
//map.restoreBlocks(worldObj, 0, 0);
|
//map.restoreBlocks(worldObj, 0, 0);
|
||||||
map.restoreEntities(worldObj, 0, 0);
|
map.restoreEntities(Bukkit.getWorld(world.getName()), 0, 0);
|
||||||
});
|
|
||||||
}
|
|
||||||
if (!chunks.isEmpty()) {
|
|
||||||
TaskManager.runTaskLater(this, TaskTime.ticks(1L));
|
|
||||||
} else {
|
|
||||||
TaskManager.runTaskLater(whenDone, TaskTime.ticks(1L));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
regenQueue.setCompleteTask(whenDone);
|
||||||
|
queue.setCompleteTask(regenQueue::enqueue);
|
||||||
|
queue.enqueue();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -438,59 +323,6 @@ import static com.plotsquared.core.util.entity.EntityCategories.CAP_VEHICLE;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void swap(Location bot1, Location top1, Location bot2, Location top2,
|
|
||||||
final Runnable whenDone) {
|
|
||||||
CuboidRegion region1 =
|
|
||||||
RegionUtil.createRegion(bot1.getX(), top1.getX(), bot1.getZ(), top1.getZ());
|
|
||||||
CuboidRegion region2 =
|
|
||||||
RegionUtil.createRegion(bot2.getX(), top2.getX(), bot2.getZ(), top2.getZ());
|
|
||||||
final World world1 = Bukkit.getWorld(bot1.getWorldName());
|
|
||||||
final World world2 = Bukkit.getWorld(bot2.getWorldName());
|
|
||||||
checkNotNull(world1, "Critical error during swap.");
|
|
||||||
checkNotNull(world2, "Critical error during swap.");
|
|
||||||
int relX = bot2.getX() - bot1.getX();
|
|
||||||
int relZ = bot2.getZ() - bot1.getZ();
|
|
||||||
|
|
||||||
final ArrayDeque<ContentMap> maps = new ArrayDeque<>();
|
|
||||||
|
|
||||||
for (int x = bot1.getX() >> 4; x <= top1.getX() >> 4; x++) {
|
|
||||||
for (int z = bot1.getZ() >> 4; z <= top1.getZ() >> 4; z++) {
|
|
||||||
Chunk chunk1 = world1.getChunkAt(x, z);
|
|
||||||
Chunk chunk2 = world2.getChunkAt(x + (relX >> 4), z + (relZ >> 4));
|
|
||||||
maps.add(
|
|
||||||
BukkitChunkManager.swapChunk(world1, world2, chunk1, chunk2, region1, region2));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PlotSquared.platform().getGlobalBlockQueue().addEmptyTask(() -> {
|
|
||||||
for (ContentMap map : maps) {
|
|
||||||
map.restoreEntities(world1, 0, 0);
|
|
||||||
TaskManager.runTaskLater(whenDone, TaskTime.ticks(1L));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setBiome(final CuboidRegion region, final int extendBiome, final BiomeType biome,
|
|
||||||
final String world, final Runnable whenDone) {
|
|
||||||
Location pos1 = Location.at(world, region.getMinimumPoint().getX() - extendBiome,
|
|
||||||
region.getMinimumPoint().getY(), region.getMinimumPoint().getZ() - extendBiome);
|
|
||||||
Location pos2 = Location.at(world, region.getMaximumPoint().getX() + extendBiome,
|
|
||||||
region.getMaximumPoint().getY(), region.getMaximumPoint().getZ() + extendBiome);
|
|
||||||
final LocalBlockQueue queue = PlotSquared.platform().getGlobalBlockQueue()
|
|
||||||
.getNewQueue(world, false);
|
|
||||||
|
|
||||||
ChunkManager.chunkTask(pos1, pos2, new RunnableVal<int[]>() {
|
|
||||||
@Override public void run(int[] value) {
|
|
||||||
BlockVector2 loc = BlockVector2.at(value[0], value[1]);
|
|
||||||
PlotSquared.platform().getChunkManager().loadChunk(world, loc, false).thenRun(() -> {
|
|
||||||
WorldUtil.setBiome(world, value[2], value[3], value[4], value[5], biome);
|
|
||||||
queue.refreshChunk(value[0], value[1]);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, whenDone, 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void count(int[] count, Entity entity) {
|
private void count(int[] count, Entity entity) {
|
||||||
final com.sk89q.worldedit.world.entity.EntityType entityType =
|
final com.sk89q.worldedit.world.entity.EntityType entityType =
|
||||||
BukkitAdapter.adapt(entity.getType());
|
BukkitAdapter.adapt(entity.getType());
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.plotsquared.bukkit.util;
|
package com.plotsquared.bukkit.util;
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
|
||||||
import com.google.inject.Singleton;
|
import com.google.inject.Singleton;
|
||||||
import com.plotsquared.bukkit.BukkitPlatform;
|
import com.plotsquared.bukkit.BukkitPlatform;
|
||||||
import com.plotsquared.bukkit.player.BukkitPlayer;
|
import com.plotsquared.bukkit.player.BukkitPlayer;
|
||||||
@ -38,7 +37,6 @@ import com.plotsquared.core.player.PlotPlayer;
|
|||||||
import com.plotsquared.core.util.BlockUtil;
|
import com.plotsquared.core.util.BlockUtil;
|
||||||
import com.plotsquared.core.util.MathMan;
|
import com.plotsquared.core.util.MathMan;
|
||||||
import com.plotsquared.core.util.PlayerManager;
|
import com.plotsquared.core.util.PlayerManager;
|
||||||
import com.plotsquared.core.util.RegionManager;
|
|
||||||
import com.plotsquared.core.util.StringComparison;
|
import com.plotsquared.core.util.StringComparison;
|
||||||
import com.plotsquared.core.util.WorldUtil;
|
import com.plotsquared.core.util.WorldUtil;
|
||||||
import com.plotsquared.core.util.task.TaskManager;
|
import com.plotsquared.core.util.task.TaskManager;
|
||||||
@ -106,12 +104,14 @@ import java.util.Collection;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.Semaphore;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.IntConsumer;
|
import java.util.function.IntConsumer;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@SuppressWarnings({"unused", "WeakerAccess"})
|
@SuppressWarnings({"unused", "WeakerAccess"})
|
||||||
@Singleton public class BukkitUtil extends WorldUtil {
|
@Singleton
|
||||||
|
public class BukkitUtil extends WorldUtil {
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger("P2/" + BukkitUtil.class.getSimpleName());
|
private static final Logger logger = LoggerFactory.getLogger("P2/" + BukkitUtil.class.getSimpleName());
|
||||||
|
|
||||||
@ -121,10 +121,6 @@ import java.util.stream.Stream;
|
|||||||
|
|
||||||
private final Collection<BlockType> tileEntityTypes = new HashSet<>();
|
private final Collection<BlockType> tileEntityTypes = new HashSet<>();
|
||||||
|
|
||||||
@Inject public BukkitUtil(@Nonnull final RegionManager regionManager) {
|
|
||||||
super(regionManager);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Turn a Bukkit {@link Player} into a PlotSquared {@link PlotPlayer}
|
* Turn a Bukkit {@link Player} into a PlotSquared {@link PlotPlayer}
|
||||||
*
|
*
|
||||||
@ -144,8 +140,9 @@ import java.util.stream.Stream;
|
|||||||
* @return PlotSquared location
|
* @return PlotSquared location
|
||||||
*/
|
*/
|
||||||
@Nonnull public static Location adapt(@Nonnull final org.bukkit.Location location) {
|
@Nonnull public static Location adapt(@Nonnull final org.bukkit.Location location) {
|
||||||
return Location.at(com.plotsquared.bukkit.util.BukkitWorld.of(location.getWorld()),
|
return Location
|
||||||
MathMan.roundInt(location.getX()), MathMan.roundInt(location.getY()), MathMan.roundInt(location.getZ()));
|
.at(com.plotsquared.bukkit.util.BukkitWorld.of(location.getWorld()), MathMan.roundInt(location.getX()), MathMan.roundInt(location.getY()),
|
||||||
|
MathMan.roundInt(location.getZ()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -156,9 +153,9 @@ import java.util.stream.Stream;
|
|||||||
* @return PlotSquared location
|
* @return PlotSquared location
|
||||||
*/
|
*/
|
||||||
@Nonnull public static Location adaptComplete(@Nonnull final org.bukkit.Location location) {
|
@Nonnull public static Location adaptComplete(@Nonnull final org.bukkit.Location location) {
|
||||||
return Location.at(com.plotsquared.bukkit.util.BukkitWorld.of(location.getWorld()),
|
return Location
|
||||||
MathMan.roundInt(location.getX()), MathMan.roundInt(location.getY()), MathMan.roundInt(location.getZ()), location.getYaw(),
|
.at(com.plotsquared.bukkit.util.BukkitWorld.of(location.getWorld()), MathMan.roundInt(location.getX()), MathMan.roundInt(location.getY()),
|
||||||
location.getPitch());
|
MathMan.roundInt(location.getZ()), location.getYaw(), location.getPitch());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -169,8 +166,7 @@ import java.util.stream.Stream;
|
|||||||
* @return Bukkit location
|
* @return Bukkit location
|
||||||
*/
|
*/
|
||||||
@Nonnull public static org.bukkit.Location adapt(@Nonnull final Location location) {
|
@Nonnull public static org.bukkit.Location adapt(@Nonnull final Location location) {
|
||||||
return new org.bukkit.Location((World) location.getWorld().getPlatformWorld(), location.getX(),
|
return new org.bukkit.Location((World) location.getWorld().getPlatformWorld(), location.getX(), location.getY(), location.getZ());
|
||||||
location.getY(), location.getZ());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -183,30 +179,24 @@ import java.util.stream.Stream;
|
|||||||
return Bukkit.getWorld(string);
|
return Bukkit.getWorld(string);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ensureLoaded(@Nonnull final String world, final int x, final int z,
|
private static void ensureLoaded(@Nonnull final String world, final int x, final int z, @Nonnull final Consumer<Chunk> chunkConsumer) {
|
||||||
@Nonnull final Consumer<Chunk> chunkConsumer) {
|
PaperLib.getChunkAtAsync(Objects.requireNonNull(getWorld(world)), x >> 4, z >> 4, true)
|
||||||
PaperLib.getChunkAtAsync(Objects.requireNonNull(getWorld(world)),
|
|
||||||
x >> 4, z >> 4, true)
|
|
||||||
.thenAccept(chunk -> ensureMainThread(chunkConsumer, chunk));
|
.thenAccept(chunk -> ensureMainThread(chunkConsumer, chunk));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ensureLoaded(@Nonnull final Location location, @Nonnull final Consumer<Chunk> chunkConsumer) {
|
private static void ensureLoaded(@Nonnull final Location location, @Nonnull final Consumer<Chunk> chunkConsumer) {
|
||||||
PaperLib.getChunkAtAsync(adapt(location), true)
|
PaperLib.getChunkAtAsync(adapt(location), true).thenAccept(chunk -> ensureMainThread(chunkConsumer, chunk));
|
||||||
.thenAccept(chunk -> ensureMainThread(chunkConsumer, chunk));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <T> void ensureMainThread(@Nonnull final Consumer<T> consumer,
|
private static <T> void ensureMainThread(@Nonnull final Consumer<T> consumer, @Nonnull final T value) {
|
||||||
@Nonnull final T value) {
|
|
||||||
if (Bukkit.isPrimaryThread()) {
|
if (Bukkit.isPrimaryThread()) {
|
||||||
consumer.accept(value);
|
consumer.accept(value);
|
||||||
} else {
|
} else {
|
||||||
Bukkit.getScheduler()
|
Bukkit.getScheduler().runTask(BukkitPlatform.getPlugin(BukkitPlatform.class), () -> consumer.accept(value));
|
||||||
.runTask(BukkitPlatform.getPlugin(BukkitPlatform.class), () -> consumer.accept(value));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean isBlockSame(@Nonnull final BlockState block1,
|
@Override public boolean isBlockSame(@Nonnull final BlockState block1, @Nonnull final BlockState block2) {
|
||||||
@Nonnull final BlockState block2) {
|
|
||||||
if (block1.equals(block2)) {
|
if (block1.equals(block2)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -219,20 +209,15 @@ import java.util.stream.Stream;
|
|||||||
return getWorld(worldName) != null;
|
return getWorld(worldName) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void getBiome(@Nonnull final String world, final int x,
|
@Override public void getBiome(@Nonnull final String world, final int x, final int z, @Nonnull final Consumer<BiomeType> result) {
|
||||||
final int z, @Nonnull final Consumer<BiomeType> result) {
|
ensureLoaded(world, x, z, chunk -> result.accept(BukkitAdapter.adapt(getWorld(world).getBiome(x, z))));
|
||||||
ensureLoaded(world, x, z,
|
|
||||||
chunk -> result.accept(BukkitAdapter.adapt(getWorld(world).getBiome(x, z))));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override @Nonnull public BiomeType getBiomeSynchronous(@Nonnull final String world,
|
@Override @Nonnull public BiomeType getBiomeSynchronous(@Nonnull final String world, final int x, final int z) {
|
||||||
final int x, final int z) {
|
|
||||||
return BukkitAdapter.adapt(Objects.requireNonNull(getWorld(world)).getBiome(x, z));
|
return BukkitAdapter.adapt(Objects.requireNonNull(getWorld(world)).getBiome(x, z));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override public void getHighestBlock(@Nonnull final String world, final int x, final int z, @Nonnull final IntConsumer result) {
|
||||||
public void getHighestBlock(@Nonnull final String world, final int x, final int z,
|
|
||||||
@Nonnull final IntConsumer result) {
|
|
||||||
ensureLoaded(world, x, z, chunk -> {
|
ensureLoaded(world, x, z, chunk -> {
|
||||||
final World bukkitWorld = Objects.requireNonNull(getWorld(world));
|
final World bukkitWorld = Objects.requireNonNull(getWorld(world));
|
||||||
// Skip top and bottom block
|
// Skip top and bottom block
|
||||||
@ -258,9 +243,7 @@ import java.util.stream.Stream;
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override @Nonnegative
|
@Override @Nonnegative public int getHighestBlockSynchronous(@Nonnull final String world, final int x, final int z) {
|
||||||
public int getHighestBlockSynchronous(@Nonnull final String world,
|
|
||||||
final int x, final int z) {
|
|
||||||
final World bukkitWorld = Objects.requireNonNull(getWorld(world));
|
final World bukkitWorld = Objects.requireNonNull(getWorld(world));
|
||||||
// Skip top and bottom block
|
// Skip top and bottom block
|
||||||
int air = 1;
|
int air = 1;
|
||||||
@ -282,10 +265,8 @@ import java.util.stream.Stream;
|
|||||||
return bukkitWorld.getMaxHeight() - 1;
|
return bukkitWorld.getMaxHeight() - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override @Nonnull
|
@Override @Nonnull public String[] getSignSynchronous(@Nonnull final Location location) {
|
||||||
public String[] getSignSynchronous(@Nonnull final Location location) {
|
Block block = Objects.requireNonNull(getWorld(location.getWorldName())).getBlockAt(location.getX(), location.getY(), location.getZ());
|
||||||
Block block = Objects.requireNonNull(getWorld(location.getWorldName()))
|
|
||||||
.getBlockAt(location.getX(), location.getY(), location.getZ());
|
|
||||||
try {
|
try {
|
||||||
return TaskManager.getPlatformImplementation().sync(() -> {
|
return TaskManager.getPlatformImplementation().sync(() -> {
|
||||||
if (block.getState() instanceof Sign) {
|
if (block.getState() instanceof Sign) {
|
||||||
@ -300,11 +281,9 @@ import java.util.stream.Stream;
|
|||||||
return new String[0];
|
return new String[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override @Nonnull
|
@Override @Nonnull public Location getSpawn(@Nonnull final String world) {
|
||||||
public Location getSpawn(@Nonnull final String world) {
|
|
||||||
final org.bukkit.Location temp = getWorld(world).getSpawnLocation();
|
final org.bukkit.Location temp = getWorld(world).getSpawnLocation();
|
||||||
return Location.at(world, temp.getBlockX(), temp.getBlockY(), temp.getBlockZ(),
|
return Location.at(world, temp.getBlockX(), temp.getBlockY(), temp.getBlockZ(), temp.getYaw(), temp.getPitch());
|
||||||
temp.getYaw(), temp.getPitch());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void setSpawn(@Nonnull final Location location) {
|
@Override public void setSpawn(@Nonnull final Location location) {
|
||||||
@ -362,16 +341,12 @@ import java.util.stream.Stream;
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override @Nonnull
|
@Override @Nonnull public StringComparison<BlockState>.ComparisonResult getClosestBlock(@Nonnull String name) {
|
||||||
public StringComparison<BlockState>.ComparisonResult getClosestBlock(@Nonnull String name) {
|
|
||||||
BlockState state = BlockUtil.get(name);
|
BlockState state = BlockUtil.get(name);
|
||||||
return new StringComparison<BlockState>().new ComparisonResult(1, state);
|
return new StringComparison<BlockState>().new ComparisonResult(1, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override public void setBiomes(@Nonnull final String worldName, @Nonnull final CuboidRegion region, @Nonnull final BiomeType biomeType) {
|
||||||
public void setBiomes(@Nonnull final String worldName,
|
|
||||||
@Nonnull final CuboidRegion region,
|
|
||||||
@Nonnull final BiomeType biomeType) {
|
|
||||||
final World world = getWorld(worldName);
|
final World world = getWorld(worldName);
|
||||||
if (world == null) {
|
if (world == null) {
|
||||||
logger.warn("[P2] An error occured while setting the biome because the world was null", new RuntimeException());
|
logger.warn("[P2] An error occured while setting the biome because the world was null", new RuntimeException());
|
||||||
@ -379,8 +354,7 @@ import java.util.stream.Stream;
|
|||||||
}
|
}
|
||||||
final Biome biome = BukkitAdapter.adapt(biomeType);
|
final Biome biome = BukkitAdapter.adapt(biomeType);
|
||||||
for (int x = region.getMinimumPoint().getX(); x <= region.getMaximumPoint().getX(); x++) {
|
for (int x = region.getMinimumPoint().getX(); x <= region.getMaximumPoint().getX(); x++) {
|
||||||
for (int z = region.getMinimumPoint().getZ();
|
for (int z = region.getMinimumPoint().getZ(); z <= region.getMaximumPoint().getZ(); z++) {
|
||||||
z <= region.getMaximumPoint().getZ(); z++) {
|
|
||||||
if (world.getBiome(x, z) != biome) {
|
if (world.getBiome(x, z) != biome) {
|
||||||
world.setBiome(x, z, biome);
|
world.setBiome(x, z, biome);
|
||||||
}
|
}
|
||||||
@ -392,50 +366,41 @@ import java.util.stream.Stream;
|
|||||||
return new BukkitWorld(Bukkit.getWorld(world));
|
return new BukkitWorld(Bukkit.getWorld(world));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override public void refreshChunk(int x, int z, String world) {
|
||||||
public void getBlock(@Nonnull final Location location,
|
Bukkit.getWorld(world).refreshChunk(x, z);
|
||||||
@Nonnull final Consumer<BlockState> result) {
|
}
|
||||||
|
|
||||||
|
@Override public void getBlock(@Nonnull final Location location, @Nonnull final Consumer<BlockState> result) {
|
||||||
ensureLoaded(location, chunk -> {
|
ensureLoaded(location, chunk -> {
|
||||||
final World world = getWorld(location.getWorldName());
|
final World world = getWorld(location.getWorldName());
|
||||||
final Block block = Objects.requireNonNull(world)
|
final Block block = Objects.requireNonNull(world).getBlockAt(location.getX(), location.getY(), location.getZ());
|
||||||
.getBlockAt(location.getX(), location.getY(), location.getZ());
|
result.accept(Objects.requireNonNull(BukkitAdapter.asBlockType(block.getType())).getDefaultState());
|
||||||
result.accept(Objects.requireNonNull(BukkitAdapter
|
|
||||||
.asBlockType(block.getType())).getDefaultState());
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override @Nonnull public BlockState getBlockSynchronous(@Nonnull final Location location) {
|
@Override @Nonnull public BlockState getBlockSynchronous(@Nonnull final Location location) {
|
||||||
final World world = getWorld(location.getWorldName());
|
final World world = getWorld(location.getWorldName());
|
||||||
final Block block = Objects.requireNonNull(world)
|
final Block block = Objects.requireNonNull(world).getBlockAt(location.getX(), location.getY(), location.getZ());
|
||||||
.getBlockAt(location.getX(), location.getY(), location.getZ());
|
return Objects.requireNonNull(BukkitAdapter.asBlockType(block.getType())).getDefaultState();
|
||||||
return Objects.requireNonNull(BukkitAdapter
|
|
||||||
.asBlockType(block.getType())).getDefaultState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override @Nonnegative public double getHealth(@Nonnull final PlotPlayer player) {
|
@Override @Nonnegative public double getHealth(@Nonnull final PlotPlayer player) {
|
||||||
return Objects.requireNonNull(Bukkit
|
return Objects.requireNonNull(Bukkit.getPlayer(player.getUUID())).getHealth();
|
||||||
.getPlayer(player.getUUID())).getHealth();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override @Nonnegative public int getFoodLevel(@Nonnull final PlotPlayer<?> player) {
|
@Override @Nonnegative public int getFoodLevel(@Nonnull final PlotPlayer<?> player) {
|
||||||
return Objects.requireNonNull(Bukkit.getPlayer(player.getUUID()))
|
return Objects.requireNonNull(Bukkit.getPlayer(player.getUUID())).getFoodLevel();
|
||||||
.getFoodLevel();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void setHealth(@Nonnull final PlotPlayer<?> player,
|
@Override public void setHealth(@Nonnull final PlotPlayer<?> player, @Nonnegative final double health) {
|
||||||
@Nonnegative final double health) {
|
Objects.requireNonNull(Bukkit.getPlayer(player.getUUID())).setHealth(health);
|
||||||
Objects.requireNonNull(Bukkit.getPlayer(player.getUUID()))
|
|
||||||
.setHealth(health);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void setFoodLevel(@Nonnull final PlotPlayer<?> player,
|
@Override public void setFoodLevel(@Nonnull final PlotPlayer<?> player, @Nonnegative final int foodLevel) {
|
||||||
@Nonnegative final int foodLevel) {
|
|
||||||
Bukkit.getPlayer(player.getUUID()).setFoodLevel(foodLevel);
|
Bukkit.getPlayer(player.getUUID()).setFoodLevel(foodLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override @Nonnull
|
@Override @Nonnull public Set<com.sk89q.worldedit.world.entity.EntityType> getTypesInCategory(@Nonnull final String category) {
|
||||||
public Set<com.sk89q.worldedit.world.entity.EntityType> getTypesInCategory(
|
|
||||||
@Nonnull final String category) {
|
|
||||||
final Collection<Class<?>> allowedInterfaces = new HashSet<>();
|
final Collection<Class<?>> allowedInterfaces = new HashSet<>();
|
||||||
switch (category) {
|
switch (category) {
|
||||||
case "animal": {
|
case "animal": {
|
||||||
@ -524,28 +489,45 @@ import java.util.stream.Stream;
|
|||||||
tileEntityTypes.addAll(BlockCategories.FLOWER_POTS.getAll());
|
tileEntityTypes.addAll(BlockCategories.FLOWER_POTS.getAll());
|
||||||
// Individual Types
|
// Individual Types
|
||||||
// Add these from strings
|
// Add these from strings
|
||||||
Stream.of("barrel", "beacon", "beehive", "bee_nest", "bell", "blast_furnace",
|
Stream.of("barrel", "beacon", "beehive", "bee_nest", "bell", "blast_furnace", "brewing_stand", "campfire", "chest", "ender_chest",
|
||||||
"brewing_stand", "campfire", "chest", "ender_chest", "trapped_chest",
|
"trapped_chest", "command_block", "end_gateway", "hopper", "jigsaw", "jubekox", "lectern", "note_block", "black_shulker_box",
|
||||||
"command_block", "end_gateway", "hopper", "jigsaw", "jubekox",
|
"blue_shulker_box", "brown_shulker_box", "cyan_shulker_box", "gray_shulker_box", "green_shulker_box", "light_blue_shulker_box",
|
||||||
"lectern", "note_block", "black_shulker_box", "blue_shulker_box",
|
"light_gray_shulker_box", "lime_shulker_box", "magenta_shulker_box", "orange_shulker_box", "pink_shulker_box", "purple_shulker_box",
|
||||||
"brown_shulker_box", "cyan_shulker_box", "gray_shulker_box", "green_shulker_box",
|
"red_shulker_box", "shulker_box", "white_shulker_box", "yellow_shulker_box", "smoker", "structure_block", "structure_void")
|
||||||
"light_blue_shulker_box", "light_gray_shulker_box", "lime_shulker_box",
|
.map(BlockTypes::get).filter(Objects::nonNull).forEach(tileEntityTypes::add);
|
||||||
"magenta_shulker_box", "orange_shulker_box", "pink_shulker_box",
|
|
||||||
"purple_shulker_box", "red_shulker_box", "shulker_box", "white_shulker_box",
|
|
||||||
"yellow_shulker_box", "smoker", "structure_block", "structure_void")
|
|
||||||
.map(BlockTypes::get)
|
|
||||||
.filter(Objects::nonNull)
|
|
||||||
.forEach(tileEntityTypes::add);
|
|
||||||
}
|
}
|
||||||
return this.tileEntityTypes;
|
return this.tileEntityTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override @Nonnegative
|
@Override @Nonnegative public int getTileEntityCount(@Nonnull final String world, @Nonnull final BlockVector2 chunk) {
|
||||||
public int getTileEntityCount(@Nonnull final String world,
|
|
||||||
@Nonnull final BlockVector2 chunk) {
|
|
||||||
return Objects.requireNonNull(getWorld(world)).
|
return Objects.requireNonNull(getWorld(world)).
|
||||||
getChunkAt(chunk.getBlockX(), chunk.getBlockZ())
|
getChunkAt(chunk.getBlockX(), chunk.getBlockZ()).getTileEntities().length;
|
||||||
.getTileEntities().length;
|
}
|
||||||
|
|
||||||
|
@Override public Set<BlockVector2> getChunkChunks(String world) {
|
||||||
|
Set<BlockVector2> chunks = super.getChunkChunks(world);
|
||||||
|
if (Bukkit.isPrimaryThread()) {
|
||||||
|
for (Chunk chunk : Objects.requireNonNull(Bukkit.getWorld(world)).getLoadedChunks()) {
|
||||||
|
BlockVector2 loc = BlockVector2.at(chunk.getX() >> 5, chunk.getZ() >> 5);
|
||||||
|
chunks.add(loc);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
final Semaphore semaphore = new Semaphore(1);
|
||||||
|
try {
|
||||||
|
semaphore.acquire();
|
||||||
|
Bukkit.getScheduler().runTask(BukkitPlatform.getPlugin(BukkitPlatform.class), () -> {
|
||||||
|
for (Chunk chunk : Objects.requireNonNull(Bukkit.getWorld(world)).getLoadedChunks()) {
|
||||||
|
BlockVector2 loc = BlockVector2.at(chunk.getX() >> 5, chunk.getZ() >> 5);
|
||||||
|
chunks.add(loc);
|
||||||
|
}
|
||||||
|
semaphore.release();
|
||||||
|
});
|
||||||
|
semaphore.acquireUninterruptibly();
|
||||||
|
} catch (final Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return chunks;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ load: STARTUP
|
|||||||
description: "Easy, yet powerful Plot World generation and management."
|
description: "Easy, yet powerful Plot World generation and management."
|
||||||
authors: [Citymonstret, Empire92, MattBDev, dordsor21, NotMyFault, SirYwell]
|
authors: [Citymonstret, Empire92, MattBDev, dordsor21, NotMyFault, SirYwell]
|
||||||
website: https://www.spigotmc.org/resources/77506/
|
website: https://www.spigotmc.org/resources/77506/
|
||||||
softdepend: [Vault, PlaceholderAPI, Essentials, LuckPerms, BungeePerms]
|
softdepend: [Vault, PlaceholderAPI, Essentials, LuckPerms, BungeePerms, MVdWPlaceholderAPI]
|
||||||
loadbefore: [MultiWorld, Multiverse-Core]
|
loadbefore: [MultiWorld, Multiverse-Core]
|
||||||
depend: [WorldEdit]
|
depend: [WorldEdit]
|
||||||
database: false
|
database: false
|
||||||
|
44
Core/pom.xml
44
Core/pom.xml
@ -48,16 +48,10 @@
|
|||||||
<version>1.0</version>
|
<version>1.0</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.projectlombok</groupId>
|
|
||||||
<artifactId>lombok</artifactId>
|
|
||||||
<version>1.18.12</version>
|
|
||||||
<scope>runtime</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.sk89q.worldedit</groupId>
|
<groupId>com.sk89q.worldedit</groupId>
|
||||||
<artifactId>worldedit-core</artifactId>
|
<artifactId>worldedit-core</artifactId>
|
||||||
<version>7.0.0</version>
|
<version>7.2.0-SNAPSHOT</version>
|
||||||
<scope>runtime</scope>
|
<scope>runtime</scope>
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
@ -74,30 +68,6 @@
|
|||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>net.kyori</groupId>
|
|
||||||
<artifactId>text-api</artifactId>
|
|
||||||
<version>3.0.2</version>
|
|
||||||
<scope>runtime</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>net.kyori</groupId>
|
|
||||||
<artifactId>text-serializer-gson</artifactId>
|
|
||||||
<version>3.0.2</version>
|
|
||||||
<scope>runtime</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>net.kyori</groupId>
|
|
||||||
<artifactId>text-serializer-legacy</artifactId>
|
|
||||||
<version>3.0.2</version>
|
|
||||||
<scope>runtime</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>net.kyori</groupId>
|
|
||||||
<artifactId>text-serializer-plain</artifactId>
|
|
||||||
<version>3.0.2</version>
|
|
||||||
<scope>runtime</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.guava</groupId>
|
<groupId>com.google.guava</groupId>
|
||||||
<artifactId>guava</artifactId>
|
<artifactId>guava</artifactId>
|
||||||
@ -128,6 +98,18 @@
|
|||||||
<version>1.7.0-SNAPSHOT</version>
|
<version>1.7.0-SNAPSHOT</version>
|
||||||
<scope>runtime</scope>
|
<scope>runtime</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.kyori</groupId>
|
||||||
|
<artifactId>adventure-api</artifactId>
|
||||||
|
<version>4.0.0-SNAPSHOT</version>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.kyori</groupId>
|
||||||
|
<artifactId>adventure-text-minimessage</artifactId>
|
||||||
|
<version>3.0.0-SNAPSHOT</version>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.logging.log4j</groupId>
|
<groupId>org.apache.logging.log4j</groupId>
|
||||||
<artifactId>log4j-slf4j-impl</artifactId>
|
<artifactId>log4j-slf4j-impl</artifactId>
|
||||||
|
@ -59,6 +59,7 @@ import com.plotsquared.core.plot.PlotId;
|
|||||||
import com.plotsquared.core.plot.PlotManager;
|
import com.plotsquared.core.plot.PlotManager;
|
||||||
import com.plotsquared.core.plot.expiration.ExpireManager;
|
import com.plotsquared.core.plot.expiration.ExpireManager;
|
||||||
import com.plotsquared.core.plot.expiration.ExpiryTask;
|
import com.plotsquared.core.plot.expiration.ExpiryTask;
|
||||||
|
import com.plotsquared.core.plot.flag.GlobalFlagContainer;
|
||||||
import com.plotsquared.core.plot.world.PlotAreaManager;
|
import com.plotsquared.core.plot.world.PlotAreaManager;
|
||||||
import com.plotsquared.core.plot.world.SinglePlotArea;
|
import com.plotsquared.core.plot.world.SinglePlotArea;
|
||||||
import com.plotsquared.core.plot.world.SinglePlotAreaManager;
|
import com.plotsquared.core.plot.world.SinglePlotAreaManager;
|
||||||
@ -67,6 +68,7 @@ import com.plotsquared.core.util.FileUtils;
|
|||||||
import com.plotsquared.core.util.LegacyConverter;
|
import com.plotsquared.core.util.LegacyConverter;
|
||||||
import com.plotsquared.core.util.MathMan;
|
import com.plotsquared.core.util.MathMan;
|
||||||
import com.plotsquared.core.util.ReflectionUtils;
|
import com.plotsquared.core.util.ReflectionUtils;
|
||||||
|
import com.plotsquared.core.util.placeholders.PlaceholderRegistry;
|
||||||
import com.plotsquared.core.util.task.TaskManager;
|
import com.plotsquared.core.util.task.TaskManager;
|
||||||
import com.plotsquared.core.uuid.UUIDPipeline;
|
import com.plotsquared.core.uuid.UUIDPipeline;
|
||||||
import com.sk89q.worldedit.WorldEdit;
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
@ -147,7 +149,7 @@ public class PlotSquared {
|
|||||||
private File storageFile;
|
private File storageFile;
|
||||||
private EventDispatcher eventDispatcher;
|
private EventDispatcher eventDispatcher;
|
||||||
private PlotListener plotListener;
|
private PlotListener plotListener;
|
||||||
|
private PlaceholderRegistry placeholderRegistry;
|
||||||
/**
|
/**
|
||||||
* Initialize PlotSquared with the desired Implementation class.
|
* Initialize PlotSquared with the desired Implementation class.
|
||||||
*
|
*
|
||||||
@ -172,6 +174,9 @@ public class PlotSquared {
|
|||||||
//
|
//
|
||||||
ConfigurationSerialization.registerClass(BlockBucket.class, "BlockBucket");
|
ConfigurationSerialization.registerClass(BlockBucket.class, "BlockBucket");
|
||||||
|
|
||||||
|
// Setup the global flag container
|
||||||
|
GlobalFlagContainer.setup();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
new ReflectionUtils(this.platform.getNMSPackage());
|
new ReflectionUtils(this.platform.getNMSPackage());
|
||||||
try {
|
try {
|
||||||
@ -1501,6 +1506,10 @@ public class PlotSquared {
|
|||||||
return this.plotListener;
|
return this.plotListener;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PlaceholderRegistry getPlaceholderRegistry() {
|
||||||
|
return this.placeholderRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
public enum SortType {
|
public enum SortType {
|
||||||
CREATION_DATE, CREATION_DATE_TIMESTAMP, LAST_MODIFIED, DISTANCE_FROM_ORIGIN
|
CREATION_DATE, CREATION_DATE_TIMESTAMP, LAST_MODIFIED, DISTANCE_FROM_ORIGIN
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,8 @@ import com.plotsquared.core.plot.PlotAreaTerrainType;
|
|||||||
import com.plotsquared.core.plot.PlotAreaType;
|
import com.plotsquared.core.plot.PlotAreaType;
|
||||||
import com.plotsquared.core.plot.PlotId;
|
import com.plotsquared.core.plot.PlotId;
|
||||||
import com.plotsquared.core.plot.world.PlotAreaManager;
|
import com.plotsquared.core.plot.world.PlotAreaManager;
|
||||||
|
import com.plotsquared.core.queue.GlobalBlockQueue;
|
||||||
|
import com.plotsquared.core.queue.QueueCoordinator;
|
||||||
import com.plotsquared.core.setup.PlotAreaBuilder;
|
import com.plotsquared.core.setup.PlotAreaBuilder;
|
||||||
import com.plotsquared.core.util.FileUtils;
|
import com.plotsquared.core.util.FileUtils;
|
||||||
import com.plotsquared.core.util.MathMan;
|
import com.plotsquared.core.util.MathMan;
|
||||||
@ -59,7 +61,6 @@ import com.plotsquared.core.util.SchematicHandler;
|
|||||||
import com.plotsquared.core.util.SetupUtils;
|
import com.plotsquared.core.util.SetupUtils;
|
||||||
import com.plotsquared.core.util.StringMan;
|
import com.plotsquared.core.util.StringMan;
|
||||||
import com.plotsquared.core.util.WorldUtil;
|
import com.plotsquared.core.util.WorldUtil;
|
||||||
import com.plotsquared.core.util.task.RunnableVal;
|
|
||||||
import com.plotsquared.core.util.task.RunnableVal3;
|
import com.plotsquared.core.util.task.RunnableVal3;
|
||||||
import com.sk89q.worldedit.EditSession;
|
import com.sk89q.worldedit.EditSession;
|
||||||
import com.sk89q.worldedit.LocalSession;
|
import com.sk89q.worldedit.LocalSession;
|
||||||
@ -70,11 +71,9 @@ import com.sk89q.worldedit.extent.clipboard.io.BuiltInClipboardFormat;
|
|||||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter;
|
import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter;
|
||||||
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
|
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
|
||||||
import com.sk89q.worldedit.function.operation.Operations;
|
import com.sk89q.worldedit.function.operation.Operations;
|
||||||
import com.sk89q.worldedit.math.BlockVector2;
|
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
|
||||||
import net.kyori.adventure.text.minimessage.Template;
|
import net.kyori.adventure.text.minimessage.Template;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
@ -107,6 +106,7 @@ public class Area extends SubCommand {
|
|||||||
private final SetupUtils setupUtils;
|
private final SetupUtils setupUtils;
|
||||||
private final WorldUtil worldUtil;
|
private final WorldUtil worldUtil;
|
||||||
private final RegionManager regionManager;
|
private final RegionManager regionManager;
|
||||||
|
private final GlobalBlockQueue blockQueue;
|
||||||
|
|
||||||
private final Map<UUID, Map<String, Object>> metaData = new HashMap<>();
|
private final Map<UUID, Map<String, Object>> metaData = new HashMap<>();
|
||||||
|
|
||||||
@ -114,9 +114,8 @@ public class Area extends SubCommand {
|
|||||||
@WorldConfig @Nonnull final YamlConfiguration worldConfiguration,
|
@WorldConfig @Nonnull final YamlConfiguration worldConfiguration,
|
||||||
@WorldFile @Nonnull final File worldFile,
|
@WorldFile @Nonnull final File worldFile,
|
||||||
@Nonnull final HybridPlotWorldFactory hybridPlotWorldFactory,
|
@Nonnull final HybridPlotWorldFactory hybridPlotWorldFactory,
|
||||||
@Nonnull final SetupUtils setupUtils,
|
@Nonnull final SetupUtils setupUtils, @Nonnull final WorldUtil worldUtil,
|
||||||
@Nonnull final WorldUtil worldUtil,
|
@Nonnull final RegionManager regionManager, @Nonnull final GlobalBlockQueue blockQueue) {
|
||||||
@Nonnull final RegionManager regionManager) {
|
|
||||||
this.plotAreaManager = plotAreaManager;
|
this.plotAreaManager = plotAreaManager;
|
||||||
this.worldConfiguration = worldConfiguration;
|
this.worldConfiguration = worldConfiguration;
|
||||||
this.worldFile = worldFile;
|
this.worldFile = worldFile;
|
||||||
@ -124,6 +123,7 @@ public class Area extends SubCommand {
|
|||||||
this.setupUtils = setupUtils;
|
this.setupUtils = setupUtils;
|
||||||
this.worldUtil = worldUtil;
|
this.worldUtil = worldUtil;
|
||||||
this.regionManager = regionManager;
|
this.regionManager = regionManager;
|
||||||
|
this.blockQueue = blockQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean onCommand(final PlotPlayer<?> player, String[] args) {
|
@Override public boolean onCommand(final PlotPlayer<?> player, String[] args) {
|
||||||
@ -146,20 +146,24 @@ public class Area extends SubCommand {
|
|||||||
player.sendMessage(TranslatableCaption.of("single.single_area_needs_name"));
|
player.sendMessage(TranslatableCaption.of("single.single_area_needs_name"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final PlotArea existingArea = this.plotAreaManager.getPlotArea(player.getLocation().getWorldName(), args[1]);
|
final PlotArea existingArea =
|
||||||
|
this.plotAreaManager.getPlotArea(player.getLocation().getWorldName(), args[1]);
|
||||||
if (existingArea != null && existingArea.getId().equalsIgnoreCase(args[1])) {
|
if (existingArea != null && existingArea.getId().equalsIgnoreCase(args[1])) {
|
||||||
player.sendMessage(TranslatableCaption.of("single.single_area_name_taken"));
|
player.sendMessage(TranslatableCaption.of("single.single_area_name_taken"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final LocalSession localSession = WorldEdit.getInstance().getSessionManager().getIfPresent(player.toActor());
|
final LocalSession localSession =
|
||||||
|
WorldEdit.getInstance().getSessionManager().getIfPresent(player.toActor());
|
||||||
if (localSession == null) {
|
if (localSession == null) {
|
||||||
player.sendMessage(TranslatableCaption.of("single.single_area_missing_selection"));
|
player.sendMessage(TranslatableCaption.of("single.single_area_missing_selection"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Region playerSelectedRegion = null;
|
Region playerSelectedRegion = null;
|
||||||
try {
|
try {
|
||||||
playerSelectedRegion = localSession.getSelection(((Player) player.toActor()).getWorld());
|
playerSelectedRegion =
|
||||||
} catch (final Exception ignored) {}
|
localSession.getSelection(((Player) player.toActor()).getWorld());
|
||||||
|
} catch (final Exception ignored) {
|
||||||
|
}
|
||||||
if (playerSelectedRegion == null) {
|
if (playerSelectedRegion == null) {
|
||||||
player.sendMessage(TranslatableCaption.of("single.single_area_missing_selection"));
|
player.sendMessage(TranslatableCaption.of("single.single_area_missing_selection"));
|
||||||
return false;
|
return false;
|
||||||
@ -176,15 +180,19 @@ public class Area extends SubCommand {
|
|||||||
final BlockVector3 playerSelectionMin = playerSelectedRegion.getMinimumPoint();
|
final BlockVector3 playerSelectionMin = playerSelectedRegion.getMinimumPoint();
|
||||||
final BlockVector3 playerSelectionMax = playerSelectedRegion.getMaximumPoint();
|
final BlockVector3 playerSelectionMax = playerSelectedRegion.getMaximumPoint();
|
||||||
// Create a new selection that spans the entire vertical range of the world
|
// Create a new selection that spans the entire vertical range of the world
|
||||||
final CuboidRegion selectedRegion = new CuboidRegion(playerSelectedRegion.getWorld(),
|
final CuboidRegion selectedRegion =
|
||||||
|
new CuboidRegion(playerSelectedRegion.getWorld(),
|
||||||
BlockVector3.at(playerSelectionMin.getX(), 0, playerSelectionMin.getZ()),
|
BlockVector3.at(playerSelectionMin.getX(), 0, playerSelectionMin.getZ()),
|
||||||
BlockVector3.at(playerSelectionMax.getX(), 255, playerSelectionMax.getZ()));
|
BlockVector3.at(playerSelectionMax.getX(), 255, playerSelectionMax.getZ()));
|
||||||
// There's only one plot in the area...
|
// There's only one plot in the area...
|
||||||
final PlotId plotId = PlotId.of(1, 1);
|
final PlotId plotId = PlotId.of(1, 1);
|
||||||
final HybridPlotWorld hybridPlotWorld = this.hybridPlotWorldFactory.create(player.getLocation().getWorldName(), args[1],
|
final HybridPlotWorld hybridPlotWorld = this.hybridPlotWorldFactory
|
||||||
Objects.requireNonNull(PlotSquared.platform()).getDefaultGenerator(), plotId, plotId);
|
.create(player.getLocation().getWorldName(), args[1],
|
||||||
|
Objects.requireNonNull(PlotSquared.platform()).getDefaultGenerator(),
|
||||||
|
plotId, plotId);
|
||||||
// Plot size is the same as the region width
|
// Plot size is the same as the region width
|
||||||
hybridPlotWorld.PLOT_WIDTH = hybridPlotWorld.SIZE = (short) selectedRegion.getWidth();
|
hybridPlotWorld.PLOT_WIDTH =
|
||||||
|
hybridPlotWorld.SIZE = (short) selectedRegion.getWidth();
|
||||||
// We use a schematic generator
|
// We use a schematic generator
|
||||||
hybridPlotWorld.setTerrain(PlotAreaTerrainType.NONE);
|
hybridPlotWorld.setTerrain(PlotAreaTerrainType.NONE);
|
||||||
// It is always a partial plot world
|
// It is always a partial plot world
|
||||||
@ -192,23 +200,30 @@ public class Area extends SubCommand {
|
|||||||
// We save the schematic :D
|
// We save the schematic :D
|
||||||
hybridPlotWorld.PLOT_SCHEMATIC = true;
|
hybridPlotWorld.PLOT_SCHEMATIC = true;
|
||||||
// Set the road width to 0
|
// Set the road width to 0
|
||||||
hybridPlotWorld.ROAD_WIDTH = hybridPlotWorld.ROAD_OFFSET_X = hybridPlotWorld.ROAD_OFFSET_Z = 0;
|
hybridPlotWorld.ROAD_WIDTH =
|
||||||
|
hybridPlotWorld.ROAD_OFFSET_X = hybridPlotWorld.ROAD_OFFSET_Z = 0;
|
||||||
// Set the plot height to the selection height
|
// Set the plot height to the selection height
|
||||||
hybridPlotWorld.PLOT_HEIGHT = hybridPlotWorld.ROAD_HEIGHT = hybridPlotWorld.WALL_HEIGHT = playerSelectionMin.getBlockY();
|
hybridPlotWorld.PLOT_HEIGHT = hybridPlotWorld.ROAD_HEIGHT =
|
||||||
|
hybridPlotWorld.WALL_HEIGHT = playerSelectionMin.getBlockY();
|
||||||
// No sign plz
|
// No sign plz
|
||||||
hybridPlotWorld.setAllowSigns(false);
|
hybridPlotWorld.setAllowSigns(false);
|
||||||
final File parentFile = FileUtils.getFile(PlotSquared.platform().getDirectory(), "schematics" + File.separator +
|
final File parentFile = FileUtils.getFile(PlotSquared.platform().getDirectory(),
|
||||||
"GEN_ROAD_SCHEMATIC" + File.separator + hybridPlotWorld.getWorldName() + File.separator +
|
"schematics" + File.separator + "GEN_ROAD_SCHEMATIC" + File.separator
|
||||||
hybridPlotWorld.getId());
|
+ hybridPlotWorld.getWorldName() + File.separator + hybridPlotWorld
|
||||||
|
.getId());
|
||||||
if (!parentFile.exists() && !parentFile.mkdirs()) {
|
if (!parentFile.exists() && !parentFile.mkdirs()) {
|
||||||
player.sendMessage(TranslatableCaption.of("single.single_area_could_not_make_directories"));
|
player.sendMessage(TranslatableCaption.of("single.single_area_could_not_make_directories"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final File file = new File(parentFile, "plot.schem");
|
final File file = new File(parentFile, "plot.schem");
|
||||||
try (final ClipboardWriter clipboardWriter = BuiltInClipboardFormat.SPONGE_SCHEMATIC.getWriter(new FileOutputStream(file))) {
|
try (final ClipboardWriter clipboardWriter = BuiltInClipboardFormat.SPONGE_SCHEMATIC
|
||||||
|
.getWriter(new FileOutputStream(file))) {
|
||||||
final BlockArrayClipboard clipboard = new BlockArrayClipboard(selectedRegion);
|
final BlockArrayClipboard clipboard = new BlockArrayClipboard(selectedRegion);
|
||||||
final EditSession editSession = WorldEdit.getInstance().getEditSessionFactory().getEditSession(selectedRegion.getWorld(), -1);
|
final EditSession editSession = WorldEdit.getInstance().getEditSessionFactory()
|
||||||
final ForwardExtentCopy forwardExtentCopy = new ForwardExtentCopy(editSession, selectedRegion, clipboard, selectedRegion.getMinimumPoint());
|
.getEditSession(selectedRegion.getWorld(), -1);
|
||||||
|
final ForwardExtentCopy forwardExtentCopy =
|
||||||
|
new ForwardExtentCopy(editSession, selectedRegion, clipboard,
|
||||||
|
selectedRegion.getMinimumPoint());
|
||||||
forwardExtentCopy.setCopyingBiomes(true);
|
forwardExtentCopy.setCopyingBiomes(true);
|
||||||
forwardExtentCopy.setCopyingEntities(true);
|
forwardExtentCopy.setCopyingEntities(true);
|
||||||
Operations.complete(forwardExtentCopy);
|
Operations.complete(forwardExtentCopy);
|
||||||
@ -232,13 +247,13 @@ public class Area extends SubCommand {
|
|||||||
// Now the schematic is saved, which is wonderful!
|
// Now the schematic is saved, which is wonderful!
|
||||||
PlotAreaBuilder singleBuilder = PlotAreaBuilder.ofPlotArea(hybridPlotWorld)
|
PlotAreaBuilder singleBuilder = PlotAreaBuilder.ofPlotArea(hybridPlotWorld)
|
||||||
.plotManager(PlotSquared.platform().getPluginName())
|
.plotManager(PlotSquared.platform().getPluginName())
|
||||||
.generatorName(PlotSquared.platform().getPluginName())
|
.generatorName(PlotSquared.platform().getPluginName()).maximumId(plotId)
|
||||||
.maximumId(plotId)
|
|
||||||
.minimumId(plotId);
|
.minimumId(plotId);
|
||||||
Runnable singleRun = () -> {
|
Runnable singleRun = () -> {
|
||||||
final String path =
|
final String path =
|
||||||
"worlds." + hybridPlotWorld.getWorldName() + ".areas." + hybridPlotWorld.getId() + '-'
|
"worlds." + hybridPlotWorld.getWorldName() + ".areas." + hybridPlotWorld
|
||||||
+ singleBuilder.minimumId() + '-' + singleBuilder.maximumId();
|
.getId() + '-' + singleBuilder.minimumId() + '-' + singleBuilder
|
||||||
|
.maximumId();
|
||||||
final int offsetX = singlePos1.getX();
|
final int offsetX = singlePos1.getX();
|
||||||
final int offsetZ = singlePos1.getZ();
|
final int offsetZ = singlePos1.getZ();
|
||||||
if (offsetX != 0) {
|
if (offsetX != 0) {
|
||||||
@ -276,8 +291,9 @@ public class Area extends SubCommand {
|
|||||||
case 2:
|
case 2:
|
||||||
switch (args[1].toLowerCase()) {
|
switch (args[1].toLowerCase()) {
|
||||||
case "pos1": { // Set position 1
|
case "pos1": { // Set position 1
|
||||||
HybridPlotWorld area = (HybridPlotWorld) metaData.computeIfAbsent(player.getUUID(), missingUUID -> new HashMap<>())
|
HybridPlotWorld area = (HybridPlotWorld) metaData
|
||||||
.get("area_create_area");
|
.computeIfAbsent(player.getUUID(),
|
||||||
|
missingUUID -> new HashMap<>()).get("area_create_area");
|
||||||
if (area == null) {
|
if (area == null) {
|
||||||
player.sendMessage(TranslatableCaption.of("commandconfig.command_syntax"),
|
player.sendMessage(TranslatableCaption.of("commandconfig.command_syntax"),
|
||||||
Templates.of("value", "/plot area create [world[:id]] [<modifier>=<value>]..."));
|
Templates.of("value", "/plot area create [world[:id]] [<modifier>=<value>]..."));
|
||||||
@ -294,14 +310,17 @@ public class Area extends SubCommand {
|
|||||||
}
|
}
|
||||||
case "pos2": // Set position 2 and finish creation for type=2 (partial)
|
case "pos2": // Set position 2 and finish creation for type=2 (partial)
|
||||||
final HybridPlotWorld area = (HybridPlotWorld) metaData
|
final HybridPlotWorld area = (HybridPlotWorld) metaData
|
||||||
.computeIfAbsent(player.getUUID(), missingUUID -> new HashMap<>()).get("area_create_area");
|
.computeIfAbsent(player.getUUID(),
|
||||||
|
missingUUID -> new HashMap<>()).get("area_create_area");
|
||||||
if (area == null) {
|
if (area == null) {
|
||||||
player.sendMessage(TranslatableCaption.of("commandconfig.command_syntax"),
|
player.sendMessage(TranslatableCaption.of("commandconfig.command_syntax"),
|
||||||
Templates.of("value", "/plot area create [world[:id]] [<modifier>=<value>]..."));
|
Templates.of("value", "/plot area create [world[:id]] [<modifier>=<value>]..."));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Location pos1 = player.getLocation();
|
Location pos1 = player.getLocation();
|
||||||
Location pos2 = (Location) metaData.computeIfAbsent(player.getUUID(), missingUUID -> new HashMap<>()).get("area_pos1");
|
Location pos2 = (Location) metaData
|
||||||
|
.computeIfAbsent(player.getUUID(),
|
||||||
|
missingUUID -> new HashMap<>()).get("area_pos1");
|
||||||
int dx = Math.abs(pos1.getX() - pos2.getX());
|
int dx = Math.abs(pos1.getX() - pos2.getX());
|
||||||
int dz = Math.abs(pos1.getZ() - pos2.getZ());
|
int dz = Math.abs(pos1.getZ() - pos2.getZ());
|
||||||
int numX = Math.max(1,
|
int numX = Math.max(1,
|
||||||
@ -330,17 +349,18 @@ public class Area extends SubCommand {
|
|||||||
PlotAreaBuilder builder = PlotAreaBuilder.ofPlotArea(area)
|
PlotAreaBuilder builder = PlotAreaBuilder.ofPlotArea(area)
|
||||||
.plotManager(PlotSquared.platform().getPluginName())
|
.plotManager(PlotSquared.platform().getPluginName())
|
||||||
.generatorName(PlotSquared.platform().getPluginName())
|
.generatorName(PlotSquared.platform().getPluginName())
|
||||||
.minimumId(PlotId.of(1, 1))
|
.minimumId(PlotId.of(1, 1)).maximumId(PlotId.of(numX, numZ));
|
||||||
.maximumId(PlotId.of(numX, numZ));
|
|
||||||
final String path =
|
final String path =
|
||||||
"worlds." + area.getWorldName() + ".areas." + area.getId() + '-'
|
"worlds." + area.getWorldName() + ".areas." + area.getId() + '-'
|
||||||
+ builder.minimumId() + '-' + builder.maximumId();
|
+ builder.minimumId() + '-' + builder.maximumId();
|
||||||
Runnable run = () -> {
|
Runnable run = () -> {
|
||||||
if (offsetX != 0) {
|
if (offsetX != 0) {
|
||||||
this.worldConfiguration.set(path + ".road.offset.x", offsetX);
|
this.worldConfiguration
|
||||||
|
.set(path + ".road.offset.x", offsetX);
|
||||||
}
|
}
|
||||||
if (offsetZ != 0) {
|
if (offsetZ != 0) {
|
||||||
this.worldConfiguration.set(path + ".road.offset.z", offsetZ);
|
this.worldConfiguration
|
||||||
|
.set(path + ".road.offset.z", offsetZ);
|
||||||
}
|
}
|
||||||
final String world = this.setupUtils.setupWorld(builder);
|
final String world = this.setupUtils.setupWorld(builder);
|
||||||
if (this.worldUtil.isWorld(world)) {
|
if (this.worldUtil.isWorld(world)) {
|
||||||
@ -349,14 +369,13 @@ public class Area extends SubCommand {
|
|||||||
player.teleport(this.worldUtil.getSpawn(world),
|
player.teleport(this.worldUtil.getSpawn(world),
|
||||||
TeleportCause.COMMAND);
|
TeleportCause.COMMAND);
|
||||||
if (area.getTerrain() != PlotAreaTerrainType.ALL) {
|
if (area.getTerrain() != PlotAreaTerrainType.ALL) {
|
||||||
this.regionManager.largeRegionTask(world, region,
|
QueueCoordinator queue =
|
||||||
new RunnableVal<BlockVector2>() {
|
blockQueue.getNewQueue(worldUtil.getWeWorld(world));
|
||||||
@Override public void run(BlockVector2 value) {
|
queue.setChunkConsumer(chunk -> AugmentedUtils
|
||||||
AugmentedUtils
|
.generate(null, world, chunk.getX(), chunk.getZ(),
|
||||||
.generate(null, world, value.getX(),
|
null));
|
||||||
value.getZ(), null);
|
queue.addReadChunks(region.getChunks());
|
||||||
}
|
queue.enqueue();
|
||||||
}, null);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
player.sendMessage(
|
player.sendMessage(
|
||||||
@ -383,15 +402,17 @@ public class Area extends SubCommand {
|
|||||||
}
|
}
|
||||||
PlotAreaBuilder builder = PlotAreaBuilder.newBuilder();
|
PlotAreaBuilder builder = PlotAreaBuilder.newBuilder();
|
||||||
builder.worldName(split[0]);
|
builder.worldName(split[0]);
|
||||||
final HybridPlotWorld pa = this.hybridPlotWorldFactory.create(builder.worldName(),
|
final HybridPlotWorld pa = this.hybridPlotWorldFactory
|
||||||
id, PlotSquared.platform().getDefaultGenerator(), null, null);
|
.create(builder.worldName(), id,
|
||||||
|
PlotSquared.platform().getDefaultGenerator(), null, null);
|
||||||
PlotArea other = this.plotAreaManager.getPlotArea(pa.getWorldName(), id);
|
PlotArea other = this.plotAreaManager.getPlotArea(pa.getWorldName(), id);
|
||||||
if (other != null && Objects.equals(pa.getId(), other.getId())) {
|
if (other != null && Objects.equals(pa.getId(), other.getId())) {
|
||||||
player.sendMessage(TranslatableCaption.of("setup.setup_world_taken"),
|
player.sendMessage(TranslatableCaption.of("setup.setup_world_taken"),
|
||||||
Template.of("value", pa.toString()));
|
Template.of("value", pa.toString()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Set<PlotArea> areas = this.plotAreaManager.getPlotAreasSet(pa.getWorldName());
|
Set<PlotArea> areas =
|
||||||
|
this.plotAreaManager.getPlotAreasSet(pa.getWorldName());
|
||||||
if (!areas.isEmpty()) {
|
if (!areas.isEmpty()) {
|
||||||
PlotArea area = areas.iterator().next();
|
PlotArea area = areas.iterator().next();
|
||||||
pa.setType(area.getType());
|
pa.setType(area.getType());
|
||||||
@ -477,7 +498,8 @@ public class Area extends SubCommand {
|
|||||||
if (!this.worldConfiguration.contains(path)) {
|
if (!this.worldConfiguration.contains(path)) {
|
||||||
this.worldConfiguration.createSection(path);
|
this.worldConfiguration.createSection(path);
|
||||||
}
|
}
|
||||||
ConfigurationSection section = this.worldConfiguration.getConfigurationSection(path);
|
ConfigurationSection section =
|
||||||
|
this.worldConfiguration.getConfigurationSection(path);
|
||||||
pa.saveConfiguration(section);
|
pa.saveConfiguration(section);
|
||||||
pa.loadConfiguration(section);
|
pa.loadConfiguration(section);
|
||||||
builder.plotManager(PlotSquared.platform().getPluginName());
|
builder.plotManager(PlotSquared.platform().getPluginName());
|
||||||
@ -627,7 +649,8 @@ public class Area extends SubCommand {
|
|||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final List<PlotArea> areas = new ArrayList<>(Arrays.asList(this.plotAreaManager.getAllPlotAreas()));
|
final List<PlotArea> areas =
|
||||||
|
new ArrayList<>(Arrays.asList(this.plotAreaManager.getAllPlotAreas()));
|
||||||
paginate(player, areas, 8, page,
|
paginate(player, areas, 8, page,
|
||||||
new RunnableVal3<Integer, PlotArea, CaptionHolder>() {
|
new RunnableVal3<Integer, PlotArea, CaptionHolder>() {
|
||||||
@Override public void run(Integer i, PlotArea area, CaptionHolder caption) {
|
@Override public void run(Integer i, PlotArea area, CaptionHolder caption) {
|
||||||
@ -642,7 +665,8 @@ public class Area extends SubCommand {
|
|||||||
PlotId max = area.getMax();
|
PlotId max = area.getMax();
|
||||||
name = area.getWorldName() + ';' + area.getId() + ';' + min + ';'
|
name = area.getWorldName() + ';' + area.getId() + ';' + min + ';'
|
||||||
+ max;
|
+ max;
|
||||||
int size = (max.getX() - min.getX() + 1) * (max.getY() - min.getY() + 1);
|
int size =
|
||||||
|
(max.getX() - min.getX() + 1) * (max.getY() - min.getY() + 1);
|
||||||
percent = claimed == 0 ? 0 : size / (double) claimed;
|
percent = claimed == 0 ? 0 : size / (double) claimed;
|
||||||
region = area.getRegion().toString();
|
region = area.getRegion().toString();
|
||||||
} else {
|
} else {
|
||||||
@ -694,15 +718,13 @@ public class Area extends SubCommand {
|
|||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
this.regionManager.largeRegionTask(area.getWorldName(), area.getRegion(),
|
QueueCoordinator queue =
|
||||||
new RunnableVal<BlockVector2>() {
|
blockQueue.getNewQueue(worldUtil.getWeWorld(area.getWorldName()));
|
||||||
@Override public void run(BlockVector2 value) {
|
queue.setChunkConsumer(chunk -> AugmentedUtils
|
||||||
AugmentedUtils
|
.generate(null, area.getWorldName(), chunk.getX(), chunk.getZ(), null));
|
||||||
.generate(null, area.getWorldName(), value.getX(), value.getZ(),
|
queue.addReadChunks(area.getRegion().getChunks());
|
||||||
null);
|
queue.setCompleteTask(() -> player.sendMessage(TranslatableCaption.of("single.regeneration_complete")));
|
||||||
}
|
queue.enqueue();
|
||||||
}, () -> player.sendMessage(TranslatableCaption.of("single.regeneration_complete"))
|
|
||||||
);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case "goto":
|
case "goto":
|
||||||
@ -737,9 +759,11 @@ public class Area extends SubCommand {
|
|||||||
center = Location.at(area.getWorldName(), region.getMinimumPoint().getX()
|
center = Location.at(area.getWorldName(), region.getMinimumPoint().getX()
|
||||||
+ (region.getMaximumPoint().getX() - region.getMinimumPoint().getX()) / 2,
|
+ (region.getMaximumPoint().getX() - region.getMinimumPoint().getX()) / 2,
|
||||||
0, region.getMinimumPoint().getZ()
|
0, region.getMinimumPoint().getZ()
|
||||||
+ (region.getMaximumPoint().getZ() - region.getMinimumPoint().getZ()) / 2);
|
+ (region.getMaximumPoint().getZ() - region.getMinimumPoint().getZ())
|
||||||
this.worldUtil.getHighestBlock(area.getWorldName(), center.getX(), center.getZ(), y ->
|
/ 2);
|
||||||
player.teleport(center.withY(1 + y), TeleportCause.COMMAND));
|
this.worldUtil
|
||||||
|
.getHighestBlock(area.getWorldName(), center.getX(), center.getZ(),
|
||||||
|
y -> player.teleport(center.withY(1 + y), TeleportCause.COMMAND));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
case "delete":
|
case "delete":
|
||||||
|
@ -42,7 +42,7 @@ import com.plotsquared.core.util.Permissions;
|
|||||||
import com.plotsquared.core.util.task.RunnableVal2;
|
import com.plotsquared.core.util.task.RunnableVal2;
|
||||||
import com.plotsquared.core.util.task.RunnableVal3;
|
import com.plotsquared.core.util.task.RunnableVal3;
|
||||||
import net.kyori.adventure.text.minimessage.Template;
|
import net.kyori.adventure.text.minimessage.Template;
|
||||||
|
import com.plotsquared.core.util.task.TaskManager;
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
@ -94,7 +94,7 @@ public class Clear extends Command {
|
|||||||
final long start = System.currentTimeMillis();
|
final long start = System.currentTimeMillis();
|
||||||
boolean result = plot.clear(true, false, () -> {
|
boolean result = plot.clear(true, false, () -> {
|
||||||
plot.unlink();
|
plot.unlink();
|
||||||
this.blockQueue.addEmptyTask(() -> {
|
TaskManager.runTask(() -> {
|
||||||
plot.removeRunning();
|
plot.removeRunning();
|
||||||
// If the state changes, then mark it as no longer done
|
// If the state changes, then mark it as no longer done
|
||||||
if (DoneFlag.isDone(plot)) {
|
if (DoneFlag.isDone(plot)) {
|
||||||
|
@ -51,15 +51,6 @@ public interface CommandCaller {
|
|||||||
*/
|
*/
|
||||||
boolean hasPermission(@Nonnull String permission);
|
boolean hasPermission(@Nonnull String permission);
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if this object contains an override for the specified
|
|
||||||
* permission, by fully qualified name
|
|
||||||
*
|
|
||||||
* @param permission Name of the permission
|
|
||||||
* @return true if the permission is set, otherwise false
|
|
||||||
*/
|
|
||||||
boolean isPermissionSet(@Nonnull String permission);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the type of the caller
|
* Get the type of the caller
|
||||||
*
|
*
|
||||||
|
@ -33,8 +33,8 @@ import com.plotsquared.core.configuration.caption.TranslatableCaption;
|
|||||||
import com.plotsquared.core.player.ConsolePlayer;
|
import com.plotsquared.core.player.ConsolePlayer;
|
||||||
import com.plotsquared.core.player.PlotPlayer;
|
import com.plotsquared.core.player.PlotPlayer;
|
||||||
import com.plotsquared.core.plot.world.PlotAreaManager;
|
import com.plotsquared.core.plot.world.PlotAreaManager;
|
||||||
import com.plotsquared.core.util.RegionManager;
|
|
||||||
import com.plotsquared.core.util.StringMan;
|
import com.plotsquared.core.util.StringMan;
|
||||||
|
import com.plotsquared.core.util.WorldUtil;
|
||||||
import com.plotsquared.core.util.entity.EntityCategories;
|
import com.plotsquared.core.util.entity.EntityCategories;
|
||||||
import com.plotsquared.core.util.entity.EntityCategory;
|
import com.plotsquared.core.util.entity.EntityCategory;
|
||||||
import com.plotsquared.core.util.query.PlotQuery;
|
import com.plotsquared.core.util.query.PlotQuery;
|
||||||
@ -63,12 +63,12 @@ public class Debug extends SubCommand {
|
|||||||
private static final Logger logger = LoggerFactory.getLogger("P2/" + Debug.class.getSimpleName());
|
private static final Logger logger = LoggerFactory.getLogger("P2/" + Debug.class.getSimpleName());
|
||||||
|
|
||||||
private final PlotAreaManager plotAreaManager;
|
private final PlotAreaManager plotAreaManager;
|
||||||
private final RegionManager regionManager;
|
private final WorldUtil worldUtil;
|
||||||
|
|
||||||
@Inject public Debug(@Nonnull final PlotAreaManager plotAreaManager,
|
@Inject public Debug(@Nonnull final PlotAreaManager plotAreaManager,
|
||||||
@Nonnull final RegionManager regionManager) {
|
@Nonnull final WorldUtil worldUtil) {
|
||||||
this.plotAreaManager = plotAreaManager;
|
this.plotAreaManager = plotAreaManager;
|
||||||
this.regionManager = regionManager;
|
this.worldUtil = worldUtil;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean onCommand(PlotPlayer<?> player, String[] args) {
|
@Override public boolean onCommand(PlotPlayer<?> player, String[] args) {
|
||||||
@ -82,9 +82,9 @@ public class Debug extends SubCommand {
|
|||||||
if (args.length > 0 && "loadedchunks".equalsIgnoreCase(args[0])) {
|
if (args.length > 0 && "loadedchunks".equalsIgnoreCase(args[0])) {
|
||||||
final long start = System.currentTimeMillis();
|
final long start = System.currentTimeMillis();
|
||||||
player.sendMessage(TranslatableCaption.of("debug.fetching_loaded_chunks"));
|
player.sendMessage(TranslatableCaption.of("debug.fetching_loaded_chunks"));
|
||||||
TaskManager.runTaskAsync(() -> player.sendMessage(StaticCaption.of("Loaded chunks: " + this.regionManager.getChunkChunks(player.getLocation().getWorldName()).size() + "(" + (
|
TaskManager.runTaskAsync(() -> player.sendMessage(StaticCaption
|
||||||
System.currentTimeMillis() - start) + "ms) using thread: " + Thread
|
.of("Loaded chunks: " + this.worldUtil.getChunkChunks(player.getLocation().getWorldName()).size() + "(" + (System.currentTimeMillis()
|
||||||
.currentThread().getName())));
|
- start) + "ms) using thread: " + Thread.currentThread().getName())));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (args.length > 0 && "uuids".equalsIgnoreCase(args[0])) {
|
if (args.length > 0 && "uuids".equalsIgnoreCase(args[0])) {
|
||||||
|
@ -35,6 +35,7 @@ import com.plotsquared.core.plot.Plot;
|
|||||||
import com.plotsquared.core.plot.PlotArea;
|
import com.plotsquared.core.plot.PlotArea;
|
||||||
import com.plotsquared.core.plot.PlotManager;
|
import com.plotsquared.core.plot.PlotManager;
|
||||||
import net.kyori.adventure.text.minimessage.Template;
|
import net.kyori.adventure.text.minimessage.Template;
|
||||||
|
import com.plotsquared.core.queue.QueueCoordinator;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -91,9 +92,10 @@ public class DebugRoadRegen extends SubCommand {
|
|||||||
player.sendMessage(TranslatableCaption.of("debug.requires_unmerged"));
|
player.sendMessage(TranslatableCaption.of("debug.requires_unmerged"));
|
||||||
} else {
|
} else {
|
||||||
PlotManager manager = area.getPlotManager();
|
PlotManager manager = area.getPlotManager();
|
||||||
manager.createRoadEast(plot);
|
QueueCoordinator queue = area.getQueue();
|
||||||
manager.createRoadSouth(plot);
|
manager.createRoadEast(plot, queue);
|
||||||
manager.createRoadSouthEast(plot);
|
manager.createRoadSouth(plot, queue);
|
||||||
|
manager.createRoadSouthEast(plot, queue);
|
||||||
player.sendMessage(
|
player.sendMessage(
|
||||||
TranslatableCaption.of("debugroadregen.regen_done"),
|
TranslatableCaption.of("debugroadregen.regen_done"),
|
||||||
Template.of("value", String.valueOf(plot.getId()))
|
Template.of("value", String.valueOf(plot.getId()))
|
||||||
|
@ -25,12 +25,8 @@
|
|||||||
*/
|
*/
|
||||||
package com.plotsquared.core.command;
|
package com.plotsquared.core.command;
|
||||||
|
|
||||||
import com.plotsquared.core.configuration.caption.TranslatableCaption;
|
import com.plotsquared.core.configuration.caption.StaticCaption;
|
||||||
import com.plotsquared.core.player.PlotPlayer;
|
import com.plotsquared.core.player.PlotPlayer;
|
||||||
import com.plotsquared.core.plot.Plot;
|
|
||||||
import com.plotsquared.core.queue.LocalBlockQueue;
|
|
||||||
import com.plotsquared.core.util.ChunkManager;
|
|
||||||
import com.plotsquared.core.util.task.RunnableVal;
|
|
||||||
import com.plotsquared.core.util.task.RunnableVal2;
|
import com.plotsquared.core.util.task.RunnableVal2;
|
||||||
import com.plotsquared.core.util.task.RunnableVal3;
|
import com.plotsquared.core.util.task.RunnableVal3;
|
||||||
|
|
||||||
@ -50,12 +46,13 @@ public class Relight extends Command {
|
|||||||
public CompletableFuture<Boolean> execute(final PlotPlayer<?> player, String[] args,
|
public CompletableFuture<Boolean> execute(final PlotPlayer<?> player, String[] args,
|
||||||
RunnableVal3<Command, Runnable, Runnable> confirm,
|
RunnableVal3<Command, Runnable, Runnable> confirm,
|
||||||
RunnableVal2<Command, CommandResult> whenDone) {
|
RunnableVal2<Command, CommandResult> whenDone) {
|
||||||
final Plot plot = player.getCurrentPlot();
|
player.sendMessage(StaticCaption.of("Not implemented."));
|
||||||
|
/* final Plot plot = player.getCurrentPlot();
|
||||||
if (plot == null) {
|
if (plot == null) {
|
||||||
player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
|
player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
|
||||||
return CompletableFuture.completedFuture(false);
|
return CompletableFuture.completedFuture(false);
|
||||||
}
|
}
|
||||||
final LocalBlockQueue queue = plot.getArea().getQueue(false);
|
final QueueCoordinator queue = plot.getArea().getQueue(false);
|
||||||
ChunkManager.chunkTask(plot, new RunnableVal<int[]>() {
|
ChunkManager.chunkTask(plot, new RunnableVal<int[]>() {
|
||||||
@Override public void run(int[] value) {
|
@Override public void run(int[] value) {
|
||||||
queue.fixChunkLighting(value[0], value[1]);
|
queue.fixChunkLighting(value[0], value[1]);
|
||||||
@ -63,7 +60,7 @@ public class Relight extends Command {
|
|||||||
}, () -> {
|
}, () -> {
|
||||||
plot.refreshChunks();
|
plot.refreshChunks();
|
||||||
player.sendMessage(TranslatableCaption.of("setblock.set_block_action_finished"));
|
player.sendMessage(TranslatableCaption.of("setblock.set_block_action_finished"));
|
||||||
}, 5);
|
}, 5);*/
|
||||||
|
|
||||||
return CompletableFuture.completedFuture(true);
|
return CompletableFuture.completedFuture(true);
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ import com.plotsquared.core.player.PlotPlayer;
|
|||||||
import com.plotsquared.core.plot.Plot;
|
import com.plotsquared.core.plot.Plot;
|
||||||
import com.plotsquared.core.plot.PlotArea;
|
import com.plotsquared.core.plot.PlotArea;
|
||||||
import com.plotsquared.core.plot.PlotManager;
|
import com.plotsquared.core.plot.PlotManager;
|
||||||
import com.plotsquared.core.queue.GlobalBlockQueue;
|
import com.plotsquared.core.queue.QueueCoordinator;
|
||||||
import com.plotsquared.core.util.PatternUtil;
|
import com.plotsquared.core.util.PatternUtil;
|
||||||
import com.plotsquared.core.util.Permissions;
|
import com.plotsquared.core.util.Permissions;
|
||||||
import com.plotsquared.core.util.StringMan;
|
import com.plotsquared.core.util.StringMan;
|
||||||
@ -70,13 +70,8 @@ public class Set extends SubCommand {
|
|||||||
public static final String[] aliases = new String[] {"b", "w", "wf", "a", "h"};
|
public static final String[] aliases = new String[] {"b", "w", "wf", "a", "h"};
|
||||||
|
|
||||||
private final SetCommand component;
|
private final SetCommand component;
|
||||||
private final WorldUtil worldUtil;
|
|
||||||
private final GlobalBlockQueue blockQueue;
|
|
||||||
|
|
||||||
@Inject public Set(@Nonnull final WorldUtil worldUtil,
|
@Inject public Set(@Nonnull final WorldUtil worldUtil) {
|
||||||
@Nonnull final GlobalBlockQueue blockQueue) {
|
|
||||||
this.worldUtil = worldUtil;
|
|
||||||
this.blockQueue = blockQueue;
|
|
||||||
this.component = new SetCommand() {
|
this.component = new SetCommand() {
|
||||||
|
|
||||||
@Override public String getId() {
|
@Override public String getId() {
|
||||||
@ -158,11 +153,13 @@ public class Set extends SubCommand {
|
|||||||
|
|
||||||
BackupManager.backup(player, plot, () -> {
|
BackupManager.backup(player, plot, () -> {
|
||||||
plot.addRunning();
|
plot.addRunning();
|
||||||
|
QueueCoordinator queue = plotArea.getQueue();
|
||||||
for (Plot current : plot.getConnectedPlots()) {
|
for (Plot current : plot.getConnectedPlots()) {
|
||||||
current.setComponent(component, pattern);
|
current.setComponent(component, pattern, queue);
|
||||||
}
|
}
|
||||||
|
queue.setCompleteTask(plot::removeRunning);
|
||||||
|
queue.enqueue();
|
||||||
player.sendMessage(TranslatableCaption.of("working.generating_component"));
|
player.sendMessage(TranslatableCaption.of("working.generating_component"));
|
||||||
blockQueue.addEmptyTask(plot::removeRunning);
|
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,6 @@ import com.plotsquared.core.player.PlotPlayer;
|
|||||||
import com.plotsquared.core.plot.PlotArea;
|
import com.plotsquared.core.plot.PlotArea;
|
||||||
import com.plotsquared.core.plot.PlotManager;
|
import com.plotsquared.core.plot.PlotManager;
|
||||||
import com.plotsquared.core.plot.world.PlotAreaManager;
|
import com.plotsquared.core.plot.world.PlotAreaManager;
|
||||||
import com.plotsquared.core.queue.GlobalBlockQueue;
|
|
||||||
import com.plotsquared.core.setup.PlotAreaBuilder;
|
import com.plotsquared.core.setup.PlotAreaBuilder;
|
||||||
import com.plotsquared.core.setup.SettingsNodesWrapper;
|
import com.plotsquared.core.setup.SettingsNodesWrapper;
|
||||||
import com.plotsquared.core.util.FileBytes;
|
import com.plotsquared.core.util.FileBytes;
|
||||||
@ -71,20 +70,17 @@ public class Template extends SubCommand {
|
|||||||
private final YamlConfiguration worldConfiguration;
|
private final YamlConfiguration worldConfiguration;
|
||||||
private final File worldFile;
|
private final File worldFile;
|
||||||
private final SetupUtils setupUtils;
|
private final SetupUtils setupUtils;
|
||||||
private final GlobalBlockQueue globalBlockQueue;
|
|
||||||
private final WorldUtil worldUtil;
|
private final WorldUtil worldUtil;
|
||||||
|
|
||||||
@Inject public Template(@Nonnull final PlotAreaManager plotAreaManager,
|
@Inject public Template(@Nonnull final PlotAreaManager plotAreaManager,
|
||||||
@WorldConfig @Nonnull final YamlConfiguration worldConfiguration,
|
@WorldConfig @Nonnull final YamlConfiguration worldConfiguration,
|
||||||
@WorldFile @Nonnull final File worldFile,
|
@WorldFile @Nonnull final File worldFile,
|
||||||
@Nonnull final SetupUtils setupUtils,
|
@Nonnull final SetupUtils setupUtils,
|
||||||
@Nonnull final GlobalBlockQueue globalBlockQueue,
|
|
||||||
@Nonnull final WorldUtil worldUtil) {
|
@Nonnull final WorldUtil worldUtil) {
|
||||||
this.plotAreaManager = plotAreaManager;
|
this.plotAreaManager = plotAreaManager;
|
||||||
this.worldConfiguration = worldConfiguration;
|
this.worldConfiguration = worldConfiguration;
|
||||||
this.worldFile = worldFile;
|
this.worldFile = worldFile;
|
||||||
this.setupUtils = setupUtils;
|
this.setupUtils = setupUtils;
|
||||||
this.globalBlockQueue = globalBlockQueue;
|
|
||||||
this.worldUtil = worldUtil;
|
this.worldUtil = worldUtil;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -227,7 +223,7 @@ public class Template extends SubCommand {
|
|||||||
.worldName(world);
|
.worldName(world);
|
||||||
|
|
||||||
this.setupUtils.setupWorld(builder);
|
this.setupUtils.setupWorld(builder);
|
||||||
this.globalBlockQueue.addEmptyTask(() -> {
|
TaskManager.runTask(() -> {
|
||||||
player.sendMessage(TranslatableCaption.of("debugimportworlds.done"));
|
player.sendMessage(TranslatableCaption.of("debugimportworlds.done"));
|
||||||
player.teleport(this.worldUtil.getSpawn(world), TeleportCause.COMMAND);
|
player.teleport(this.worldUtil.getSpawn(world), TeleportCause.COMMAND);
|
||||||
});
|
});
|
||||||
|
@ -35,7 +35,7 @@ import com.plotsquared.core.plot.Plot;
|
|||||||
import com.plotsquared.core.plot.expiration.ExpireManager;
|
import com.plotsquared.core.plot.expiration.ExpireManager;
|
||||||
import com.plotsquared.core.plot.world.PlotAreaManager;
|
import com.plotsquared.core.plot.world.PlotAreaManager;
|
||||||
import com.plotsquared.core.queue.GlobalBlockQueue;
|
import com.plotsquared.core.queue.GlobalBlockQueue;
|
||||||
import com.plotsquared.core.queue.LocalBlockQueue;
|
import com.plotsquared.core.queue.QueueCoordinator;
|
||||||
import com.plotsquared.core.util.RegionManager;
|
import com.plotsquared.core.util.RegionManager;
|
||||||
import com.plotsquared.core.util.RegionUtil;
|
import com.plotsquared.core.util.RegionUtil;
|
||||||
import com.plotsquared.core.util.WorldUtil;
|
import com.plotsquared.core.util.WorldUtil;
|
||||||
@ -98,7 +98,7 @@ public class Trim extends SubCommand {
|
|||||||
if (ExpireManager.IMP != null) {
|
if (ExpireManager.IMP != null) {
|
||||||
plots.removeAll(ExpireManager.IMP.getPendingExpired());
|
plots.removeAll(ExpireManager.IMP.getPendingExpired());
|
||||||
}
|
}
|
||||||
result.value1 = new HashSet<>(PlotSquared.platform().getRegionManager().getChunkChunks(world));
|
result.value1 = new HashSet<>(PlotSquared.platform().getWorldUtil().getChunkChunks(world));
|
||||||
result.value2 = new HashSet<>();
|
result.value2 = new HashSet<>();
|
||||||
StaticCaption.of(" - MCA #: " + result.value1.size());
|
StaticCaption.of(" - MCA #: " + result.value1.size());
|
||||||
StaticCaption.of(" - CHUNKS: " + (result.value1.size() * 1024) + " (max)");
|
StaticCaption.of(" - CHUNKS: " + (result.value1.size() * 1024) + " (max)");
|
||||||
@ -190,7 +190,7 @@ public class Trim extends SubCommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final LocalBlockQueue queue = blockQueue.getNewQueue(world, false);
|
final QueueCoordinator queue = blockQueue.getNewQueue(worldUtil.getWeWorld(world));
|
||||||
TaskManager.getPlatformImplementation().objectTask(chunks, new RunnableVal<BlockVector2>() {
|
TaskManager.getPlatformImplementation().objectTask(chunks, new RunnableVal<BlockVector2>() {
|
||||||
@Override public void run(BlockVector2 value) {
|
@Override public void run(BlockVector2 value) {
|
||||||
queue.regenChunk(value.getX(), value.getZ());
|
queue.regenChunk(value.getX(), value.getZ());
|
||||||
|
@ -37,6 +37,7 @@ import com.plotsquared.core.player.PlotPlayer;
|
|||||||
import com.plotsquared.core.plot.Plot;
|
import com.plotsquared.core.plot.Plot;
|
||||||
import com.plotsquared.core.plot.PlotInventory;
|
import com.plotsquared.core.plot.PlotInventory;
|
||||||
import com.plotsquared.core.plot.PlotItemStack;
|
import com.plotsquared.core.plot.PlotItemStack;
|
||||||
|
import com.plotsquared.core.queue.QueueCoordinator;
|
||||||
import com.plotsquared.core.util.EconHandler;
|
import com.plotsquared.core.util.EconHandler;
|
||||||
import com.plotsquared.core.util.InventoryUtil;
|
import com.plotsquared.core.util.InventoryUtil;
|
||||||
import com.plotsquared.core.util.PatternUtil;
|
import com.plotsquared.core.util.PatternUtil;
|
||||||
@ -70,8 +71,7 @@ public class ComponentPresetManager {
|
|||||||
private final EconHandler econHandler;
|
private final EconHandler econHandler;
|
||||||
private final InventoryUtil inventoryUtil;
|
private final InventoryUtil inventoryUtil;
|
||||||
|
|
||||||
@Inject public ComponentPresetManager(@Nullable final EconHandler econHandler, @Nonnull final
|
@Inject public ComponentPresetManager(@Nullable final EconHandler econHandler, @Nonnull final InventoryUtil inventoryUtil) {
|
||||||
InventoryUtil inventoryUtil) {
|
|
||||||
this.econHandler = econHandler;
|
this.econHandler = econHandler;
|
||||||
this.inventoryUtil = inventoryUtil;
|
this.inventoryUtil = inventoryUtil;
|
||||||
final File file = new File(Objects.requireNonNull(PlotSquared.platform()).getDirectory(), "components.yml");
|
final File file = new File(Objects.requireNonNull(PlotSquared.platform()).getDirectory(), "components.yml");
|
||||||
@ -105,15 +105,13 @@ public class ComponentPresetManager {
|
|||||||
this.guiName = yamlConfiguration.getString("title", "&6Plot Components");
|
this.guiName = yamlConfiguration.getString("title", "&6Plot Components");
|
||||||
|
|
||||||
if (yamlConfiguration.contains("presets")) {
|
if (yamlConfiguration.contains("presets")) {
|
||||||
this.presets = yamlConfiguration.getMapList("presets").stream().map(o -> (Map<String, Object>) o)
|
this.presets = yamlConfiguration.getMapList("presets").stream().map(o -> (Map<String, Object>) o).map(ComponentPreset::deserialize)
|
||||||
.map(ComponentPreset::deserialize).collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
} else {
|
} else {
|
||||||
final List<ComponentPreset> defaultPreset =
|
final List<ComponentPreset> defaultPreset = Collections.singletonList(
|
||||||
Collections.singletonList(new ComponentPreset(ClassicPlotManagerComponent.FLOOR,
|
new ComponentPreset(ClassicPlotManagerComponent.FLOOR, "##wool", 0, "", "&6D&ai&cs&ec&bo &2F&3l&do&9o&4r",
|
||||||
"##wool", 0, "", "&6D&ai&cs&ec&bo &2F&3l&do&9o&4r",
|
|
||||||
Arrays.asList("&6Spice up your plot floor"), ItemTypes.YELLOW_WOOL));
|
Arrays.asList("&6Spice up your plot floor"), ItemTypes.YELLOW_WOOL));
|
||||||
yamlConfiguration.set("presets", defaultPreset.stream().map(ComponentPreset::serialize)
|
yamlConfiguration.set("presets", defaultPreset.stream().map(ComponentPreset::serialize).collect(Collectors.toList()));
|
||||||
.collect(Collectors.toList()));
|
|
||||||
try {
|
try {
|
||||||
yamlConfiguration.save(file);
|
yamlConfiguration.save(file);
|
||||||
} catch (final IOException e) {
|
} catch (final IOException e) {
|
||||||
@ -148,8 +146,7 @@ public class ComponentPresetManager {
|
|||||||
|
|
||||||
final List<ComponentPreset> allowedPresets = new ArrayList<>(this.presets.size());
|
final List<ComponentPreset> allowedPresets = new ArrayList<>(this.presets.size());
|
||||||
for (final ComponentPreset componentPreset : this.presets) {
|
for (final ComponentPreset componentPreset : this.presets) {
|
||||||
if (!componentPreset.getPermission().isEmpty() && !Permissions
|
if (!componentPreset.getPermission().isEmpty() && !Permissions.hasPermission(player, componentPreset.getPermission())) {
|
||||||
.hasPermission(player, componentPreset.getPermission())) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
allowedPresets.add(componentPreset);
|
allowedPresets.add(componentPreset);
|
||||||
@ -194,11 +191,13 @@ public class ComponentPresetManager {
|
|||||||
|
|
||||||
BackupManager.backup(player, plot, () -> {
|
BackupManager.backup(player, plot, () -> {
|
||||||
plot.addRunning();
|
plot.addRunning();
|
||||||
|
QueueCoordinator queue = plot.getArea().getQueue();
|
||||||
for (Plot current : plot.getConnectedPlots()) {
|
for (Plot current : plot.getConnectedPlots()) {
|
||||||
current.setComponent(componentPreset.getComponent().name(), pattern);
|
current.setComponent(componentPreset.getComponent().name(), pattern, queue);
|
||||||
}
|
}
|
||||||
|
queue.setCompleteTask(plot::removeRunning);
|
||||||
|
queue.enqueue();
|
||||||
player.sendMessage(TranslatableCaption.of("working.generating_component"));
|
player.sendMessage(TranslatableCaption.of("working.generating_component"));
|
||||||
PlotSquared.platform().getGlobalBlockQueue().addEmptyTask(plot::removeRunning);
|
|
||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* | |
|
* | |
|
||||||
* |_|
|
* |_|
|
||||||
* PlotSquared plot management system for Minecraft
|
* PlotSquared plot management system for Minecraft
|
||||||
* Copyright (C) ${year} IntellectualSites
|
* Copyright (C) 2020 IntellectualSites
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -23,7 +23,6 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.plotsquared.core.configuration.caption;
|
package com.plotsquared.core.configuration.caption;
|
||||||
|
|
||||||
public class CaptionHolder {
|
public class CaptionHolder {
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* | |
|
* | |
|
||||||
* |_|
|
* |_|
|
||||||
* PlotSquared plot management system for Minecraft
|
* PlotSquared plot management system for Minecraft
|
||||||
* Copyright (C) ${year} IntellectualSites
|
* Copyright (C) 2020 IntellectualSites
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -31,10 +31,10 @@ import com.plotsquared.core.plot.PlotArea;
|
|||||||
import com.plotsquared.core.plot.PlotAreaTerrainType;
|
import com.plotsquared.core.plot.PlotAreaTerrainType;
|
||||||
import com.plotsquared.core.plot.PlotAreaType;
|
import com.plotsquared.core.plot.PlotAreaType;
|
||||||
import com.plotsquared.core.plot.PlotManager;
|
import com.plotsquared.core.plot.PlotManager;
|
||||||
import com.plotsquared.core.queue.AreaBoundDelegateLocalBlockQueue;
|
import com.plotsquared.core.queue.AreaBoundDelegateQueueCoordinator;
|
||||||
import com.plotsquared.core.queue.LocalBlockQueue;
|
import com.plotsquared.core.queue.LocationOffsetDelegateQueueCoordinator;
|
||||||
import com.plotsquared.core.queue.LocationOffsetDelegateLocalBlockQueue;
|
import com.plotsquared.core.queue.QueueCoordinator;
|
||||||
import com.plotsquared.core.queue.ScopedLocalBlockQueue;
|
import com.plotsquared.core.queue.ScopedQueueCoordinator;
|
||||||
import com.plotsquared.core.util.RegionUtil;
|
import com.plotsquared.core.util.RegionUtil;
|
||||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
@ -54,8 +54,11 @@ public class AugmentedUtils {
|
|||||||
enabled = true;
|
enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean generate(@Nullable Object chunkObject, @Nonnull final String world,
|
public static boolean generate(@Nullable Object chunkObject,
|
||||||
final int chunkX, final int chunkZ, LocalBlockQueue queue) {
|
@Nonnull final String world,
|
||||||
|
final int chunkX,
|
||||||
|
final int chunkZ,
|
||||||
|
QueueCoordinator queue) {
|
||||||
if (!enabled) {
|
if (!enabled) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -71,6 +74,7 @@ public class AugmentedUtils {
|
|||||||
if (areas.isEmpty()) {
|
if (areas.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
boolean enqueue = false;
|
||||||
boolean generationResult = false;
|
boolean generationResult = false;
|
||||||
for (final PlotArea area : areas) {
|
for (final PlotArea area : areas) {
|
||||||
// A normal plot world may not contain any clusters
|
// A normal plot world may not contain any clusters
|
||||||
@ -80,16 +84,19 @@ public class AugmentedUtils {
|
|||||||
}
|
}
|
||||||
// This means that full vanilla generation is used
|
// This means that full vanilla generation is used
|
||||||
// so we do not interfere
|
// so we do not interfere
|
||||||
if (area.getTerrain() == PlotAreaTerrainType.ALL) {
|
if (area.getTerrain() == PlotAreaTerrainType.ALL || !area.contains(blockX, blockZ)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
IndependentPlotGenerator generator = area.getGenerator();
|
IndependentPlotGenerator generator = area.getGenerator();
|
||||||
// Mask
|
// Mask
|
||||||
if (queue == null) {
|
if (queue == null) {
|
||||||
queue = PlotSquared.platform().getGlobalBlockQueue().getNewQueue(world, false);
|
enqueue = true;
|
||||||
|
queue = PlotSquared.platform().getGlobalBlockQueue().getNewQueue(PlotSquared.platform().getWorldUtil().getWeWorld(world));
|
||||||
|
if (chunkObject != null) {
|
||||||
queue.setChunkObject(chunkObject);
|
queue.setChunkObject(chunkObject);
|
||||||
}
|
}
|
||||||
LocalBlockQueue primaryMask;
|
}
|
||||||
|
QueueCoordinator primaryMask;
|
||||||
// coordinates
|
// coordinates
|
||||||
int relativeBottomX;
|
int relativeBottomX;
|
||||||
int relativeBottomZ;
|
int relativeBottomZ;
|
||||||
@ -102,14 +109,13 @@ public class AugmentedUtils {
|
|||||||
relativeTopX = Math.min(15, area.getRegion().getMaximumPoint().getX() - blockX);
|
relativeTopX = Math.min(15, area.getRegion().getMaximumPoint().getX() - blockX);
|
||||||
relativeTopZ = Math.min(15, area.getRegion().getMaximumPoint().getZ() - blockZ);
|
relativeTopZ = Math.min(15, area.getRegion().getMaximumPoint().getZ() - blockZ);
|
||||||
|
|
||||||
primaryMask = new AreaBoundDelegateLocalBlockQueue(area, queue);
|
primaryMask = new AreaBoundDelegateQueueCoordinator(area, queue);
|
||||||
} else {
|
} else {
|
||||||
relativeBottomX = relativeBottomZ = 0;
|
relativeBottomX = relativeBottomZ = 0;
|
||||||
relativeTopX = relativeTopZ = 15;
|
relativeTopX = relativeTopZ = 15;
|
||||||
primaryMask = queue;
|
primaryMask = queue;
|
||||||
}
|
}
|
||||||
|
QueueCoordinator secondaryMask;
|
||||||
LocalBlockQueue secondaryMask;
|
|
||||||
BlockState air = BlockTypes.AIR.getDefaultState();
|
BlockState air = BlockTypes.AIR.getDefaultState();
|
||||||
if (area.getTerrain() == PlotAreaTerrainType.ROAD) {
|
if (area.getTerrain() == PlotAreaTerrainType.ROAD) {
|
||||||
PlotManager manager = area.getPlotManager();
|
PlotManager manager = area.getPlotManager();
|
||||||
@ -133,8 +139,7 @@ public class AugmentedUtils {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
generationResult = true;
|
generationResult = true;
|
||||||
secondaryMask = new LocationOffsetDelegateLocalBlockQueue(canPlace, blockX, blockZ,
|
secondaryMask = new LocationOffsetDelegateQueueCoordinator(canPlace, blockX, blockZ, primaryMask);
|
||||||
primaryMask);
|
|
||||||
} else {
|
} else {
|
||||||
secondaryMask = primaryMask;
|
secondaryMask = primaryMask;
|
||||||
for (int x = relativeBottomX; x <= relativeTopX; x++) {
|
for (int x = relativeBottomX; x <= relativeTopX; x++) {
|
||||||
@ -146,20 +151,22 @@ public class AugmentedUtils {
|
|||||||
}
|
}
|
||||||
generationResult = true;
|
generationResult = true;
|
||||||
}
|
}
|
||||||
|
if (chunkObject != null) {
|
||||||
primaryMask.setChunkObject(chunkObject);
|
primaryMask.setChunkObject(chunkObject);
|
||||||
primaryMask.setForceSync(true);
|
}
|
||||||
|
if (chunkObject != null) {
|
||||||
secondaryMask.setChunkObject(chunkObject);
|
secondaryMask.setChunkObject(chunkObject);
|
||||||
secondaryMask.setForceSync(true);
|
}
|
||||||
|
|
||||||
ScopedLocalBlockQueue scoped =
|
ScopedQueueCoordinator scoped =
|
||||||
new ScopedLocalBlockQueue(secondaryMask, Location.at(world, blockX, 0, blockZ),
|
new ScopedQueueCoordinator(secondaryMask, Location.at(world, blockX, 0, blockZ), Location.at(world, blockX + 15, 255, blockZ + 15));
|
||||||
Location.at(world, blockX + 15, 255, blockZ + 15));
|
|
||||||
generator.generateChunk(scoped, area);
|
generator.generateChunk(scoped, area);
|
||||||
generator.populateChunk(scoped, area);
|
generator.populateChunk(scoped, area);
|
||||||
|
scoped.setForceSync(true);
|
||||||
|
scoped.enqueue();
|
||||||
}
|
}
|
||||||
if (queue != null) {
|
if (enqueue) {
|
||||||
queue.setForceSync(true);
|
queue.enqueue();
|
||||||
queue.flush();
|
|
||||||
}
|
}
|
||||||
return generationResult;
|
return generationResult;
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.plotsquared.core.generator;
|
package com.plotsquared.core.generator;
|
||||||
|
|
||||||
import com.plotsquared.core.PlotSquared;
|
|
||||||
import com.plotsquared.core.configuration.Settings;
|
import com.plotsquared.core.configuration.Settings;
|
||||||
import com.plotsquared.core.location.Direction;
|
import com.plotsquared.core.location.Direction;
|
||||||
import com.plotsquared.core.location.Location;
|
import com.plotsquared.core.location.Location;
|
||||||
@ -33,15 +32,17 @@ import com.plotsquared.core.plot.BlockBucket;
|
|||||||
import com.plotsquared.core.plot.Plot;
|
import com.plotsquared.core.plot.Plot;
|
||||||
import com.plotsquared.core.plot.PlotAreaTerrainType;
|
import com.plotsquared.core.plot.PlotAreaTerrainType;
|
||||||
import com.plotsquared.core.plot.PlotId;
|
import com.plotsquared.core.plot.PlotId;
|
||||||
import com.plotsquared.core.queue.LocalBlockQueue;
|
import com.plotsquared.core.queue.QueueCoordinator;
|
||||||
import com.plotsquared.core.util.BlockUtil;
|
import com.plotsquared.core.util.BlockUtil;
|
||||||
import com.plotsquared.core.util.MathMan;
|
import com.plotsquared.core.util.MathMan;
|
||||||
import com.plotsquared.core.util.RegionManager;
|
import com.plotsquared.core.util.RegionManager;
|
||||||
|
import com.plotsquared.core.util.task.TaskManager;
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@ -53,98 +54,140 @@ public class ClassicPlotManager extends SquarePlotManager {
|
|||||||
private final ClassicPlotWorld classicPlotWorld;
|
private final ClassicPlotWorld classicPlotWorld;
|
||||||
private final RegionManager regionManager;
|
private final RegionManager regionManager;
|
||||||
|
|
||||||
public ClassicPlotManager(@Nonnull final ClassicPlotWorld classicPlotWorld,
|
public ClassicPlotManager(@Nonnull final ClassicPlotWorld classicPlotWorld, @Nonnull final RegionManager regionManager) {
|
||||||
@Nonnull final RegionManager regionManager) {
|
|
||||||
super(classicPlotWorld, regionManager);
|
super(classicPlotWorld, regionManager);
|
||||||
this.classicPlotWorld = classicPlotWorld;
|
this.classicPlotWorld = classicPlotWorld;
|
||||||
this.regionManager = regionManager;
|
this.regionManager = regionManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean setComponent(PlotId plotId, String component, Pattern blocks) {
|
@Override public boolean setComponent(@Nonnull PlotId plotId,
|
||||||
final Optional<ClassicPlotManagerComponent> componentOptional =
|
@Nonnull String component,
|
||||||
ClassicPlotManagerComponent.fromString(component);
|
@Nonnull Pattern blocks,
|
||||||
|
@Nullable QueueCoordinator queue) {
|
||||||
|
final Optional<ClassicPlotManagerComponent> componentOptional = ClassicPlotManagerComponent.fromString(component);
|
||||||
if (componentOptional.isPresent()) {
|
if (componentOptional.isPresent()) {
|
||||||
switch (componentOptional.get()) {
|
switch (componentOptional.get()) {
|
||||||
case FLOOR:
|
case FLOOR:
|
||||||
return setFloor(plotId, blocks);
|
return setFloor(plotId, blocks, queue);
|
||||||
case WALL:
|
case WALL:
|
||||||
return setWallFilling(plotId, blocks);
|
return setWallFilling(plotId, blocks, queue);
|
||||||
case AIR:
|
case AIR:
|
||||||
return setAir(plotId, blocks);
|
return setAir(plotId, blocks, queue);
|
||||||
case MAIN:
|
case MAIN:
|
||||||
return setMain(plotId, blocks);
|
return setMain(plotId, blocks, queue);
|
||||||
case MIDDLE:
|
case MIDDLE:
|
||||||
return setMiddle(plotId, blocks);
|
return setMiddle(plotId, blocks, queue);
|
||||||
case OUTLINE:
|
case OUTLINE:
|
||||||
return setOutline(plotId, blocks);
|
return setOutline(plotId, blocks, queue);
|
||||||
case BORDER:
|
case BORDER:
|
||||||
return setWall(plotId, blocks);
|
return setWall(plotId, blocks, queue);
|
||||||
case ALL:
|
case ALL:
|
||||||
return setAll(plotId, blocks);
|
return setAll(plotId, blocks, queue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean unClaimPlot(Plot plot, Runnable whenDone) {
|
@Override public boolean unClaimPlot(@Nonnull Plot plot, @Nullable Runnable whenDone, @Nullable QueueCoordinator queue) {
|
||||||
setWallFilling(plot.getId(), classicPlotWorld.WALL_FILLING.toPattern());
|
setWallFilling(plot.getId(), classicPlotWorld.WALL_FILLING.toPattern(), queue);
|
||||||
if (!classicPlotWorld.WALL_BLOCK.isAir() || !classicPlotWorld.WALL_BLOCK
|
if (classicPlotWorld.PLACE_TOP_BLOCK && (!classicPlotWorld.WALL_BLOCK.isAir() || !classicPlotWorld.WALL_BLOCK
|
||||||
.equals(classicPlotWorld.CLAIMED_WALL_BLOCK)) {
|
.equals(classicPlotWorld.CLAIMED_WALL_BLOCK))) {
|
||||||
setWall(plot.getId(), classicPlotWorld.WALL_BLOCK.toPattern());
|
setWall(plot.getId(), classicPlotWorld.WALL_BLOCK.toPattern(), queue);
|
||||||
}
|
}
|
||||||
return PlotSquared.platform().getGlobalBlockQueue().addEmptyTask(whenDone);
|
TaskManager.runTask(whenDone);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean setFloor(PlotId plotId, Pattern blocks) {
|
/**
|
||||||
|
* Set the plot floor
|
||||||
|
*
|
||||||
|
* @param queue Nullable {@link QueueCoordinator}. If null, creates own queue and enqueues,
|
||||||
|
* otherwise writes to the queue but does not enqueue.
|
||||||
|
*/
|
||||||
|
public boolean setFloor(@Nonnull PlotId plotId, @Nonnull Pattern blocks, @Nullable QueueCoordinator queue) {
|
||||||
Plot plot = classicPlotWorld.getPlotAbs(plotId);
|
Plot plot = classicPlotWorld.getPlotAbs(plotId);
|
||||||
if (plot.isBasePlot()) {
|
if (plot != null && plot.isBasePlot()) {
|
||||||
return this.regionManager.setCuboids(classicPlotWorld, plot.getRegions(), blocks,
|
return this.regionManager
|
||||||
classicPlotWorld.PLOT_HEIGHT, classicPlotWorld.PLOT_HEIGHT);
|
.setCuboids(classicPlotWorld, plot.getRegions(), blocks, classicPlotWorld.PLOT_HEIGHT, classicPlotWorld.PLOT_HEIGHT, queue);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean setAll(PlotId plotId, Pattern blocks) {
|
/**
|
||||||
|
* Sets the plot main, floor and air areas.
|
||||||
|
*
|
||||||
|
* @param queue Nullable {@link QueueCoordinator}. If null, creates own queue and enqueues,
|
||||||
|
* otherwise writes to the queue but does not enqueue.
|
||||||
|
*/
|
||||||
|
public boolean setAll(@Nonnull PlotId plotId, @Nonnull Pattern blocks, @Nullable QueueCoordinator queue) {
|
||||||
Plot plot = classicPlotWorld.getPlotAbs(plotId);
|
Plot plot = classicPlotWorld.getPlotAbs(plotId);
|
||||||
if (plot.isBasePlot()) {
|
if (plot != null && plot.isBasePlot()) {
|
||||||
return this.regionManager.setCuboids(classicPlotWorld, plot.getRegions(), blocks, 1, getWorldHeight());
|
return this.regionManager.setCuboids(classicPlotWorld, plot.getRegions(), blocks, 1, getWorldHeight(), queue);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean setAir(PlotId plotId, Pattern blocks) {
|
/**
|
||||||
|
* Sets the plot air region.
|
||||||
|
*
|
||||||
|
* @param queue Nullable {@link QueueCoordinator}. If null, creates own queue and enqueues,
|
||||||
|
* otherwise writes to the queue but does not enqueue.
|
||||||
|
*/
|
||||||
|
public boolean setAir(@Nonnull PlotId plotId, @Nonnull Pattern blocks, @Nullable QueueCoordinator queue) {
|
||||||
Plot plot = classicPlotWorld.getPlotAbs(plotId);
|
Plot plot = classicPlotWorld.getPlotAbs(plotId);
|
||||||
if (plot.isBasePlot()) {
|
if (plot != null && plot.isBasePlot()) {
|
||||||
return this.regionManager.setCuboids(classicPlotWorld, plot.getRegions(), blocks,
|
return this.regionManager
|
||||||
classicPlotWorld.PLOT_HEIGHT + 1, getWorldHeight());
|
.setCuboids(classicPlotWorld, plot.getRegions(), blocks, classicPlotWorld.PLOT_HEIGHT + 1, getWorldHeight(), queue);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean setMain(PlotId plotId, Pattern blocks) {
|
/**
|
||||||
|
* Sets the plot main blocks.
|
||||||
|
*
|
||||||
|
* @param queue Nullable {@link QueueCoordinator}. If null, creates own queue and enqueues,
|
||||||
|
* otherwise writes to the queue but does not enqueue.
|
||||||
|
*/
|
||||||
|
public boolean setMain(@Nonnull PlotId plotId, @Nonnull Pattern blocks, @Nullable QueueCoordinator queue) {
|
||||||
Plot plot = classicPlotWorld.getPlotAbs(plotId);
|
Plot plot = classicPlotWorld.getPlotAbs(plotId);
|
||||||
if (plot.isBasePlot()) {
|
if (plot == null || plot.isBasePlot()) {
|
||||||
return this.regionManager.setCuboids(classicPlotWorld, plot.getRegions(), blocks, 1,
|
return this.regionManager.setCuboids(classicPlotWorld, plot.getRegions(), blocks, 1, classicPlotWorld.PLOT_HEIGHT - 1, queue);
|
||||||
classicPlotWorld.PLOT_HEIGHT - 1);
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean setMiddle(PlotId plotId, Pattern blocks) {
|
/**
|
||||||
|
* Set the middle plot block to a Pattern
|
||||||
|
*
|
||||||
|
* @param queue Nullable {@link QueueCoordinator}. If null, creates own queue and enqueues,
|
||||||
|
* otherwise writes to the queue but does not enqueue.
|
||||||
|
*/
|
||||||
|
public boolean setMiddle(@Nonnull PlotId plotId, @Nonnull Pattern blocks, @Nullable QueueCoordinator queue) {
|
||||||
Plot plot = classicPlotWorld.getPlotAbs(plotId);
|
Plot plot = classicPlotWorld.getPlotAbs(plotId);
|
||||||
if (!plot.isBasePlot()) {
|
if (plot == null || !plot.isBasePlot()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Location[] corners = plot.getCorners();
|
Location[] corners = plot.getCorners();
|
||||||
LocalBlockQueue queue = classicPlotWorld.getQueue(false);
|
|
||||||
|
boolean enqueue = false;
|
||||||
|
if (queue == null) {
|
||||||
|
queue = classicPlotWorld.getQueue();
|
||||||
|
enqueue = true;
|
||||||
|
}
|
||||||
|
|
||||||
int x = MathMan.average(corners[0].getX(), corners[1].getX());
|
int x = MathMan.average(corners[0].getX(), corners[1].getX());
|
||||||
int z = MathMan.average(corners[0].getZ(), corners[1].getZ());
|
int z = MathMan.average(corners[0].getZ(), corners[1].getZ());
|
||||||
queue.setBlock(x, classicPlotWorld.PLOT_HEIGHT, z, blocks);
|
queue.setBlock(x, classicPlotWorld.PLOT_HEIGHT, z, blocks);
|
||||||
return queue.enqueue();
|
return !enqueue || queue.enqueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean setOutline(PlotId plotId, Pattern blocks) {
|
/**
|
||||||
|
* Set a plot's outline
|
||||||
|
*
|
||||||
|
* @param queue Nullable {@link QueueCoordinator}. If null, creates own queue and enqueues,
|
||||||
|
* otherwise writes to the queue but does not enqueue.
|
||||||
|
*/
|
||||||
|
public boolean setOutline(@Nonnull PlotId plotId, @Nonnull Pattern blocks, @Nullable QueueCoordinator queue) {
|
||||||
if (classicPlotWorld.ROAD_WIDTH == 0) {
|
if (classicPlotWorld.ROAD_WIDTH == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -155,9 +198,18 @@ public class ClassicPlotManager extends SquarePlotManager {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
Plot plot = classicPlotWorld.getPlotAbs(plotId);
|
Plot plot = classicPlotWorld.getPlotAbs(plotId);
|
||||||
|
if (plot == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
Location bottom = plot.getBottomAbs();
|
Location bottom = plot.getBottomAbs();
|
||||||
Location top = plot.getExtendedTopAbs();
|
Location top = plot.getExtendedTopAbs();
|
||||||
LocalBlockQueue queue = classicPlotWorld.getQueue(false);
|
|
||||||
|
boolean enqueue = false;
|
||||||
|
if (queue == null) {
|
||||||
|
queue = classicPlotWorld.getQueue();
|
||||||
|
enqueue = true;
|
||||||
|
}
|
||||||
|
|
||||||
int maxY = classicPlotWorld.getPlotManager().getWorldHeight();
|
int maxY = classicPlotWorld.getPlotManager().getWorldHeight();
|
||||||
if (!plot.getMerged(Direction.NORTH)) {
|
if (!plot.getMerged(Direction.NORTH)) {
|
||||||
int z = bottom.getZ();
|
int z = bottom.getZ();
|
||||||
@ -194,19 +246,21 @@ public class ClassicPlotManager extends SquarePlotManager {
|
|||||||
}
|
}
|
||||||
if (plot.isBasePlot()) {
|
if (plot.isBasePlot()) {
|
||||||
for (CuboidRegion region : plot.getRegions()) {
|
for (CuboidRegion region : plot.getRegions()) {
|
||||||
Location pos1 =
|
Location pos1 = Location.at(classicPlotWorld.getWorldName(), region.getMinimumPoint().getX(), maxY, region.getMinimumPoint().getZ());
|
||||||
Location.at(classicPlotWorld.getWorldName(), region.getMinimumPoint().getX(),
|
Location pos2 = Location.at(classicPlotWorld.getWorldName(), region.getMaximumPoint().getX(), maxY, region.getMaximumPoint().getZ());
|
||||||
maxY, region.getMinimumPoint().getZ());
|
|
||||||
Location pos2 =
|
|
||||||
Location.at(classicPlotWorld.getWorldName(), region.getMaximumPoint().getX(),
|
|
||||||
maxY, region.getMaximumPoint().getZ());
|
|
||||||
queue.setCuboid(pos1, pos2, blocks);
|
queue.setCuboid(pos1, pos2, blocks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return queue.enqueue();
|
return !enqueue || queue.enqueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean setWallFilling(PlotId plotId, Pattern blocks) {
|
/**
|
||||||
|
* Set the wall filling for a plot
|
||||||
|
*
|
||||||
|
* @param queue Nullable {@link QueueCoordinator}. If null, creates own queue and enqueues,
|
||||||
|
* otherwise writes to the queue but does not enqueue.
|
||||||
|
*/
|
||||||
|
public boolean setWallFilling(@Nonnull PlotId plotId, @Nonnull Pattern blocks, @Nullable QueueCoordinator queue) {
|
||||||
if (classicPlotWorld.ROAD_WIDTH == 0) {
|
if (classicPlotWorld.ROAD_WIDTH == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -217,11 +271,18 @@ public class ClassicPlotManager extends SquarePlotManager {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
Plot plot = classicPlotWorld.getPlotAbs(plotId);
|
Plot plot = classicPlotWorld.getPlotAbs(plotId);
|
||||||
Location bot = plot.getExtendedBottomAbs()
|
if (plot == null) {
|
||||||
.subtract(plot.getMerged(Direction.WEST) ? 0 : 1, 0,
|
return false;
|
||||||
plot.getMerged(Direction.NORTH) ? 0 : 1);
|
}
|
||||||
|
Location bot = plot.getExtendedBottomAbs().subtract(plot.getMerged(Direction.WEST) ? 0 : 1, 0, plot.getMerged(Direction.NORTH) ? 0 : 1);
|
||||||
Location top = plot.getExtendedTopAbs().add(1, 0, 1);
|
Location top = plot.getExtendedTopAbs().add(1, 0, 1);
|
||||||
LocalBlockQueue queue = classicPlotWorld.getQueue(false);
|
|
||||||
|
boolean enqueue = false;
|
||||||
|
if (queue == null) {
|
||||||
|
queue = classicPlotWorld.getQueue();
|
||||||
|
enqueue = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!plot.getMerged(Direction.NORTH)) {
|
if (!plot.getMerged(Direction.NORTH)) {
|
||||||
int z = bot.getZ();
|
int z = bot.getZ();
|
||||||
for (int x = bot.getX(); x < top.getX(); x++) {
|
for (int x = bot.getX(); x < top.getX(); x++) {
|
||||||
@ -240,8 +301,7 @@ public class ClassicPlotManager extends SquarePlotManager {
|
|||||||
}
|
}
|
||||||
if (!plot.getMerged(Direction.SOUTH)) {
|
if (!plot.getMerged(Direction.SOUTH)) {
|
||||||
int z = top.getZ();
|
int z = top.getZ();
|
||||||
for (int x = bot.getX();
|
for (int x = bot.getX(); x < top.getX() + (plot.getMerged(Direction.EAST) ? 0 : 1); x++) {
|
||||||
x < top.getX() + (plot.getMerged(Direction.EAST) ? 0 : 1); x++) {
|
|
||||||
for (int y = 1; y <= classicPlotWorld.WALL_HEIGHT; y++) {
|
for (int y = 1; y <= classicPlotWorld.WALL_HEIGHT; y++) {
|
||||||
queue.setBlock(x, y, z, blocks);
|
queue.setBlock(x, y, z, blocks);
|
||||||
}
|
}
|
||||||
@ -249,17 +309,22 @@ public class ClassicPlotManager extends SquarePlotManager {
|
|||||||
}
|
}
|
||||||
if (!plot.getMerged(Direction.EAST)) {
|
if (!plot.getMerged(Direction.EAST)) {
|
||||||
int x = top.getX();
|
int x = top.getX();
|
||||||
for (int z = bot.getZ();
|
for (int z = bot.getZ(); z < top.getZ() + (plot.getMerged(Direction.SOUTH) ? 0 : 1); z++) {
|
||||||
z < top.getZ() + (plot.getMerged(Direction.SOUTH) ? 0 : 1); z++) {
|
|
||||||
for (int y = 1; y <= classicPlotWorld.WALL_HEIGHT; y++) {
|
for (int y = 1; y <= classicPlotWorld.WALL_HEIGHT; y++) {
|
||||||
queue.setBlock(x, y, z, blocks);
|
queue.setBlock(x, y, z, blocks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return queue.enqueue();
|
return !enqueue || queue.enqueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean setWall(PlotId plotId, Pattern blocks) {
|
/**
|
||||||
|
* Set a plot's wall top block only
|
||||||
|
*
|
||||||
|
* @param queue Nullable {@link QueueCoordinator}. If null, creates own queue and enqueues,
|
||||||
|
* otherwise writes to the queue but does not enqueue.
|
||||||
|
*/
|
||||||
|
public boolean setWall(@Nonnull PlotId plotId, @Nonnull Pattern blocks, @Nullable QueueCoordinator queue) {
|
||||||
if (classicPlotWorld.ROAD_WIDTH == 0) {
|
if (classicPlotWorld.ROAD_WIDTH == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -270,11 +335,18 @@ public class ClassicPlotManager extends SquarePlotManager {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
Plot plot = classicPlotWorld.getPlotAbs(plotId);
|
Plot plot = classicPlotWorld.getPlotAbs(plotId);
|
||||||
Location bot = plot.getExtendedBottomAbs()
|
if (plot == null) {
|
||||||
.subtract(plot.getMerged(Direction.WEST) ? 0 : 1, 0,
|
return false;
|
||||||
plot.getMerged(Direction.NORTH) ? 0 : 1);
|
}
|
||||||
|
Location bot = plot.getExtendedBottomAbs().subtract(plot.getMerged(Direction.WEST) ? 0 : 1, 0, plot.getMerged(Direction.NORTH) ? 0 : 1);
|
||||||
Location top = plot.getExtendedTopAbs().add(1, 0, 1);
|
Location top = plot.getExtendedTopAbs().add(1, 0, 1);
|
||||||
LocalBlockQueue queue = classicPlotWorld.getQueue(false);
|
|
||||||
|
boolean enqueue = false;
|
||||||
|
if (queue == null) {
|
||||||
|
enqueue = true;
|
||||||
|
queue = classicPlotWorld.getQueue();
|
||||||
|
}
|
||||||
|
|
||||||
int y = classicPlotWorld.WALL_HEIGHT + 1;
|
int y = classicPlotWorld.WALL_HEIGHT + 1;
|
||||||
if (!plot.getMerged(Direction.NORTH)) {
|
if (!plot.getMerged(Direction.NORTH)) {
|
||||||
int z = bot.getZ();
|
int z = bot.getZ();
|
||||||
@ -290,237 +362,239 @@ public class ClassicPlotManager extends SquarePlotManager {
|
|||||||
}
|
}
|
||||||
if (!plot.getMerged(Direction.SOUTH)) {
|
if (!plot.getMerged(Direction.SOUTH)) {
|
||||||
int z = top.getZ();
|
int z = top.getZ();
|
||||||
for (int x = bot.getX();
|
for (int x = bot.getX(); x < top.getX() + (plot.getMerged(Direction.EAST) ? 0 : 1); x++) {
|
||||||
x < top.getX() + (plot.getMerged(Direction.EAST) ? 0 : 1); x++) {
|
|
||||||
queue.setBlock(x, y, z, blocks);
|
queue.setBlock(x, y, z, blocks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!plot.getMerged(Direction.EAST)) {
|
if (!plot.getMerged(Direction.EAST)) {
|
||||||
int x = top.getX();
|
int x = top.getX();
|
||||||
for (int z = bot.getZ();
|
for (int z = bot.getZ(); z < top.getZ() + (plot.getMerged(Direction.SOUTH) ? 0 : 1); z++) {
|
||||||
z < top.getZ() + (plot.getMerged(Direction.SOUTH) ? 0 : 1); z++) {
|
|
||||||
queue.setBlock(x, y, z, blocks);
|
queue.setBlock(x, y, z, blocks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return queue.enqueue();
|
return !enqueue || queue.enqueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override public boolean createRoadEast(@Nonnull Plot plot, @Nullable QueueCoordinator queue) {
|
||||||
* PLOT MERGING.
|
|
||||||
*/
|
|
||||||
@Override public boolean createRoadEast(Plot plot) {
|
|
||||||
Location pos1 = getPlotBottomLocAbs(plot.getId());
|
Location pos1 = getPlotBottomLocAbs(plot.getId());
|
||||||
Location pos2 = getPlotTopLocAbs(plot.getId());
|
Location pos2 = getPlotTopLocAbs(plot.getId());
|
||||||
int sx = pos2.getX() + 1;
|
int sx = pos2.getX() + 1;
|
||||||
int ex = sx + classicPlotWorld.ROAD_WIDTH - 1;
|
int ex = sx + classicPlotWorld.ROAD_WIDTH - 1;
|
||||||
int sz = pos1.getZ() - 2;
|
int sz = pos1.getZ() - 2;
|
||||||
int ez = pos2.getZ() + 2;
|
int ez = pos2.getZ() + 2;
|
||||||
LocalBlockQueue queue = classicPlotWorld.getQueue(false);
|
|
||||||
int maxY = getWorldHeight();
|
boolean enqueue = false;
|
||||||
queue.setCuboid(Location.at(classicPlotWorld.getWorldName(), sx,
|
if (queue == null) {
|
||||||
Math.min(classicPlotWorld.WALL_HEIGHT, classicPlotWorld.ROAD_HEIGHT) + 1, sz + 1),
|
queue = classicPlotWorld.getQueue();
|
||||||
Location.at(classicPlotWorld.getWorldName(), ex, maxY, ez - 1),
|
enqueue = true;
|
||||||
BlockTypes.AIR.getDefaultState());
|
|
||||||
queue.setCuboid(Location.at(classicPlotWorld.getWorldName(), sx, 0, sz + 1),
|
|
||||||
Location.at(classicPlotWorld.getWorldName(), ex, 0, ez - 1),
|
|
||||||
BlockUtil.get((short) 7, (byte) 0));
|
|
||||||
queue.setCuboid(Location.at(classicPlotWorld.getWorldName(), sx, 1, sz + 1),
|
|
||||||
Location.at(classicPlotWorld.getWorldName(), sx, classicPlotWorld.WALL_HEIGHT, ez - 1),
|
|
||||||
classicPlotWorld.WALL_FILLING.toPattern());
|
|
||||||
queue.setCuboid(
|
|
||||||
Location.at(classicPlotWorld.getWorldName(), sx, classicPlotWorld.WALL_HEIGHT + 1,
|
|
||||||
sz + 1),
|
|
||||||
Location.at(classicPlotWorld.getWorldName(), sx, classicPlotWorld.WALL_HEIGHT + 1,
|
|
||||||
ez - 1), classicPlotWorld.WALL_BLOCK.toPattern());
|
|
||||||
queue.setCuboid(Location.at(classicPlotWorld.getWorldName(), ex, 1, sz + 1),
|
|
||||||
Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.WALL_HEIGHT, ez - 1),
|
|
||||||
classicPlotWorld.WALL_FILLING.toPattern());
|
|
||||||
queue.setCuboid(
|
|
||||||
Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.WALL_HEIGHT + 1,
|
|
||||||
sz + 1),
|
|
||||||
Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.WALL_HEIGHT + 1,
|
|
||||||
ez - 1), classicPlotWorld.WALL_BLOCK.toPattern());
|
|
||||||
queue.setCuboid(Location.at(classicPlotWorld.getWorldName(), sx + 1, 1, sz + 1),
|
|
||||||
Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.ROAD_HEIGHT,
|
|
||||||
ez - 1), classicPlotWorld.ROAD_BLOCK.toPattern());
|
|
||||||
return queue.enqueue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean createRoadSouth(Plot plot) {
|
int maxY = getWorldHeight();
|
||||||
|
queue.setCuboid(
|
||||||
|
Location.at(classicPlotWorld.getWorldName(), sx, Math.min(classicPlotWorld.WALL_HEIGHT, classicPlotWorld.ROAD_HEIGHT) + 1, sz + 1),
|
||||||
|
Location.at(classicPlotWorld.getWorldName(), ex, maxY, ez - 1), BlockTypes.AIR.getDefaultState());
|
||||||
|
queue.setCuboid(Location.at(classicPlotWorld.getWorldName(), sx, 0, sz + 1), Location.at(classicPlotWorld.getWorldName(), ex, 0, ez - 1),
|
||||||
|
BlockUtil.get((short) 7, (byte) 0));
|
||||||
|
queue.setCuboid(Location.at(classicPlotWorld.getWorldName(), sx, 1, sz + 1),
|
||||||
|
Location.at(classicPlotWorld.getWorldName(), sx, classicPlotWorld.WALL_HEIGHT, ez - 1), classicPlotWorld.WALL_FILLING.toPattern());
|
||||||
|
|
||||||
|
if (classicPlotWorld.PLACE_TOP_BLOCK) {
|
||||||
|
queue.setCuboid(Location.at(classicPlotWorld.getWorldName(), sx, classicPlotWorld.WALL_HEIGHT + 1, sz + 1),
|
||||||
|
Location.at(classicPlotWorld.getWorldName(), sx, classicPlotWorld.WALL_HEIGHT + 1, ez - 1), classicPlotWorld.WALL_BLOCK.toPattern());
|
||||||
|
}
|
||||||
|
queue.setCuboid(Location.at(classicPlotWorld.getWorldName(), ex, 1, sz + 1),
|
||||||
|
Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.WALL_HEIGHT, ez - 1), classicPlotWorld.WALL_FILLING.toPattern());
|
||||||
|
if (classicPlotWorld.PLACE_TOP_BLOCK) {
|
||||||
|
queue.setCuboid(Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.WALL_HEIGHT + 1, sz + 1),
|
||||||
|
Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.WALL_HEIGHT + 1, ez - 1), classicPlotWorld.WALL_BLOCK.toPattern());
|
||||||
|
}
|
||||||
|
queue.setCuboid(Location.at(classicPlotWorld.getWorldName(), sx + 1, 1, sz + 1),
|
||||||
|
Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.ROAD_HEIGHT, ez - 1), classicPlotWorld.ROAD_BLOCK.toPattern());
|
||||||
|
return !enqueue || queue.enqueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean createRoadSouth(@Nonnull Plot plot, @Nullable QueueCoordinator queue) {
|
||||||
Location pos1 = getPlotBottomLocAbs(plot.getId());
|
Location pos1 = getPlotBottomLocAbs(plot.getId());
|
||||||
Location pos2 = getPlotTopLocAbs(plot.getId());
|
Location pos2 = getPlotTopLocAbs(plot.getId());
|
||||||
int sz = pos2.getZ() + 1;
|
int sz = pos2.getZ() + 1;
|
||||||
int ez = sz + classicPlotWorld.ROAD_WIDTH - 1;
|
int ez = sz + classicPlotWorld.ROAD_WIDTH - 1;
|
||||||
int sx = pos1.getX() - 2;
|
int sx = pos1.getX() - 2;
|
||||||
int ex = pos2.getX() + 2;
|
int ex = pos2.getX() + 2;
|
||||||
LocalBlockQueue queue = classicPlotWorld.getQueue(false);
|
|
||||||
queue.setCuboid(Location.at(classicPlotWorld.getWorldName(), sx + 1,
|
boolean enqueue = false;
|
||||||
Math.min(classicPlotWorld.WALL_HEIGHT, classicPlotWorld.ROAD_HEIGHT) + 1, sz),
|
if (queue == null) {
|
||||||
Location.at(classicPlotWorld.getWorldName(), ex - 1,
|
queue = classicPlotWorld.getQueue();
|
||||||
classicPlotWorld.getPlotManager().getWorldHeight(), ez),
|
enqueue = true;
|
||||||
BlockTypes.AIR.getDefaultState());
|
|
||||||
queue.setCuboid(Location.at(classicPlotWorld.getWorldName(), sx + 1, 0, sz),
|
|
||||||
Location.at(classicPlotWorld.getWorldName(), ex - 1, 0, ez),
|
|
||||||
BlockUtil.get((short) 7, (byte) 0));
|
|
||||||
queue.setCuboid(Location.at(classicPlotWorld.getWorldName(), sx + 1, 1, sz),
|
|
||||||
Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.WALL_HEIGHT, sz),
|
|
||||||
classicPlotWorld.WALL_FILLING.toPattern());
|
|
||||||
queue.setCuboid(
|
|
||||||
Location.at(classicPlotWorld.getWorldName(), sx + 1, classicPlotWorld.WALL_HEIGHT + 1,
|
|
||||||
sz),
|
|
||||||
Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.WALL_HEIGHT + 1,
|
|
||||||
sz), classicPlotWorld.WALL_BLOCK.toPattern());
|
|
||||||
queue.setCuboid(Location.at(classicPlotWorld.getWorldName(), sx + 1, 1, ez),
|
|
||||||
Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.WALL_HEIGHT, ez),
|
|
||||||
classicPlotWorld.WALL_FILLING.toPattern());
|
|
||||||
queue.setCuboid(
|
|
||||||
Location.at(classicPlotWorld.getWorldName(), sx + 1, classicPlotWorld.WALL_HEIGHT + 1,
|
|
||||||
ez),
|
|
||||||
Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.WALL_HEIGHT + 1,
|
|
||||||
ez), classicPlotWorld.WALL_BLOCK.toPattern());
|
|
||||||
queue.setCuboid(Location.at(classicPlotWorld.getWorldName(), sx + 1, 1, sz + 1),
|
|
||||||
Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.ROAD_HEIGHT,
|
|
||||||
ez - 1), classicPlotWorld.ROAD_BLOCK.toPattern());
|
|
||||||
return queue.enqueue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean createRoadSouthEast(Plot plot) {
|
queue.setCuboid(
|
||||||
|
Location.at(classicPlotWorld.getWorldName(), sx + 1, Math.min(classicPlotWorld.WALL_HEIGHT, classicPlotWorld.ROAD_HEIGHT) + 1, sz),
|
||||||
|
Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.getPlotManager().getWorldHeight(), ez),
|
||||||
|
BlockTypes.AIR.getDefaultState());
|
||||||
|
queue.setCuboid(Location.at(classicPlotWorld.getWorldName(), sx + 1, 0, sz), Location.at(classicPlotWorld.getWorldName(), ex - 1, 0, ez),
|
||||||
|
BlockUtil.get((short) 7, (byte) 0));
|
||||||
|
queue.setCuboid(Location.at(classicPlotWorld.getWorldName(), sx + 1, 1, sz),
|
||||||
|
Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.WALL_HEIGHT, sz), classicPlotWorld.WALL_FILLING.toPattern());
|
||||||
|
|
||||||
|
if (classicPlotWorld.PLACE_TOP_BLOCK) {
|
||||||
|
queue.setCuboid(Location.at(classicPlotWorld.getWorldName(), sx + 1, classicPlotWorld.WALL_HEIGHT + 1, sz),
|
||||||
|
Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.WALL_HEIGHT + 1, sz), classicPlotWorld.WALL_BLOCK.toPattern());
|
||||||
|
}
|
||||||
|
queue.setCuboid(Location.at(classicPlotWorld.getWorldName(), sx + 1, 1, ez),
|
||||||
|
Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.WALL_HEIGHT, ez), classicPlotWorld.WALL_FILLING.toPattern());
|
||||||
|
if (classicPlotWorld.PLACE_TOP_BLOCK) {
|
||||||
|
queue.setCuboid(Location.at(classicPlotWorld.getWorldName(), sx + 1, classicPlotWorld.WALL_HEIGHT + 1, ez),
|
||||||
|
Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.WALL_HEIGHT + 1, ez), classicPlotWorld.WALL_BLOCK.toPattern());
|
||||||
|
}
|
||||||
|
queue.setCuboid(Location.at(classicPlotWorld.getWorldName(), sx + 1, 1, sz + 1),
|
||||||
|
Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.ROAD_HEIGHT, ez - 1), classicPlotWorld.ROAD_BLOCK.toPattern());
|
||||||
|
return !enqueue || queue.enqueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override public boolean createRoadSouthEast(@Nonnull Plot plot, @Nullable QueueCoordinator queue) {
|
||||||
Location pos2 = getPlotTopLocAbs(plot.getId());
|
Location pos2 = getPlotTopLocAbs(plot.getId());
|
||||||
int sx = pos2.getX() + 1;
|
int sx = pos2.getX() + 1;
|
||||||
int ex = sx + classicPlotWorld.ROAD_WIDTH - 1;
|
int ex = sx + classicPlotWorld.ROAD_WIDTH - 1;
|
||||||
int sz = pos2.getZ() + 1;
|
int sz = pos2.getZ() + 1;
|
||||||
int ez = sz + classicPlotWorld.ROAD_WIDTH - 1;
|
int ez = sz + classicPlotWorld.ROAD_WIDTH - 1;
|
||||||
LocalBlockQueue queue = classicPlotWorld.getQueue(false);
|
|
||||||
queue.setCuboid(
|
boolean enqueue = false;
|
||||||
Location.at(classicPlotWorld.getWorldName(), sx + 1, classicPlotWorld.ROAD_HEIGHT + 1,
|
if (queue == null) {
|
||||||
sz + 1), Location.at(classicPlotWorld.getWorldName(), ex - 1,
|
queue = classicPlotWorld.getQueue();
|
||||||
classicPlotWorld.getPlotManager().getWorldHeight(), ez - 1),
|
enqueue = true;
|
||||||
BlockTypes.AIR.getDefaultState());
|
|
||||||
queue.setCuboid(Location.at(classicPlotWorld.getWorldName(), sx + 1, 0, sz + 1),
|
|
||||||
Location.at(classicPlotWorld.getWorldName(), ex - 1, 0, ez - 1),
|
|
||||||
BlockUtil.get((short) 7, (byte) 0));
|
|
||||||
queue.setCuboid(Location.at(classicPlotWorld.getWorldName(), sx + 1, 1, sz + 1),
|
|
||||||
Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.ROAD_HEIGHT,
|
|
||||||
ez - 1), classicPlotWorld.ROAD_BLOCK.toPattern());
|
|
||||||
return queue.enqueue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean removeRoadEast(Plot plot) {
|
queue.setCuboid(Location.at(classicPlotWorld.getWorldName(), sx + 1, classicPlotWorld.ROAD_HEIGHT + 1, sz + 1),
|
||||||
|
Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.getPlotManager().getWorldHeight(), ez - 1),
|
||||||
|
BlockTypes.AIR.getDefaultState());
|
||||||
|
queue.setCuboid(Location.at(classicPlotWorld.getWorldName(), sx + 1, 0, sz + 1),
|
||||||
|
Location.at(classicPlotWorld.getWorldName(), ex - 1, 0, ez - 1), BlockUtil.get((short) 7, (byte) 0));
|
||||||
|
queue.setCuboid(Location.at(classicPlotWorld.getWorldName(), sx + 1, 1, sz + 1),
|
||||||
|
Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.ROAD_HEIGHT, ez - 1), classicPlotWorld.ROAD_BLOCK.toPattern());
|
||||||
|
return !enqueue || queue.enqueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean removeRoadEast(@Nonnull Plot plot, @Nullable QueueCoordinator queue) {
|
||||||
Location pos1 = getPlotBottomLocAbs(plot.getId());
|
Location pos1 = getPlotBottomLocAbs(plot.getId());
|
||||||
Location pos2 = getPlotTopLocAbs(plot.getId());
|
Location pos2 = getPlotTopLocAbs(plot.getId());
|
||||||
int sx = pos2.getX() + 1;
|
int sx = pos2.getX() + 1;
|
||||||
int ex = sx + classicPlotWorld.ROAD_WIDTH - 1;
|
int ex = sx + classicPlotWorld.ROAD_WIDTH - 1;
|
||||||
int sz = pos1.getZ() - 1;
|
int sz = pos1.getZ() - 1;
|
||||||
int ez = pos2.getZ() + 1;
|
int ez = pos2.getZ() + 1;
|
||||||
LocalBlockQueue queue = classicPlotWorld.getQueue(false);
|
|
||||||
queue.setCuboid(Location.at(classicPlotWorld.getWorldName(), sx,
|
boolean enqueue = false;
|
||||||
Math.min(classicPlotWorld.PLOT_HEIGHT, classicPlotWorld.ROAD_HEIGHT) + 1, sz),
|
if (queue == null) {
|
||||||
Location.at(classicPlotWorld.getWorldName(), ex,
|
queue = classicPlotWorld.getQueue();
|
||||||
classicPlotWorld.getPlotManager().getWorldHeight(), ez),
|
enqueue = true;
|
||||||
BlockTypes.AIR.getDefaultState());
|
|
||||||
queue.setCuboid(Location.at(classicPlotWorld.getWorldName(), sx, 1, sz + 1),
|
|
||||||
Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.PLOT_HEIGHT - 1,
|
|
||||||
ez - 1), classicPlotWorld.MAIN_BLOCK.toPattern());
|
|
||||||
queue.setCuboid(
|
|
||||||
Location.at(classicPlotWorld.getWorldName(), sx, classicPlotWorld.PLOT_HEIGHT, sz + 1),
|
|
||||||
Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.PLOT_HEIGHT, ez - 1),
|
|
||||||
classicPlotWorld.TOP_BLOCK.toPattern());
|
|
||||||
return queue.enqueue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean removeRoadSouth(Plot plot) {
|
queue
|
||||||
|
.setCuboid(Location.at(classicPlotWorld.getWorldName(), sx, Math.min(classicPlotWorld.PLOT_HEIGHT, classicPlotWorld.ROAD_HEIGHT) + 1, sz),
|
||||||
|
Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.getPlotManager().getWorldHeight(), ez),
|
||||||
|
BlockTypes.AIR.getDefaultState());
|
||||||
|
queue.setCuboid(Location.at(classicPlotWorld.getWorldName(), sx, 1, sz + 1),
|
||||||
|
Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.PLOT_HEIGHT - 1, ez - 1), classicPlotWorld.MAIN_BLOCK.toPattern());
|
||||||
|
queue.setCuboid(Location.at(classicPlotWorld.getWorldName(), sx, classicPlotWorld.PLOT_HEIGHT, sz + 1),
|
||||||
|
Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.PLOT_HEIGHT, ez - 1), classicPlotWorld.TOP_BLOCK.toPattern());
|
||||||
|
|
||||||
|
return !enqueue || queue.enqueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean removeRoadSouth(@Nonnull Plot plot, @Nullable QueueCoordinator queue) {
|
||||||
Location pos1 = getPlotBottomLocAbs(plot.getId());
|
Location pos1 = getPlotBottomLocAbs(plot.getId());
|
||||||
Location pos2 = getPlotTopLocAbs(plot.getId());
|
Location pos2 = getPlotTopLocAbs(plot.getId());
|
||||||
int sz = pos2.getZ() + 1;
|
int sz = pos2.getZ() + 1;
|
||||||
int ez = sz + classicPlotWorld.ROAD_WIDTH - 1;
|
int ez = sz + classicPlotWorld.ROAD_WIDTH - 1;
|
||||||
int sx = pos1.getX() - 1;
|
int sx = pos1.getX() - 1;
|
||||||
int ex = pos2.getX() + 1;
|
int ex = pos2.getX() + 1;
|
||||||
LocalBlockQueue queue = classicPlotWorld.getQueue(false);
|
|
||||||
queue.setCuboid(Location.at(classicPlotWorld.getWorldName(), sx,
|
boolean enqueue = false;
|
||||||
Math.min(classicPlotWorld.PLOT_HEIGHT, classicPlotWorld.ROAD_HEIGHT) + 1, sz),
|
if (queue == null) {
|
||||||
Location.at(classicPlotWorld.getWorldName(), ex,
|
queue = classicPlotWorld.getQueue();
|
||||||
classicPlotWorld.getPlotManager().getWorldHeight(), ez),
|
enqueue = true;
|
||||||
BlockTypes.AIR.getDefaultState());
|
|
||||||
queue.setCuboid(Location.at(classicPlotWorld.getWorldName(), sx + 1, 1, sz),
|
|
||||||
Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.PLOT_HEIGHT - 1,
|
|
||||||
ez), classicPlotWorld.MAIN_BLOCK.toPattern());
|
|
||||||
queue.setCuboid(
|
|
||||||
Location.at(classicPlotWorld.getWorldName(), sx + 1, classicPlotWorld.PLOT_HEIGHT, sz),
|
|
||||||
Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.PLOT_HEIGHT, ez),
|
|
||||||
classicPlotWorld.TOP_BLOCK.toPattern());
|
|
||||||
return queue.enqueue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean removeRoadSouthEast(Plot plot) {
|
queue
|
||||||
|
.setCuboid(Location.at(classicPlotWorld.getWorldName(), sx, Math.min(classicPlotWorld.PLOT_HEIGHT, classicPlotWorld.ROAD_HEIGHT) + 1, sz),
|
||||||
|
Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.getPlotManager().getWorldHeight(), ez),
|
||||||
|
BlockTypes.AIR.getDefaultState());
|
||||||
|
queue.setCuboid(Location.at(classicPlotWorld.getWorldName(), sx + 1, 1, sz),
|
||||||
|
Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.PLOT_HEIGHT - 1, ez), classicPlotWorld.MAIN_BLOCK.toPattern());
|
||||||
|
queue.setCuboid(Location.at(classicPlotWorld.getWorldName(), sx + 1, classicPlotWorld.PLOT_HEIGHT, sz),
|
||||||
|
Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.PLOT_HEIGHT, ez), classicPlotWorld.TOP_BLOCK.toPattern());
|
||||||
|
|
||||||
|
return !enqueue || queue.enqueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean removeRoadSouthEast(@Nonnull Plot plot, @Nullable QueueCoordinator queue) {
|
||||||
Location location = getPlotTopLocAbs(plot.getId());
|
Location location = getPlotTopLocAbs(plot.getId());
|
||||||
int sx = location.getX() + 1;
|
int sx = location.getX() + 1;
|
||||||
int ex = sx + classicPlotWorld.ROAD_WIDTH - 1;
|
int ex = sx + classicPlotWorld.ROAD_WIDTH - 1;
|
||||||
int sz = location.getZ() + 1;
|
int sz = location.getZ() + 1;
|
||||||
int ez = sz + classicPlotWorld.ROAD_WIDTH - 1;
|
int ez = sz + classicPlotWorld.ROAD_WIDTH - 1;
|
||||||
LocalBlockQueue queue = classicPlotWorld.getQueue(false);
|
|
||||||
queue.setCuboid(Location.at(classicPlotWorld.getWorldName(), sx,
|
boolean enqueue = false;
|
||||||
Math.min(classicPlotWorld.PLOT_HEIGHT, classicPlotWorld.ROAD_HEIGHT) + 1, sz),
|
if (queue == null) {
|
||||||
Location.at(classicPlotWorld.getWorldName(), ex,
|
queue = classicPlotWorld.getQueue();
|
||||||
classicPlotWorld.getPlotManager().getWorldHeight(), ez),
|
enqueue = true;
|
||||||
BlockTypes.AIR.getDefaultState());
|
|
||||||
queue.setCuboid(Location.at(classicPlotWorld.getWorldName(), sx, 1, sz),
|
|
||||||
Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.PLOT_HEIGHT - 1, ez),
|
|
||||||
classicPlotWorld.MAIN_BLOCK.toPattern());
|
|
||||||
queue.setCuboid(
|
|
||||||
Location.at(classicPlotWorld.getWorldName(), sx, classicPlotWorld.PLOT_HEIGHT, sz),
|
|
||||||
Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.PLOT_HEIGHT, ez),
|
|
||||||
classicPlotWorld.TOP_BLOCK.toPattern());
|
|
||||||
return queue.enqueue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
queue
|
||||||
* Finishing off plot merging by adding in the walls surrounding the plot (OPTIONAL)(UNFINISHED).
|
.setCuboid(Location.at(classicPlotWorld.getWorldName(), sx, Math.min(classicPlotWorld.PLOT_HEIGHT, classicPlotWorld.ROAD_HEIGHT) + 1, sz),
|
||||||
*
|
Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.getPlotManager().getWorldHeight(), ez),
|
||||||
* @return false if part of the merge failed, otherwise true if successful.
|
BlockTypes.AIR.getDefaultState());
|
||||||
*/
|
queue.setCuboid(Location.at(classicPlotWorld.getWorldName(), sx, 1, sz),
|
||||||
@Override public boolean finishPlotMerge(List<PlotId> plotIds) {
|
Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.PLOT_HEIGHT - 1, ez), classicPlotWorld.MAIN_BLOCK.toPattern());
|
||||||
|
queue.setCuboid(Location.at(classicPlotWorld.getWorldName(), sx, classicPlotWorld.PLOT_HEIGHT, sz),
|
||||||
|
Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.PLOT_HEIGHT, ez), classicPlotWorld.TOP_BLOCK.toPattern());
|
||||||
|
|
||||||
|
return !enqueue || queue.enqueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean finishPlotMerge(@Nonnull List<PlotId> plotIds, @Nullable QueueCoordinator queue) {
|
||||||
final BlockBucket claim = classicPlotWorld.CLAIMED_WALL_BLOCK;
|
final BlockBucket claim = classicPlotWorld.CLAIMED_WALL_BLOCK;
|
||||||
if (!claim.isAir() || !claim.equals(classicPlotWorld.WALL_BLOCK)) {
|
if (classicPlotWorld.PLACE_TOP_BLOCK && (!claim.isAir() || !claim.equals(classicPlotWorld.WALL_BLOCK))) {
|
||||||
for (PlotId plotId : plotIds) {
|
for (PlotId plotId : plotIds) {
|
||||||
setWall(plotId, claim.toPattern());
|
setWall(plotId, claim.toPattern(), queue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Settings.General.MERGE_REPLACE_WALL) {
|
if (Settings.General.MERGE_REPLACE_WALL) {
|
||||||
final BlockBucket wallBlock = classicPlotWorld.WALL_FILLING;
|
final BlockBucket wallBlock = classicPlotWorld.WALL_FILLING;
|
||||||
for (PlotId id : plotIds) {
|
for (PlotId id : plotIds) {
|
||||||
setWallFilling(id, wallBlock.toPattern());
|
setWallFilling(id, wallBlock.toPattern(), queue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean finishPlotUnlink(List<PlotId> plotIds) {
|
@Override public boolean finishPlotUnlink(@Nonnull List<PlotId> plotIds, @Nullable QueueCoordinator queue) {
|
||||||
final BlockBucket claim = classicPlotWorld.CLAIMED_WALL_BLOCK;
|
final BlockBucket claim = classicPlotWorld.CLAIMED_WALL_BLOCK;
|
||||||
if (!claim.isAir() || !claim.equals(classicPlotWorld.WALL_BLOCK)) {
|
if (classicPlotWorld.PLACE_TOP_BLOCK && (!claim.isAir() || !claim.equals(classicPlotWorld.WALL_BLOCK))) {
|
||||||
for (PlotId id : plotIds) {
|
for (PlotId id : plotIds) {
|
||||||
setWall(id, claim.toPattern());
|
setWall(id, claim.toPattern(), queue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true; // return false if unlink has been denied
|
return true; // return false if unlink has been denied
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean startPlotMerge(List<PlotId> plotIds) {
|
@Override public boolean startPlotMerge(@Nonnull List<PlotId> plotIds, @Nullable QueueCoordinator queue) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean startPlotUnlink(List<PlotId> plotIds) {
|
@Override public boolean startPlotUnlink(@Nonnull List<PlotId> plotIds, @Nullable QueueCoordinator queue) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean claimPlot(Plot plot) {
|
@Override public boolean claimPlot(@Nonnull Plot plot, @Nullable QueueCoordinator queue) {
|
||||||
final BlockBucket claim = classicPlotWorld.CLAIMED_WALL_BLOCK;
|
final BlockBucket claim = classicPlotWorld.CLAIMED_WALL_BLOCK;
|
||||||
if (!claim.isAir() || !claim.equals(classicPlotWorld.WALL_BLOCK)) {
|
if (classicPlotWorld.PLACE_TOP_BLOCK && (!claim.isAir() || !claim.equals(classicPlotWorld.WALL_BLOCK))) {
|
||||||
return setWall(plot.getId(), claim.toPattern());
|
return setWall(plot.getId(), claim.toPattern(), queue);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public String[] getPlotComponents(PlotId plotId) {
|
@Override public String[] getPlotComponents(@Nonnull PlotId plotId) {
|
||||||
return ClassicPlotManagerComponent.stringValues();
|
return ClassicPlotManagerComponent.stringValues();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -530,11 +604,10 @@ public class ClassicPlotManager extends SquarePlotManager {
|
|||||||
* @param plot The plot
|
* @param plot The plot
|
||||||
* @return The location where a sign should be
|
* @return The location where a sign should be
|
||||||
*/
|
*/
|
||||||
@Override public Location getSignLoc(Plot plot) {
|
@Override public Location getSignLoc(@Nonnull Plot plot) {
|
||||||
plot = plot.getBasePlot(false);
|
plot = plot.getBasePlot(false);
|
||||||
final Location bot = plot.getBottomAbs();
|
final Location bot = plot.getBottomAbs();
|
||||||
return Location.at(classicPlotWorld.getWorldName(), bot.getX() - 1,
|
return Location.at(classicPlotWorld.getWorldName(), bot.getX() - 1, classicPlotWorld.ROAD_HEIGHT + 1, bot.getZ() - 2);
|
||||||
classicPlotWorld.ROAD_HEIGHT + 1, bot.getZ() - 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,7 @@ public abstract class ClassicPlotWorld extends SquarePlotWorld {
|
|||||||
public BlockBucket ROAD_BLOCK = new BlockBucket(BlockTypes.QUARTZ_BLOCK);
|
public BlockBucket ROAD_BLOCK = new BlockBucket(BlockTypes.QUARTZ_BLOCK);
|
||||||
// BlockUtil.get((short) 155, (byte) 0);
|
// BlockUtil.get((short) 155, (byte) 0);
|
||||||
public boolean PLOT_BEDROCK = true;
|
public boolean PLOT_BEDROCK = true;
|
||||||
|
public boolean PLACE_TOP_BLOCK = true;
|
||||||
|
|
||||||
public ClassicPlotWorld(@Nonnull final String worldName,
|
public ClassicPlotWorld(@Nonnull final String worldName,
|
||||||
@Nullable final String id,
|
@Nullable final String id,
|
||||||
@ -91,6 +92,8 @@ public abstract class ClassicPlotWorld extends SquarePlotWorld {
|
|||||||
ConfigurationUtil.BLOCK_BUCKET),
|
ConfigurationUtil.BLOCK_BUCKET),
|
||||||
new ConfigurationNode("wall.block_claimed", this.CLAIMED_WALL_BLOCK,
|
new ConfigurationNode("wall.block_claimed", this.CLAIMED_WALL_BLOCK,
|
||||||
"Wall block (claimed)", ConfigurationUtil.BLOCK_BUCKET),
|
"Wall block (claimed)", ConfigurationUtil.BLOCK_BUCKET),
|
||||||
|
new ConfigurationNode("wall.place_top_block", this.PLACE_TOP_BLOCK,
|
||||||
|
"Place or not the top block", ConfigurationUtil.BOOLEAN),
|
||||||
new ConfigurationNode("road.width", this.ROAD_WIDTH, "Road width",
|
new ConfigurationNode("road.width", this.ROAD_WIDTH, "Road width",
|
||||||
ConfigurationUtil.INTEGER),
|
ConfigurationUtil.INTEGER),
|
||||||
new ConfigurationNode("road.height", this.ROAD_HEIGHT, "Road height",
|
new ConfigurationNode("road.height", this.ROAD_HEIGHT, "Road height",
|
||||||
@ -121,5 +124,6 @@ public abstract class ClassicPlotWorld extends SquarePlotWorld {
|
|||||||
this.WALL_FILLING = new BlockBucket(config.getString("wall.filling"));
|
this.WALL_FILLING = new BlockBucket(config.getString("wall.filling"));
|
||||||
this.WALL_HEIGHT = Math.min(254, config.getInt("wall.height"));
|
this.WALL_HEIGHT = Math.min(254, config.getInt("wall.height"));
|
||||||
this.CLAIMED_WALL_BLOCK = new BlockBucket(config.getString("wall.block_claimed"));
|
this.CLAIMED_WALL_BLOCK = new BlockBucket(config.getString("wall.block_claimed"));
|
||||||
|
this.PLACE_TOP_BLOCK = config.getBoolean("wall.place_top_block");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ import com.plotsquared.core.inject.factory.HybridPlotWorldFactory;
|
|||||||
import com.plotsquared.core.location.Location;
|
import com.plotsquared.core.location.Location;
|
||||||
import com.plotsquared.core.plot.PlotArea;
|
import com.plotsquared.core.plot.PlotArea;
|
||||||
import com.plotsquared.core.plot.PlotId;
|
import com.plotsquared.core.plot.PlotId;
|
||||||
import com.plotsquared.core.queue.ScopedLocalBlockQueue;
|
import com.plotsquared.core.queue.ScopedQueueCoordinator;
|
||||||
import com.plotsquared.core.util.MathMan;
|
import com.plotsquared.core.util.MathMan;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
@ -53,7 +53,7 @@ public class HybridGen extends IndependentPlotGenerator {
|
|||||||
return PlotSquared.platform().getPluginName();
|
return PlotSquared.platform().getPluginName();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void placeSchem(HybridPlotWorld world, ScopedLocalBlockQueue result, short relativeX,
|
private void placeSchem(HybridPlotWorld world, ScopedQueueCoordinator result, short relativeX,
|
||||||
short relativeZ, int x, int z, boolean isRoad) {
|
short relativeZ, int x, int z, boolean isRoad) {
|
||||||
int minY; // Math.min(world.PLOT_HEIGHT, world.ROAD_HEIGHT);
|
int minY; // Math.min(world.PLOT_HEIGHT, world.ROAD_HEIGHT);
|
||||||
if ((isRoad && Settings.Schematics.PASTE_ROAD_ON_TOP) || (!isRoad
|
if ((isRoad && Settings.Schematics.PASTE_ROAD_ON_TOP) || (!isRoad
|
||||||
@ -77,7 +77,7 @@ public class HybridGen extends IndependentPlotGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void generateChunk(@Nonnull ScopedLocalBlockQueue result, @Nonnull PlotArea settings) {
|
public void generateChunk(@Nonnull ScopedQueueCoordinator result, @Nonnull PlotArea settings) {
|
||||||
Preconditions.checkNotNull(result, "result cannot be null");
|
Preconditions.checkNotNull(result, "result cannot be null");
|
||||||
Preconditions.checkNotNull(settings, "settings cannot be null");
|
Preconditions.checkNotNull(settings, "settings cannot be null");
|
||||||
|
|
||||||
@ -181,8 +181,10 @@ public class HybridGen extends IndependentPlotGenerator {
|
|||||||
result.setBlock(x, y, z, hybridPlotWorld.WALL_FILLING.toPattern());
|
result.setBlock(x, y, z, hybridPlotWorld.WALL_FILLING.toPattern());
|
||||||
}
|
}
|
||||||
if (!hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) {
|
if (!hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) {
|
||||||
|
if (hybridPlotWorld.PLACE_TOP_BLOCK) {
|
||||||
result.setBlock(x, hybridPlotWorld.WALL_HEIGHT + 1, z,
|
result.setBlock(x, hybridPlotWorld.WALL_HEIGHT + 1, z,
|
||||||
hybridPlotWorld.WALL_BLOCK.toPattern());
|
hybridPlotWorld.WALL_BLOCK.toPattern());
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z,
|
placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z,
|
||||||
true);
|
true);
|
||||||
@ -206,8 +208,10 @@ public class HybridGen extends IndependentPlotGenerator {
|
|||||||
result.setBlock(x, y, z, hybridPlotWorld.WALL_FILLING.toPattern());
|
result.setBlock(x, y, z, hybridPlotWorld.WALL_FILLING.toPattern());
|
||||||
}
|
}
|
||||||
if (!hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) {
|
if (!hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) {
|
||||||
|
if (hybridPlotWorld.PLACE_TOP_BLOCK) {
|
||||||
result.setBlock(x, hybridPlotWorld.WALL_HEIGHT + 1, z,
|
result.setBlock(x, hybridPlotWorld.WALL_HEIGHT + 1, z,
|
||||||
hybridPlotWorld.WALL_BLOCK.toPattern());
|
hybridPlotWorld.WALL_BLOCK.toPattern());
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z,
|
placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z,
|
||||||
true);
|
true);
|
||||||
|
@ -34,21 +34,22 @@ import com.plotsquared.core.plot.Plot;
|
|||||||
import com.plotsquared.core.plot.PlotAreaTerrainType;
|
import com.plotsquared.core.plot.PlotAreaTerrainType;
|
||||||
import com.plotsquared.core.plot.PlotAreaType;
|
import com.plotsquared.core.plot.PlotAreaType;
|
||||||
import com.plotsquared.core.plot.PlotId;
|
import com.plotsquared.core.plot.PlotId;
|
||||||
import com.plotsquared.core.queue.LocalBlockQueue;
|
import com.plotsquared.core.queue.QueueCoordinator;
|
||||||
import com.plotsquared.core.util.ChunkManager;
|
|
||||||
import com.plotsquared.core.util.FileBytes;
|
import com.plotsquared.core.util.FileBytes;
|
||||||
import com.plotsquared.core.util.FileUtils;
|
import com.plotsquared.core.util.FileUtils;
|
||||||
import com.plotsquared.core.util.MathMan;
|
import com.plotsquared.core.util.MathMan;
|
||||||
import com.plotsquared.core.util.RegionManager;
|
import com.plotsquared.core.util.RegionManager;
|
||||||
import com.plotsquared.core.util.WorldUtil;
|
import com.plotsquared.core.util.WorldUtil;
|
||||||
import com.plotsquared.core.util.task.RunnableVal;
|
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
|
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
@ -62,34 +63,24 @@ public class HybridPlotManager extends ClassicPlotManager {
|
|||||||
private final HybridPlotWorld hybridPlotWorld;
|
private final HybridPlotWorld hybridPlotWorld;
|
||||||
private final RegionManager regionManager;
|
private final RegionManager regionManager;
|
||||||
|
|
||||||
public HybridPlotManager(@Nonnull final HybridPlotWorld hybridPlotWorld,
|
public HybridPlotManager(@Nonnull final HybridPlotWorld hybridPlotWorld, @Nonnull final RegionManager regionManager) {
|
||||||
@Nonnull final RegionManager regionManager) {
|
|
||||||
super(hybridPlotWorld, regionManager);
|
super(hybridPlotWorld, regionManager);
|
||||||
this.hybridPlotWorld = hybridPlotWorld;
|
this.hybridPlotWorld = hybridPlotWorld;
|
||||||
this.regionManager = regionManager;
|
this.regionManager = regionManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void exportTemplate() throws IOException {
|
@Override public void exportTemplate() throws IOException {
|
||||||
HashSet<FileBytes> files = Sets.newHashSet(
|
HashSet<FileBytes> files = Sets.newHashSet(new FileBytes(Settings.Paths.TEMPLATES + "/tmp-data.yml", Template.getBytes(hybridPlotWorld)));
|
||||||
new FileBytes(Settings.Paths.TEMPLATES + "/tmp-data.yml",
|
String dir = "schematics" + File.separator + "GEN_ROAD_SCHEMATIC" + File.separator + hybridPlotWorld.getWorldName() + File.separator;
|
||||||
Template.getBytes(hybridPlotWorld)));
|
|
||||||
String dir =
|
|
||||||
"schematics" + File.separator + "GEN_ROAD_SCHEMATIC" + File.separator + hybridPlotWorld
|
|
||||||
.getWorldName() + File.separator;
|
|
||||||
try {
|
try {
|
||||||
File sideRoad =
|
File sideRoad = FileUtils.getFile(PlotSquared.platform().getDirectory(), dir + "sideroad.schem");
|
||||||
FileUtils.getFile(PlotSquared.platform().getDirectory(), dir + "sideroad.schem");
|
String newDir = "schematics" + File.separator + "GEN_ROAD_SCHEMATIC" + File.separator + "__TEMP_DIR__" + File.separator;
|
||||||
String newDir = "schematics" + File.separator + "GEN_ROAD_SCHEMATIC" + File.separator
|
|
||||||
+ "__TEMP_DIR__" + File.separator;
|
|
||||||
if (sideRoad.exists()) {
|
if (sideRoad.exists()) {
|
||||||
files.add(new FileBytes(newDir + "sideroad.schem",
|
files.add(new FileBytes(newDir + "sideroad.schem", Files.readAllBytes(sideRoad.toPath())));
|
||||||
Files.readAllBytes(sideRoad.toPath())));
|
|
||||||
}
|
}
|
||||||
File intersection =
|
File intersection = FileUtils.getFile(PlotSquared.platform().getDirectory(), dir + "intersection.schem");
|
||||||
FileUtils.getFile(PlotSquared.platform().getDirectory(), dir + "intersection.schem");
|
|
||||||
if (intersection.exists()) {
|
if (intersection.exists()) {
|
||||||
files.add(new FileBytes(newDir + "intersection.schem",
|
files.add(new FileBytes(newDir + "intersection.schem", Files.readAllBytes(intersection.toPath())));
|
||||||
Files.readAllBytes(intersection.toPath())));
|
|
||||||
}
|
}
|
||||||
File plot = FileUtils.getFile(PlotSquared.platform().getDirectory(), dir + "plot.schem");
|
File plot = FileUtils.getFile(PlotSquared.platform().getDirectory(), dir + "plot.schem");
|
||||||
if (plot.exists()) {
|
if (plot.exists()) {
|
||||||
@ -101,42 +92,39 @@ public class HybridPlotManager extends ClassicPlotManager {
|
|||||||
Template.zipAll(hybridPlotWorld.getWorldName(), files);
|
Template.zipAll(hybridPlotWorld.getWorldName(), files);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean createRoadEast(Plot plot) {
|
@Override public boolean createRoadEast(@Nonnull final Plot plot, @Nullable QueueCoordinator queue) {
|
||||||
super.createRoadEast(plot);
|
super.createRoadEast(plot, queue);
|
||||||
PlotId id = plot.getId();
|
PlotId id = plot.getId();
|
||||||
PlotId id2 = PlotId.of(id.getX() + 1, id.getY());
|
PlotId id2 = PlotId.of(id.getX() + 1, id.getY());
|
||||||
Location bot = getPlotBottomLocAbs(id2);
|
Location bot = getPlotBottomLocAbs(id2);
|
||||||
Location top = getPlotTopLocAbs(id);
|
Location top = getPlotTopLocAbs(id);
|
||||||
Location pos1 = Location.at(hybridPlotWorld.getWorldName(), top.getX() + 1, 0, bot.getZ() - 1);
|
Location pos1 = Location.at(hybridPlotWorld.getWorldName(), top.getX() + 1, 0, bot.getZ() - 1);
|
||||||
Location pos2 = Location.at(hybridPlotWorld.getWorldName(), bot.getX(),
|
Location pos2 = Location.at(hybridPlotWorld.getWorldName(), bot.getX(), Math.min(getWorldHeight(), 255), top.getZ() + 1);
|
||||||
Math.min(getWorldHeight(), 255), top.getZ() + 1);
|
|
||||||
this.resetBiome(hybridPlotWorld, pos1, pos2);
|
this.resetBiome(hybridPlotWorld, pos1, pos2);
|
||||||
if (!hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) {
|
if (!hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
LocalBlockQueue queue = hybridPlotWorld.getQueue(false);
|
boolean enqueue = false;
|
||||||
|
if (queue == null) {
|
||||||
|
queue = hybridPlotWorld.getQueue();
|
||||||
|
enqueue = true;
|
||||||
|
}
|
||||||
createSchemAbs(queue, pos1, pos2, true);
|
createSchemAbs(queue, pos1, pos2, true);
|
||||||
queue.enqueue();
|
return !enqueue || queue.enqueue();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resetBiome(@Nonnull final HybridPlotWorld hybridPlotWorld, @Nonnull final Location pos1,
|
private void resetBiome(@Nonnull final HybridPlotWorld hybridPlotWorld, @Nonnull final Location pos1, @Nonnull final Location pos2) {
|
||||||
@Nonnull final Location pos2) {
|
|
||||||
BiomeType biome = hybridPlotWorld.getPlotBiome();
|
BiomeType biome = hybridPlotWorld.getPlotBiome();
|
||||||
if (!Objects.equals(PlotSquared.platform().getWorldUtil()
|
if (!Objects.equals(PlotSquared.platform().getWorldUtil()
|
||||||
.getBiomeSynchronous(hybridPlotWorld.getWorldName(), (pos1.getX() + pos2.getX()) / 2,
|
.getBiomeSynchronous(hybridPlotWorld.getWorldName(), (pos1.getX() + pos2.getX()) / 2, (pos1.getZ() + pos2.getZ()) / 2), biome)) {
|
||||||
(pos1.getZ() + pos2.getZ()) / 2), biome)) {
|
WorldUtil.setBiome(hybridPlotWorld.getWorldName(), pos1.getX(), pos1.getZ(), pos2.getX(), pos2.getZ(), biome);
|
||||||
WorldUtil.setBiome(hybridPlotWorld.getWorldName(), pos1.getX(), pos1.getZ(), pos2.getX(), pos2.getZ(),
|
|
||||||
biome);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createSchemAbs(LocalBlockQueue queue, Location pos1, Location pos2,
|
private void createSchemAbs(@Nonnull final QueueCoordinator queue, @Nonnull final Location pos1, @Nonnull final Location pos2, boolean isRoad) {
|
||||||
boolean isRoad) {
|
|
||||||
int size = hybridPlotWorld.SIZE;
|
int size = hybridPlotWorld.SIZE;
|
||||||
int minY;
|
int minY;
|
||||||
if ((isRoad && Settings.Schematics.PASTE_ROAD_ON_TOP) || (!isRoad
|
if ((isRoad && Settings.Schematics.PASTE_ROAD_ON_TOP) || (!isRoad && Settings.Schematics.PASTE_ON_TOP)) {
|
||||||
&& Settings.Schematics.PASTE_ON_TOP)) {
|
|
||||||
minY = hybridPlotWorld.SCHEM_Y;
|
minY = hybridPlotWorld.SCHEM_Y;
|
||||||
} else {
|
} else {
|
||||||
minY = 1;
|
minY = 1;
|
||||||
@ -173,37 +161,43 @@ public class HybridPlotManager extends ClassicPlotManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean createRoadSouth(Plot plot) {
|
@Override public boolean createRoadSouth(@Nonnull final Plot plot, @Nullable QueueCoordinator queue) {
|
||||||
super.createRoadSouth(plot);
|
super.createRoadSouth(plot, queue);
|
||||||
PlotId id = plot.getId();
|
PlotId id = plot.getId();
|
||||||
PlotId id2 = PlotId.of(id.getX(), id.getY() + 1);
|
PlotId id2 = PlotId.of(id.getX(), id.getY() + 1);
|
||||||
Location bot = getPlotBottomLocAbs(id2);
|
Location bot = getPlotBottomLocAbs(id2);
|
||||||
Location top = getPlotTopLocAbs(id);
|
Location top = getPlotTopLocAbs(id);
|
||||||
Location pos1 = Location.at(hybridPlotWorld.getWorldName(), bot.getX() - 1, 0, top.getZ() + 1);
|
Location pos1 = Location.at(hybridPlotWorld.getWorldName(), bot.getX() - 1, 0, top.getZ() + 1);
|
||||||
Location pos2 = Location.at(hybridPlotWorld.getWorldName(), top.getX() + 1,
|
Location pos2 = Location.at(hybridPlotWorld.getWorldName(), top.getX() + 1, Math.min(getWorldHeight(), 255), bot.getZ());
|
||||||
Math.min(getWorldHeight(), 255), bot.getZ());
|
|
||||||
this.resetBiome(hybridPlotWorld, pos1, pos2);
|
this.resetBiome(hybridPlotWorld, pos1, pos2);
|
||||||
if (!hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) {
|
if (!hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
LocalBlockQueue queue = hybridPlotWorld.getQueue(false);
|
boolean enqueue = false;
|
||||||
|
if (queue == null) {
|
||||||
|
enqueue = true;
|
||||||
|
queue = hybridPlotWorld.getQueue();
|
||||||
|
}
|
||||||
createSchemAbs(queue, pos1, pos2, true);
|
createSchemAbs(queue, pos1, pos2, true);
|
||||||
queue.enqueue();
|
return !enqueue || queue.enqueue();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean createRoadSouthEast(Plot plot) {
|
@Override public boolean createRoadSouthEast(@Nonnull final Plot plot, @Nullable QueueCoordinator queue) {
|
||||||
super.createRoadSouthEast(plot);
|
super.createRoadSouthEast(plot, queue);
|
||||||
PlotId id = plot.getId();
|
PlotId id = plot.getId();
|
||||||
PlotId id2 = PlotId.of(id.getX() + 1, id.getY() + 1);
|
PlotId id2 = PlotId.of(id.getX() + 1, id.getY() + 1);
|
||||||
Location pos1 = getPlotTopLocAbs(id).add(1, 0, 1).withY(0);
|
Location pos1 = getPlotTopLocAbs(id).add(1, 0, 1).withY(0);
|
||||||
Location pos2 = getPlotBottomLocAbs(id2).withY(Math.min(getWorldHeight(), 255));
|
Location pos2 = getPlotBottomLocAbs(id2).withY(Math.min(getWorldHeight(), 255));
|
||||||
LocalBlockQueue queue = hybridPlotWorld.getQueue(false);
|
boolean enqueue = false;
|
||||||
|
if (queue == null) {
|
||||||
|
enqueue = true;
|
||||||
|
queue = hybridPlotWorld.getQueue();
|
||||||
|
}
|
||||||
createSchemAbs(queue, pos1, pos2, true);
|
createSchemAbs(queue, pos1, pos2, true);
|
||||||
if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) {
|
if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) {
|
||||||
createSchemAbs(queue, pos1, pos2, true);
|
createSchemAbs(queue, pos1, pos2, true);
|
||||||
}
|
}
|
||||||
return queue.enqueue();
|
return !enqueue || queue.enqueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -213,7 +207,7 @@ public class HybridPlotManager extends ClassicPlotManager {
|
|||||||
* don't need to do something quite as complex unless you happen to have 512x512 sized plots.
|
* don't need to do something quite as complex unless you happen to have 512x512 sized plots.
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
@Override public boolean clearPlot(Plot plot, final Runnable whenDone) {
|
@Override public boolean clearPlot(@Nonnull final Plot plot, @Nullable final Runnable whenDone, @Nullable QueueCoordinator queue) {
|
||||||
if (this.regionManager.notifyClear(this)) {
|
if (this.regionManager.notifyClear(this)) {
|
||||||
//If this returns false, the clear didn't work
|
//If this returns false, the clear didn't work
|
||||||
if (this.regionManager.handleClear(plot, whenDone, this)) {
|
if (this.regionManager.handleClear(plot, whenDone, this)) {
|
||||||
@ -221,12 +215,11 @@ public class HybridPlotManager extends ClassicPlotManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
final String world = hybridPlotWorld.getWorldName();
|
final String world = hybridPlotWorld.getWorldName();
|
||||||
Location pos1 = plot.getBottomAbs();
|
final Location pos1 = plot.getBottomAbs();
|
||||||
Location pos2 = plot.getExtendedTopAbs();
|
final Location pos2 = plot.getExtendedTopAbs();
|
||||||
// If augmented
|
// If augmented
|
||||||
final boolean canRegen =
|
final boolean canRegen =
|
||||||
(hybridPlotWorld.getType() == PlotAreaType.AUGMENTED) && (hybridPlotWorld.getTerrain()
|
(hybridPlotWorld.getType() == PlotAreaType.AUGMENTED) && (hybridPlotWorld.getTerrain() != PlotAreaTerrainType.NONE) && REGENERATIVE_CLEAR;
|
||||||
!= PlotAreaTerrainType.NONE) && REGENERATIVE_CLEAR;
|
|
||||||
// The component blocks
|
// The component blocks
|
||||||
final Pattern plotfloor = hybridPlotWorld.TOP_BLOCK.toPattern();
|
final Pattern plotfloor = hybridPlotWorld.TOP_BLOCK.toPattern();
|
||||||
final Pattern filling = hybridPlotWorld.MAIN_BLOCK.toPattern();
|
final Pattern filling = hybridPlotWorld.MAIN_BLOCK.toPattern();
|
||||||
@ -240,43 +233,29 @@ public class HybridPlotManager extends ClassicPlotManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final BiomeType biome = hybridPlotWorld.getPlotBiome();
|
final BiomeType biome = hybridPlotWorld.getPlotBiome();
|
||||||
final LocalBlockQueue queue = hybridPlotWorld.getQueue(false);
|
boolean enqueue = false;
|
||||||
ChunkManager.chunkTask(pos1, pos2, new RunnableVal<int[]>() {
|
if (queue == null) {
|
||||||
@Override public void run(int[] value) {
|
enqueue = true;
|
||||||
// If the chunk isn't near the edge and it isn't an augmented world we can just regen the whole chunk
|
queue = hybridPlotWorld.getQueue();
|
||||||
if (canRegen && (value[6] == 0)) {
|
|
||||||
queue.regenChunk(value[0], value[1]);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
/* Otherwise we need to set each component, as we don't want to regenerate the road or other plots that share the same chunk.*/
|
if (!canRegen) {
|
||||||
// Set the biome
|
queue.setCuboid(pos1.withY(0), pos2.withY(0), bedrock);
|
||||||
WorldUtil.setBiome(world, value[2], value[3], value[4], value[5], biome);
|
|
||||||
// These two locations are for each component (e.g. bedrock, main block, floor, air)
|
|
||||||
Location bot = Location.at(world, value[2], 0, value[3]);
|
|
||||||
Location top = Location.at(world, value[4], 1, value[5]);
|
|
||||||
queue.setCuboid(bot, top, bedrock);
|
|
||||||
// Each component has a different layer
|
// Each component has a different layer
|
||||||
bot = bot.withY(1);
|
queue.setCuboid(pos1.withY(1), pos2.withY(hybridPlotWorld.PLOT_HEIGHT - 1), filling);
|
||||||
top = top.withY(hybridPlotWorld.PLOT_HEIGHT);
|
queue.setCuboid(pos1.withY(hybridPlotWorld.PLOT_HEIGHT), pos2.withY(hybridPlotWorld.PLOT_HEIGHT), plotfloor);
|
||||||
queue.setCuboid(bot, top, filling);
|
queue.setCuboid(pos1.withY(hybridPlotWorld.PLOT_HEIGHT + 1), pos2.withY(getWorldHeight()), air);
|
||||||
bot = bot.withY(hybridPlotWorld.PLOT_HEIGHT);
|
queue.setBiomeCuboid(pos1, pos2, biome);
|
||||||
top = top.withY(hybridPlotWorld.PLOT_HEIGHT + 1);
|
} else {
|
||||||
queue.setCuboid(bot, top, plotfloor);
|
queue.setRegenRegion(new CuboidRegion(pos1.getBlockVector3(), pos2.getBlockVector3()));
|
||||||
bot = bot.withY(hybridPlotWorld.PLOT_HEIGHT + 1);
|
|
||||||
top = top.withY(getWorldHeight());
|
|
||||||
queue.setCuboid(bot, top, air);
|
|
||||||
// And finally set the schematic, the y value is unimportant for this function
|
|
||||||
pastePlotSchematic(queue, bot, top);
|
|
||||||
}
|
}
|
||||||
}, () -> {
|
pastePlotSchematic(queue, pos1, pos2);
|
||||||
queue.enqueue();
|
if (whenDone != null) {
|
||||||
// And notify whatever called this when plot clearing is done
|
queue.setCompleteTask(whenDone);
|
||||||
PlotSquared.platform().getGlobalBlockQueue().addEmptyTask(whenDone);
|
}
|
||||||
}, 10);
|
return !enqueue || queue.enqueue();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void pastePlotSchematic(LocalBlockQueue queue, Location bottom, Location top) {
|
public void pastePlotSchematic(@Nonnull final QueueCoordinator queue, @Nonnull final Location bottom, @Nonnull final Location top) {
|
||||||
if (!hybridPlotWorld.PLOT_SCHEMATIC) {
|
if (!hybridPlotWorld.PLOT_SCHEMATIC) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -289,7 +268,7 @@ public class HybridPlotManager extends ClassicPlotManager {
|
|||||||
* @param plot The plot
|
* @param plot The plot
|
||||||
* @return The location where a sign should be
|
* @return The location where a sign should be
|
||||||
*/
|
*/
|
||||||
@Override public Location getSignLoc(Plot plot) {
|
@Override public Location getSignLoc(@Nonnull final @NotNull Plot plot) {
|
||||||
return hybridPlotWorld.getSignLocation(plot);
|
return hybridPlotWorld.getSignLocation(plot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +41,6 @@ import com.plotsquared.core.queue.GlobalBlockQueue;
|
|||||||
import com.plotsquared.core.util.EconHandler;
|
import com.plotsquared.core.util.EconHandler;
|
||||||
import com.plotsquared.core.util.FileUtils;
|
import com.plotsquared.core.util.FileUtils;
|
||||||
import com.plotsquared.core.util.MathMan;
|
import com.plotsquared.core.util.MathMan;
|
||||||
import com.plotsquared.core.util.RegionManager;
|
|
||||||
import com.plotsquared.core.util.SchematicHandler;
|
import com.plotsquared.core.util.SchematicHandler;
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
import com.sk89q.jnbt.CompoundTagBuilder;
|
import com.sk89q.jnbt.CompoundTagBuilder;
|
||||||
@ -81,8 +80,7 @@ public class HybridPlotWorld extends ClassicPlotWorld {
|
|||||||
private Location SIGN_LOCATION;
|
private Location SIGN_LOCATION;
|
||||||
private File root = null;
|
private File root = null;
|
||||||
|
|
||||||
private final RegionManager regionManager;
|
@Inject private SchematicHandler schematicHandler;
|
||||||
private final SchematicHandler schematicHandler;
|
|
||||||
|
|
||||||
@Inject public HybridPlotWorld(@Assisted("world") final String worldName,
|
@Inject public HybridPlotWorld(@Assisted("world") final String worldName,
|
||||||
@Nullable @Assisted("id") final String id,
|
@Nullable @Assisted("id") final String id,
|
||||||
@ -90,13 +88,10 @@ public class HybridPlotWorld extends ClassicPlotWorld {
|
|||||||
@Nullable @Assisted("min") final PlotId min,
|
@Nullable @Assisted("min") final PlotId min,
|
||||||
@Nullable @Assisted("max") final PlotId max,
|
@Nullable @Assisted("max") final PlotId max,
|
||||||
@WorldConfig @Nonnull final YamlConfiguration worldConfiguration,
|
@WorldConfig @Nonnull final YamlConfiguration worldConfiguration,
|
||||||
@Nonnull final RegionManager regionManager,
|
|
||||||
@Nonnull final SchematicHandler schematicHandler,
|
|
||||||
@Nonnull final GlobalBlockQueue blockQueue,
|
@Nonnull final GlobalBlockQueue blockQueue,
|
||||||
@Nullable final EconHandler econHandler) {
|
@Nullable final EconHandler econHandler) {
|
||||||
super(worldName, id, generator, min, max, worldConfiguration, blockQueue, econHandler);
|
super(worldName, id, generator, min, max, worldConfiguration, blockQueue, econHandler);
|
||||||
this.regionManager = regionManager;
|
PlotSquared.platform().getInjector().injectMembers(this);
|
||||||
this.schematicHandler = schematicHandler;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte wrap(byte data, int start) {
|
public static byte wrap(byte data, int start) {
|
||||||
@ -127,11 +122,9 @@ public class HybridPlotWorld extends ClassicPlotWorld {
|
|||||||
Direction direction = MCDirections.fromRotation(rot);
|
Direction direction = MCDirections.fromRotation(rot);
|
||||||
|
|
||||||
if (direction != null) {
|
if (direction != null) {
|
||||||
Vector3 vector = transform.apply(direction.toVector())
|
Vector3 vector = transform.apply(direction.toVector()).subtract(transform.apply(Vector3.ZERO)).normalize();
|
||||||
.subtract(transform.apply(Vector3.ZERO)).normalize();
|
Direction newDirection =
|
||||||
Direction newDirection = Direction.findClosest(vector,
|
Direction.findClosest(vector, Direction.Flag.CARDINAL | Direction.Flag.ORDINAL | Direction.Flag.SECONDARY_ORDINAL);
|
||||||
Direction.Flag.CARDINAL | Direction.Flag.ORDINAL
|
|
||||||
| Direction.Flag.SECONDARY_ORDINAL);
|
|
||||||
|
|
||||||
if (newDirection != null) {
|
if (newDirection != null) {
|
||||||
CompoundTagBuilder builder = tag.createBuilder();
|
CompoundTagBuilder builder = tag.createBuilder();
|
||||||
@ -147,7 +140,7 @@ public class HybridPlotWorld extends ClassicPlotWorld {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull @Override protected PlotManager createManager() {
|
@Nonnull @Override protected PlotManager createManager() {
|
||||||
return new HybridPlotManager(this, this.regionManager);
|
return new HybridPlotManager(this, PlotSquared.platform().getRegionManager());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Location getSignLocation(@Nonnull Plot plot) {
|
public Location getSignLocation(@Nonnull Plot plot) {
|
||||||
@ -218,21 +211,24 @@ public class HybridPlotWorld extends ClassicPlotWorld {
|
|||||||
|
|
||||||
// Try to determine root. This means that plot areas can have separate schematic
|
// Try to determine root. This means that plot areas can have separate schematic
|
||||||
// directories
|
// directories
|
||||||
if (!(root = FileUtils.getFile(PlotSquared.platform().getDirectory(), "schematics/GEN_ROAD_SCHEMATIC/" +
|
if (!(root =
|
||||||
this.getWorldName() + "/" + this.getId())).exists()) {
|
FileUtils.getFile(PlotSquared.platform().getDirectory(), "schematics/GEN_ROAD_SCHEMATIC/" + this.getWorldName() + "/" + this.getId()))
|
||||||
root = FileUtils.getFile(PlotSquared.platform().getDirectory(),
|
.exists()) {
|
||||||
"schematics/GEN_ROAD_SCHEMATIC/" + this.getWorldName());
|
root = FileUtils.getFile(PlotSquared.platform().getDirectory(), "schematics/GEN_ROAD_SCHEMATIC/" + this.getWorldName());
|
||||||
}
|
}
|
||||||
|
|
||||||
File schematic1File = new File(root, "sideroad.schem");
|
File schematic1File = new File(root, "sideroad.schem");
|
||||||
if (!schematic1File.exists())
|
if (!schematic1File.exists()) {
|
||||||
schematic1File = new File(root, "sideroad.schematic");
|
schematic1File = new File(root, "sideroad.schematic");
|
||||||
|
}
|
||||||
File schematic2File = new File(root, "intersection.schem");
|
File schematic2File = new File(root, "intersection.schem");
|
||||||
if (!schematic2File.exists())
|
if (!schematic2File.exists()) {
|
||||||
schematic2File = new File(root, "intersection.schematic");
|
schematic2File = new File(root, "intersection.schematic");
|
||||||
|
}
|
||||||
File schematic3File = new File(root, "plot.schem");
|
File schematic3File = new File(root, "plot.schem");
|
||||||
if (!schematic3File.exists())
|
if (!schematic3File.exists()) {
|
||||||
schematic3File = new File(root, "plot.schematic");
|
schematic3File = new File(root, "plot.schematic");
|
||||||
|
}
|
||||||
Schematic schematic1 = this.schematicHandler.getSchematic(schematic1File);
|
Schematic schematic1 = this.schematicHandler.getSchematic(schematic1File);
|
||||||
Schematic schematic2 = this.schematicHandler.getSchematic(schematic2File);
|
Schematic schematic2 = this.schematicHandler.getSchematic(schematic2File);
|
||||||
Schematic schematic3 = this.schematicHandler.getSchematic(schematic3File);
|
Schematic schematic3 = this.schematicHandler.getSchematic(schematic3File);
|
||||||
@ -285,18 +281,15 @@ public class HybridPlotWorld extends ClassicPlotWorld {
|
|||||||
for (short x = 0; x < w3; x++) {
|
for (short x = 0; x < w3; x++) {
|
||||||
for (short z = 0; z < l3; z++) {
|
for (short z = 0; z < l3; z++) {
|
||||||
for (short y = 0; y < h3; y++) {
|
for (short y = 0; y < h3; y++) {
|
||||||
BaseBlock id = blockArrayClipboard3.getFullBlock(BlockVector3
|
BaseBlock id =
|
||||||
.at(x + min.getBlockX(), y + min.getBlockY(), z + min.getBlockZ()));
|
blockArrayClipboard3.getFullBlock(BlockVector3.at(x + min.getBlockX(), y + min.getBlockY(), z + min.getBlockZ()));
|
||||||
if (!id.getBlockType().getMaterial().isAir()) {
|
if (!id.getBlockType().getMaterial().isAir()) {
|
||||||
addOverlayBlock((short) (x + shift + oddshift + centerShiftX),
|
addOverlayBlock((short) (x + shift + oddshift + centerShiftX), (short) (y + plotY),
|
||||||
(short) (y + plotY), (short) (z + shift + oddshift + centerShiftZ),
|
(short) (z + shift + oddshift + centerShiftZ), id, false, h3);
|
||||||
id, false, h3);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BiomeType biome = blockArrayClipboard3
|
BiomeType biome = blockArrayClipboard3.getBiome(BlockVector2.at(x + min.getBlockX(), z + min.getBlockZ()));
|
||||||
.getBiome(BlockVector2.at(x + min.getBlockX(), z + min.getBlockZ()));
|
addOverlayBiome((short) (x + shift + oddshift + centerShiftX), (short) (z + shift + oddshift + centerShiftZ), biome);
|
||||||
addOverlayBiome((short) (x + shift + oddshift + centerShiftX),
|
|
||||||
(short) (z + shift + oddshift + centerShiftZ), biome);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,20 +318,15 @@ public class HybridPlotWorld extends ClassicPlotWorld {
|
|||||||
for (short x = 0; x < w1; x++) {
|
for (short x = 0; x < w1; x++) {
|
||||||
for (short z = 0; z < l1; z++) {
|
for (short z = 0; z < l1; z++) {
|
||||||
for (short y = 0; y < h1; y++) {
|
for (short y = 0; y < h1; y++) {
|
||||||
BaseBlock id = blockArrayClipboard1.getFullBlock(BlockVector3
|
BaseBlock id = blockArrayClipboard1.getFullBlock(BlockVector3.at(x + min.getBlockX(), y + min.getBlockY(), z + min.getBlockZ()));
|
||||||
.at(x + min.getBlockX(), y + min.getBlockY(), z + min.getBlockZ()));
|
|
||||||
if (!id.getBlockType().getMaterial().isAir()) {
|
if (!id.getBlockType().getMaterial().isAir()) {
|
||||||
addOverlayBlock((short) (x - shift), (short) (y + roadY),
|
addOverlayBlock((short) (x - shift), (short) (y + roadY), (short) (z + shift + oddshift), id, false, h1);
|
||||||
(short) (z + shift + oddshift), id, false, h1);
|
addOverlayBlock((short) (z + shift + oddshift), (short) (y + roadY), (short) (shift - x + (oddshift - 1)), id, true, h1);
|
||||||
addOverlayBlock((short) (z + shift + oddshift), (short) (y + roadY),
|
|
||||||
(short) (shift - x + (oddshift - 1)), id, true, h1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BiomeType biome = blockArrayClipboard1
|
BiomeType biome = blockArrayClipboard1.getBiome(BlockVector2.at(x + min.getBlockX(), z + min.getBlockZ()));
|
||||||
.getBiome(BlockVector2.at(x + min.getBlockX(), z + min.getBlockZ()));
|
|
||||||
addOverlayBiome((short) (x - shift), (short) (z + shift + oddshift), biome);
|
addOverlayBiome((short) (x - shift), (short) (z + shift + oddshift), biome);
|
||||||
addOverlayBiome((short) (z + shift + oddshift),
|
addOverlayBiome((short) (z + shift + oddshift), (short) (shift - x + (oddshift - 1)), biome);
|
||||||
(short) (shift - x + (oddshift - 1)), biome);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -351,22 +339,18 @@ public class HybridPlotWorld extends ClassicPlotWorld {
|
|||||||
for (short x = 0; x < w2; x++) {
|
for (short x = 0; x < w2; x++) {
|
||||||
for (short z = 0; z < l2; z++) {
|
for (short z = 0; z < l2; z++) {
|
||||||
for (short y = 0; y < h2; y++) {
|
for (short y = 0; y < h2; y++) {
|
||||||
BaseBlock id = blockArrayClipboard2.getFullBlock(BlockVector3
|
BaseBlock id = blockArrayClipboard2.getFullBlock(BlockVector3.at(x + min.getBlockX(), y + min.getBlockY(), z + min.getBlockZ()));
|
||||||
.at(x + min.getBlockX(), y + min.getBlockY(), z + min.getBlockZ()));
|
|
||||||
if (!id.getBlockType().getMaterial().isAir()) {
|
if (!id.getBlockType().getMaterial().isAir()) {
|
||||||
addOverlayBlock((short) (x - shift), (short) (y + roadY),
|
addOverlayBlock((short) (x - shift), (short) (y + roadY), (short) (z - shift), id, false, h2);
|
||||||
(short) (z - shift), id, false, h2);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BiomeType biome = blockArrayClipboard2
|
BiomeType biome = blockArrayClipboard2.getBiome(BlockVector2.at(x + min.getBlockX(), z + min.getBlockZ()));
|
||||||
.getBiome(BlockVector2.at(x + min.getBlockX(), z + min.getBlockZ()));
|
|
||||||
addOverlayBiome((short) (x - shift), (short) (z - shift), biome);
|
addOverlayBiome((short) (x - shift), (short) (z - shift), biome);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addOverlayBlock(short x, short y, short z, BaseBlock id, boolean rotate,
|
public void addOverlayBlock(short x, short y, short z, BaseBlock id, boolean rotate, int height) {
|
||||||
int height) {
|
|
||||||
if (z < 0) {
|
if (z < 0) {
|
||||||
z += this.SIZE;
|
z += this.SIZE;
|
||||||
} else if (z >= this.SIZE) {
|
} else if (z >= this.SIZE) {
|
||||||
|
@ -41,9 +41,9 @@ import com.plotsquared.core.plot.flag.GlobalFlagContainer;
|
|||||||
import com.plotsquared.core.plot.flag.PlotFlag;
|
import com.plotsquared.core.plot.flag.PlotFlag;
|
||||||
import com.plotsquared.core.plot.flag.implementations.AnalysisFlag;
|
import com.plotsquared.core.plot.flag.implementations.AnalysisFlag;
|
||||||
import com.plotsquared.core.plot.world.PlotAreaManager;
|
import com.plotsquared.core.plot.world.PlotAreaManager;
|
||||||
import com.plotsquared.core.queue.ChunkBlockQueue;
|
import com.plotsquared.core.queue.ChunkQueueCoordinator;
|
||||||
import com.plotsquared.core.queue.GlobalBlockQueue;
|
import com.plotsquared.core.queue.GlobalBlockQueue;
|
||||||
import com.plotsquared.core.queue.LocalBlockQueue;
|
import com.plotsquared.core.queue.QueueCoordinator;
|
||||||
import com.plotsquared.core.util.ChunkManager;
|
import com.plotsquared.core.util.ChunkManager;
|
||||||
import com.plotsquared.core.util.MathMan;
|
import com.plotsquared.core.util.MathMan;
|
||||||
import com.plotsquared.core.util.RegionManager;
|
import com.plotsquared.core.util.RegionManager;
|
||||||
@ -93,27 +93,26 @@ public class HybridUtils {
|
|||||||
private final ChunkManager chunkManager;
|
private final ChunkManager chunkManager;
|
||||||
private final GlobalBlockQueue blockQueue;
|
private final GlobalBlockQueue blockQueue;
|
||||||
private final WorldUtil worldUtil;
|
private final WorldUtil worldUtil;
|
||||||
private final RegionManager regionManager;
|
|
||||||
private final SchematicHandler schematicHandler;
|
private final SchematicHandler schematicHandler;
|
||||||
|
|
||||||
@Inject public HybridUtils(@Nonnull final PlotAreaManager plotAreaManager,
|
@Inject public HybridUtils(@Nonnull final PlotAreaManager plotAreaManager,
|
||||||
@Nonnull final ChunkManager chunkManager, @Nonnull final GlobalBlockQueue blockQueue,
|
@Nonnull final ChunkManager chunkManager,
|
||||||
@Nonnull final WorldUtil worldUtil, @Nonnull final RegionManager regionManager, @Nonnull final SchematicHandler schematicHandler) {
|
@Nonnull final GlobalBlockQueue blockQueue,
|
||||||
|
@Nonnull final WorldUtil worldUtil,
|
||||||
|
@Nonnull final SchematicHandler schematicHandler) {
|
||||||
this.plotAreaManager = plotAreaManager;
|
this.plotAreaManager = plotAreaManager;
|
||||||
this.chunkManager = chunkManager;
|
this.chunkManager = chunkManager;
|
||||||
this.blockQueue = blockQueue;
|
this.blockQueue = blockQueue;
|
||||||
this.worldUtil = worldUtil;
|
this.worldUtil = worldUtil;
|
||||||
this.regionManager = regionManager;
|
|
||||||
this.schematicHandler = schematicHandler;
|
this.schematicHandler = schematicHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void regeneratePlotWalls(final PlotArea area) {
|
public void regeneratePlotWalls(final PlotArea area) {
|
||||||
PlotManager plotManager = area.getPlotManager();
|
PlotManager plotManager = area.getPlotManager();
|
||||||
plotManager.regenerateAllPlotWalls();
|
plotManager.regenerateAllPlotWalls(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void analyzeRegion(final String world, final CuboidRegion region,
|
public void analyzeRegion(final String world, final CuboidRegion region, final RunnableVal<PlotAnalysis> whenDone) {
|
||||||
final RunnableVal<PlotAnalysis> whenDone) {
|
|
||||||
// int diff, int variety, int vertices, int rotation, int height_sd
|
// int diff, int variety, int vertices, int rotation, int height_sd
|
||||||
/*
|
/*
|
||||||
* diff: compare to base by looping through all blocks
|
* diff: compare to base by looping through all blocks
|
||||||
@ -127,8 +126,6 @@ public class HybridUtils {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
TaskManager.runTaskAsync(() -> {
|
TaskManager.runTaskAsync(() -> {
|
||||||
final LocalBlockQueue queue = blockQueue.getNewQueue(world, false);
|
|
||||||
|
|
||||||
final BlockVector3 bot = region.getMinimumPoint();
|
final BlockVector3 bot = region.getMinimumPoint();
|
||||||
final BlockVector3 top = region.getMaximumPoint();
|
final BlockVector3 top = region.getMaximumPoint();
|
||||||
|
|
||||||
@ -150,7 +147,7 @@ public class HybridUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
HybridPlotWorld hpw = (HybridPlotWorld) area;
|
HybridPlotWorld hpw = (HybridPlotWorld) area;
|
||||||
ChunkBlockQueue chunk = new ChunkBlockQueue(bot, top, false);
|
ChunkQueueCoordinator chunk = new ChunkQueueCoordinator(bot, top, false);
|
||||||
hpw.getGenerator().generateChunk(chunk, hpw);
|
hpw.getGenerator().generateChunk(chunk, hpw);
|
||||||
|
|
||||||
final BlockState[][][] oldBlocks = chunk.getBlocks();
|
final BlockState[][][] oldBlocks = chunk.getBlocks();
|
||||||
@ -160,6 +157,55 @@ public class HybridUtils {
|
|||||||
System.gc();
|
System.gc();
|
||||||
System.gc();
|
System.gc();
|
||||||
|
|
||||||
|
QueueCoordinator queue = area.getQueue();
|
||||||
|
queue.addReadChunks(region.getChunks());
|
||||||
|
queue.setChunkConsumer(blockVector2 -> {
|
||||||
|
int X = blockVector2.getX();
|
||||||
|
int Z = blockVector2.getZ();
|
||||||
|
int minX;
|
||||||
|
if (X == cbx) {
|
||||||
|
minX = bx & 15;
|
||||||
|
} else {
|
||||||
|
minX = 0;
|
||||||
|
}
|
||||||
|
int minZ;
|
||||||
|
if (Z == cbz) {
|
||||||
|
minZ = bz & 15;
|
||||||
|
} else {
|
||||||
|
minZ = 0;
|
||||||
|
}
|
||||||
|
int maxX;
|
||||||
|
if (X == ctx) {
|
||||||
|
maxX = tx & 15;
|
||||||
|
} else {
|
||||||
|
maxX = 16;
|
||||||
|
}
|
||||||
|
int maxZ;
|
||||||
|
if (Z == ctz) {
|
||||||
|
maxZ = tz & 15;
|
||||||
|
} else {
|
||||||
|
maxZ = 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
int chunkBlockX = X << 4;
|
||||||
|
int chunkBlockZ = Z << 4;
|
||||||
|
|
||||||
|
int xb = chunkBlockX - bx;
|
||||||
|
int zb = chunkBlockZ - bz;
|
||||||
|
for (int x = minX; x <= maxX; x++) {
|
||||||
|
int xx = chunkBlockX + x;
|
||||||
|
for (int z = minZ; z <= maxZ; z++) {
|
||||||
|
int zz = chunkBlockZ + z;
|
||||||
|
for (int y = 0; y < 256; y++) {
|
||||||
|
BlockState block = queue.getBlock(xx, y, zz);
|
||||||
|
int xr = xb + x;
|
||||||
|
int zr = zb + z;
|
||||||
|
newBlocks[y][xr][zr] = block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
final Runnable run = () -> TaskManager.runTaskAsync(() -> {
|
final Runnable run = () -> TaskManager.runTaskAsync(() -> {
|
||||||
int size = width * length;
|
int size = width * length;
|
||||||
int[] changes = new int[size];
|
int[] changes = new int[size];
|
||||||
@ -186,30 +232,23 @@ public class HybridUtils {
|
|||||||
} else {
|
} else {
|
||||||
// check vertices
|
// check vertices
|
||||||
// modifications_adjacent
|
// modifications_adjacent
|
||||||
if (x > 0 && z > 0 && y > 0 && x < width - 1 && z < length - 1
|
if (x > 0 && z > 0 && y > 0 && x < width - 1 && z < length - 1 && y < 255) {
|
||||||
&& y < 255) {
|
if (newBlocks[y - 1][x][z].getBlockType().getMaterial().isAir()) {
|
||||||
if (newBlocks[y - 1][x][z].getBlockType().getMaterial()
|
|
||||||
.isAir()) {
|
|
||||||
faces[i]++;
|
faces[i]++;
|
||||||
}
|
}
|
||||||
if (newBlocks[y][x - 1][z].getBlockType().getMaterial()
|
if (newBlocks[y][x - 1][z].getBlockType().getMaterial().isAir()) {
|
||||||
.isAir()) {
|
|
||||||
faces[i]++;
|
faces[i]++;
|
||||||
}
|
}
|
||||||
if (newBlocks[y][x][z - 1].getBlockType().getMaterial()
|
if (newBlocks[y][x][z - 1].getBlockType().getMaterial().isAir()) {
|
||||||
.isAir()) {
|
|
||||||
faces[i]++;
|
faces[i]++;
|
||||||
}
|
}
|
||||||
if (newBlocks[y + 1][x][z].getBlockType().getMaterial()
|
if (newBlocks[y + 1][x][z].getBlockType().getMaterial().isAir()) {
|
||||||
.isAir()) {
|
|
||||||
faces[i]++;
|
faces[i]++;
|
||||||
}
|
}
|
||||||
if (newBlocks[y][x + 1][z].getBlockType().getMaterial()
|
if (newBlocks[y][x + 1][z].getBlockType().getMaterial().isAir()) {
|
||||||
.isAir()) {
|
|
||||||
faces[i]++;
|
faces[i]++;
|
||||||
}
|
}
|
||||||
if (newBlocks[y][x][z + 1].getBlockType().getMaterial()
|
if (newBlocks[y][x][z + 1].getBlockType().getMaterial().isAir()) {
|
||||||
.isAir()) {
|
|
||||||
faces[i]++;
|
faces[i]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -248,57 +287,8 @@ public class HybridUtils {
|
|||||||
whenDone.value = analysis;
|
whenDone.value = analysis;
|
||||||
whenDone.run();
|
whenDone.run();
|
||||||
});
|
});
|
||||||
System.gc();
|
queue.setCompleteTask(run);
|
||||||
Location botLoc = Location.at(world, bot.getX(), bot.getY(), bot.getZ());
|
queue.enqueue();
|
||||||
Location topLoc = Location.at(world, top.getX(), top.getY(), top.getZ());
|
|
||||||
ChunkManager.chunkTask(botLoc, topLoc, new RunnableVal<int[]>() {
|
|
||||||
@Override public void run(int[] value) {
|
|
||||||
int X = value[0];
|
|
||||||
int Z = value[1];
|
|
||||||
int minX;
|
|
||||||
if (X == cbx) {
|
|
||||||
minX = bx & 15;
|
|
||||||
} else {
|
|
||||||
minX = 0;
|
|
||||||
}
|
|
||||||
int minZ;
|
|
||||||
if (Z == cbz) {
|
|
||||||
minZ = bz & 15;
|
|
||||||
} else {
|
|
||||||
minZ = 0;
|
|
||||||
}
|
|
||||||
int maxX;
|
|
||||||
if (X == ctx) {
|
|
||||||
maxX = tx & 15;
|
|
||||||
} else {
|
|
||||||
maxX = 16;
|
|
||||||
}
|
|
||||||
int maxZ;
|
|
||||||
if (Z == ctz) {
|
|
||||||
maxZ = tz & 15;
|
|
||||||
} else {
|
|
||||||
maxZ = 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
int cbx = X << 4;
|
|
||||||
int cbz = Z << 4;
|
|
||||||
|
|
||||||
int xb = cbx - bx;
|
|
||||||
int zb = cbz - bz;
|
|
||||||
for (int x = minX; x <= maxX; x++) {
|
|
||||||
int xx = cbx + x;
|
|
||||||
for (int z = minZ; z <= maxZ; z++) {
|
|
||||||
int zz = cbz + z;
|
|
||||||
for (int y = 0; y < 256; y++) {
|
|
||||||
BlockState block = queue.getBlock(xx, y, zz);
|
|
||||||
int xr = xb + x;
|
|
||||||
int zr = zb + z;
|
|
||||||
newBlocks[y][xr][zr] = block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, () -> TaskManager.runTaskAsync(run), 5);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -347,9 +337,7 @@ public class HybridUtils {
|
|||||||
result.add(whenDone.value.data_sd);
|
result.add(whenDone.value.data_sd);
|
||||||
result.add(whenDone.value.air_sd);
|
result.add(whenDone.value.air_sd);
|
||||||
result.add(whenDone.value.variety_sd);
|
result.add(whenDone.value.variety_sd);
|
||||||
PlotFlag<?, ?> plotFlag =
|
PlotFlag<?, ?> plotFlag = GlobalFlagContainer.getInstance().getFlag(AnalysisFlag.class).createFlagInstance(result);
|
||||||
GlobalFlagContainer.getInstance().getFlag(AnalysisFlag.class)
|
|
||||||
.createFlagInstance(result);
|
|
||||||
PlotFlagAddEvent event = new PlotFlagAddEvent(plotFlag, origin);
|
PlotFlagAddEvent event = new PlotFlagAddEvent(plotFlag, origin);
|
||||||
if (event.getEventResult() == Result.DENY) {
|
if (event.getEventResult() == Result.DENY) {
|
||||||
return;
|
return;
|
||||||
@ -371,15 +359,13 @@ public class HybridUtils {
|
|||||||
run.run();
|
run.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int checkModified(LocalBlockQueue queue, int x1, int x2, int y1, int y2, int z1, int z2,
|
public int checkModified(QueueCoordinator queue, int x1, int x2, int y1, int y2, int z1, int z2, BlockState[] blocks) {
|
||||||
BlockState[] blocks) {
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (int y = y1; y <= y2; y++) {
|
for (int y = y1; y <= y2; y++) {
|
||||||
for (int x = x1; x <= x2; x++) {
|
for (int x = x1; x <= x2; x++) {
|
||||||
for (int z = z1; z <= z2; z++) {
|
for (int z = z1; z <= z2; z++) {
|
||||||
BlockState block = queue.getBlock(x, y, z);
|
BlockState block = queue.getBlock(x, y, z);
|
||||||
boolean same =
|
boolean same = Arrays.stream(blocks).anyMatch(p -> this.worldUtil.isBlockSame(block, p));
|
||||||
Arrays.stream(blocks).anyMatch(p -> this.worldUtil.isBlockSame(block, p));
|
|
||||||
if (!same) {
|
if (!same) {
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
@ -406,7 +392,7 @@ public class HybridUtils {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
HybridUtils.UPDATE = true;
|
HybridUtils.UPDATE = true;
|
||||||
Set<BlockVector2> regions = this.regionManager.getChunkChunks(area.getWorldName());
|
Set<BlockVector2> regions = this.worldUtil.getChunkChunks(area.getWorldName());
|
||||||
return scheduleRoadUpdate(area, regions, extend, new HashSet<>());
|
return scheduleRoadUpdate(area, regions, extend, new HashSet<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -420,8 +406,7 @@ public class HybridUtils {
|
|||||||
return scheduleRoadUpdate(plot.getArea(), regions, extend, new HashSet<>());
|
return scheduleRoadUpdate(plot.getArea(), regions, extend, new HashSet<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean scheduleRoadUpdate(final PlotArea area, Set<BlockVector2> regions,
|
public boolean scheduleRoadUpdate(final PlotArea area, Set<BlockVector2> regions, final int extend, Set<BlockVector2> chunks) {
|
||||||
final int extend, Set<BlockVector2> chunks) {
|
|
||||||
HybridUtils.regions = regions;
|
HybridUtils.regions = regions;
|
||||||
HybridUtils.area = area;
|
HybridUtils.area = area;
|
||||||
HybridUtils.height = extend;
|
HybridUtils.height = extend;
|
||||||
@ -438,7 +423,6 @@ public class HybridUtils {
|
|||||||
if (!regenedRoad && Settings.DEBUG) {
|
if (!regenedRoad && Settings.DEBUG) {
|
||||||
logger.info("[P2] Failed to regenerate roads");
|
logger.info("[P2] Failed to regenerate roads");
|
||||||
}
|
}
|
||||||
chunkManager.unloadChunk(area.getWorldName(), chunk, true);
|
|
||||||
}
|
}
|
||||||
if (Settings.DEBUG) {
|
if (Settings.DEBUG) {
|
||||||
logger.info("[P2] Cancelled road task");
|
logger.info("[P2] Cancelled road task");
|
||||||
@ -461,13 +445,11 @@ public class HybridUtils {
|
|||||||
try {
|
try {
|
||||||
if (chunks.size() < 1024) {
|
if (chunks.size() < 1024) {
|
||||||
if (!HybridUtils.regions.isEmpty()) {
|
if (!HybridUtils.regions.isEmpty()) {
|
||||||
Iterator<BlockVector2> iterator =
|
Iterator<BlockVector2> iterator = HybridUtils.regions.iterator();
|
||||||
HybridUtils.regions.iterator();
|
|
||||||
BlockVector2 loc = iterator.next();
|
BlockVector2 loc = iterator.next();
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
if (Settings.DEBUG) {
|
if (Settings.DEBUG) {
|
||||||
logger.info("[P2] Updating .mcr: {}, {} (approx 1024 chunks)",
|
logger.info("[P2] Updating .mcr: {}, {} (approx 1024 chunks)", loc.getX(), loc.getZ());
|
||||||
loc.getX(), loc.getZ());
|
|
||||||
logger.info("[P2] - Remaining: {}", HybridUtils.regions.size());
|
logger.info("[P2] - Remaining: {}", HybridUtils.regions.size());
|
||||||
}
|
}
|
||||||
chunks.addAll(getChunks(loc));
|
chunks.addAll(getChunks(loc));
|
||||||
@ -478,12 +460,10 @@ public class HybridUtils {
|
|||||||
TaskManager.getPlatformImplementation().sync(() -> {
|
TaskManager.getPlatformImplementation().sync(() -> {
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
Iterator<BlockVector2> iterator = chunks.iterator();
|
Iterator<BlockVector2> iterator = chunks.iterator();
|
||||||
while (System.currentTimeMillis() - start < 20 && !chunks
|
while (System.currentTimeMillis() - start < 20 && !chunks.isEmpty()) {
|
||||||
.isEmpty()) {
|
|
||||||
final BlockVector2 chunk = iterator.next();
|
final BlockVector2 chunk = iterator.next();
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
boolean regenedRoads =
|
boolean regenedRoads = regenerateRoad(area, chunk, extend);
|
||||||
regenerateRoad(area, chunk, extend);
|
|
||||||
if (!regenedRoads && Settings.DEBUG) {
|
if (!regenedRoads && Settings.DEBUG) {
|
||||||
logger.info("[P2] Failed to regenerate road");
|
logger.info("[P2] Failed to regenerate road");
|
||||||
}
|
}
|
||||||
@ -496,18 +476,10 @@ public class HybridUtils {
|
|||||||
Iterator<BlockVector2> iterator = HybridUtils.regions.iterator();
|
Iterator<BlockVector2> iterator = HybridUtils.regions.iterator();
|
||||||
BlockVector2 loc = iterator.next();
|
BlockVector2 loc = iterator.next();
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
logger.error("[P2] Error! Could not update '{}/region/r.{}.{}.mca' (Corrupt chunk?)",
|
logger.error("[P2] Error! Could not update '{}/region/r.{}.{}.mca' (Corrupt chunk?)", area.getWorldHash(), loc.getX(),
|
||||||
area.getWorldHash(), loc.getX(), loc.getZ());
|
loc.getZ());
|
||||||
int sx = loc.getX() << 5;
|
|
||||||
int sz = loc.getZ() << 5;
|
|
||||||
for (int x = sx; x < sx + 32; x++) {
|
|
||||||
for (int z = sz; z < sz + 32; z++) {
|
|
||||||
chunkManager.unloadChunk(area.getWorldName(), BlockVector2.at(x, z),
|
|
||||||
true);
|
|
||||||
}
|
}
|
||||||
}
|
TaskManager.runTaskLater(task, TaskTime.seconds(1L));
|
||||||
}
|
|
||||||
blockQueue.addEmptyTask(() -> TaskManager.runTaskLater(task, TaskTime.seconds(1L)));
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -517,7 +489,7 @@ public class HybridUtils {
|
|||||||
|
|
||||||
public boolean setupRoadSchematic(Plot plot) {
|
public boolean setupRoadSchematic(Plot plot) {
|
||||||
final String world = plot.getWorldName();
|
final String world = plot.getWorldName();
|
||||||
final LocalBlockQueue queue = blockQueue.getNewQueue(world, false);
|
final QueueCoordinator queue = blockQueue.getNewQueue(worldUtil.getWeWorld(world));
|
||||||
Location bot = plot.getBottomAbs().subtract(1, 0, 1);
|
Location bot = plot.getBottomAbs().subtract(1, 0, 1);
|
||||||
Location top = plot.getTopAbs();
|
Location top = plot.getTopAbs();
|
||||||
final HybridPlotWorld plotworld = (HybridPlotWorld) plot.getArea();
|
final HybridPlotWorld plotworld = (HybridPlotWorld) plot.getArea();
|
||||||
@ -532,14 +504,10 @@ public class HybridUtils {
|
|||||||
int tz = sz - 1;
|
int tz = sz - 1;
|
||||||
int ty = get_ey(plotManager, queue, sx, ex, bz, tz, sy);
|
int ty = get_ey(plotManager, queue, sx, ex, bz, tz, sy);
|
||||||
|
|
||||||
Set<CuboidRegion> sideRoad = new HashSet<>(
|
Set<CuboidRegion> sideRoad = new HashSet<>(Collections.singletonList(RegionUtil.createRegion(sx, ex, sy, ey, sz, ez)));
|
||||||
Collections.singletonList(RegionUtil.createRegion(sx, ex, sy, ey, sz, ez)));
|
final Set<CuboidRegion> intersection = new HashSet<>(Collections.singletonList(RegionUtil.createRegion(sx, ex, sy, ty, bz, tz)));
|
||||||
final Set<CuboidRegion> intersection = new HashSet<>(
|
|
||||||
Collections.singletonList(RegionUtil.createRegion(sx, ex, sy, ty, bz, tz)));
|
|
||||||
|
|
||||||
final String dir =
|
final String dir = "schematics" + File.separator + "GEN_ROAD_SCHEMATIC" + File.separator + plot.getArea().toString() + File.separator;
|
||||||
"schematics" + File.separator + "GEN_ROAD_SCHEMATIC" + File.separator + plot.getArea()
|
|
||||||
.toString() + File.separator;
|
|
||||||
|
|
||||||
this.schematicHandler.getCompoundTag(world, sideRoad, new RunnableVal<CompoundTag>() {
|
this.schematicHandler.getCompoundTag(world, sideRoad, new RunnableVal<CompoundTag>() {
|
||||||
@Override public void run(CompoundTag value) {
|
@Override public void run(CompoundTag value) {
|
||||||
@ -560,8 +528,7 @@ public class HybridUtils {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int get_ey(final PlotManager pm, LocalBlockQueue queue, int sx, int ex, int sz, int ez,
|
public int get_ey(final PlotManager pm, QueueCoordinator queue, int sx, int ex, int sz, int ez, int sy) {
|
||||||
int sy) {
|
|
||||||
int ey = sy;
|
int ey = sy;
|
||||||
for (int x = sx; x <= ex; x++) {
|
for (int x = sx; x <= ex; x++) {
|
||||||
for (int z = sz; z <= ez; z++) {
|
for (int z = sz; z <= ez; z++) {
|
||||||
@ -604,7 +571,7 @@ public class HybridUtils {
|
|||||||
z -= plotWorld.ROAD_OFFSET_Z;
|
z -= plotWorld.ROAD_OFFSET_Z;
|
||||||
final int finalX = x;
|
final int finalX = x;
|
||||||
final int finalZ = z;
|
final int finalZ = z;
|
||||||
LocalBlockQueue queue = this.blockQueue.getNewQueue(plotWorld.getWorldName(), false);
|
QueueCoordinator queue = this.blockQueue.getNewQueue(worldUtil.getWeWorld(plotWorld.getWorldName()));
|
||||||
if (id1 == null || id2 == null || id1 != id2) {
|
if (id1 == null || id2 == null || id1 != id2) {
|
||||||
this.chunkManager.loadChunk(area.getWorldName(), chunk, false).thenRun(() -> {
|
this.chunkManager.loadChunk(area.getWorldName(), chunk, false).thenRun(() -> {
|
||||||
if (id1 != null) {
|
if (id1 != null) {
|
||||||
@ -632,8 +599,7 @@ public class HybridUtils {
|
|||||||
}
|
}
|
||||||
boolean condition;
|
boolean condition;
|
||||||
if (toCheck.get()) {
|
if (toCheck.get()) {
|
||||||
condition = manager.getPlotId(finalX + X + plotWorld.ROAD_OFFSET_X, 1,
|
condition = manager.getPlotId(finalX + X + plotWorld.ROAD_OFFSET_X, 1, finalZ + Z + plotWorld.ROAD_OFFSET_Z) == null;
|
||||||
finalZ + Z + plotWorld.ROAD_OFFSET_Z) == null;
|
|
||||||
} else {
|
} else {
|
||||||
boolean gx = absX > plotWorld.PATH_WIDTH_LOWER;
|
boolean gx = absX > plotWorld.PATH_WIDTH_LOWER;
|
||||||
boolean gz = absZ > plotWorld.PATH_WIDTH_LOWER;
|
boolean gz = absZ > plotWorld.PATH_WIDTH_LOWER;
|
||||||
@ -647,27 +613,23 @@ public class HybridUtils {
|
|||||||
int maxY = Math.max(extend, blocks.length);
|
int maxY = Math.max(extend, blocks.length);
|
||||||
for (int y = 0; y < maxY; y++) {
|
for (int y = 0; y < maxY; y++) {
|
||||||
if (y > blocks.length - 1) {
|
if (y > blocks.length - 1) {
|
||||||
queue.setBlock(finalX + X + plotWorld.ROAD_OFFSET_X, minY + y,
|
queue.setBlock(finalX + X + plotWorld.ROAD_OFFSET_X, minY + y, finalZ + Z + plotWorld.ROAD_OFFSET_Z,
|
||||||
finalZ + Z + plotWorld.ROAD_OFFSET_Z, WEExtent.AIRBASE);
|
WEExtent.AIRBASE);
|
||||||
} else {
|
} else {
|
||||||
BaseBlock block = blocks[y];
|
BaseBlock block = blocks[y];
|
||||||
if (block != null) {
|
if (block != null) {
|
||||||
queue.setBlock(finalX + X + plotWorld.ROAD_OFFSET_X,
|
queue.setBlock(finalX + X + plotWorld.ROAD_OFFSET_X, minY + y, finalZ + Z + plotWorld.ROAD_OFFSET_Z, block);
|
||||||
minY + y, finalZ + Z + plotWorld.ROAD_OFFSET_Z, block);
|
|
||||||
} else {
|
} else {
|
||||||
queue.setBlock(finalX + X + plotWorld.ROAD_OFFSET_X,
|
queue.setBlock(finalX + X + plotWorld.ROAD_OFFSET_X, minY + y, finalZ + Z + plotWorld.ROAD_OFFSET_Z,
|
||||||
minY + y, finalZ + Z + plotWorld.ROAD_OFFSET_Z,
|
|
||||||
WEExtent.AIRBASE);
|
WEExtent.AIRBASE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BiomeType biome = plotWorld.G_SCH_B.get(MathMan.pair(absX, absZ));
|
BiomeType biome = plotWorld.G_SCH_B.get(MathMan.pair(absX, absZ));
|
||||||
if (biome != null) {
|
if (biome != null) {
|
||||||
queue.setBiome(finalX + X + plotWorld.ROAD_OFFSET_X,
|
queue.setBiome(finalX + X + plotWorld.ROAD_OFFSET_X, finalZ + Z + plotWorld.ROAD_OFFSET_Z, biome);
|
||||||
finalZ + Z + plotWorld.ROAD_OFFSET_Z, biome);
|
|
||||||
} else {
|
} else {
|
||||||
queue.setBiome(finalX + X + plotWorld.ROAD_OFFSET_X,
|
queue.setBiome(finalX + X + plotWorld.ROAD_OFFSET_X, finalZ + Z + plotWorld.ROAD_OFFSET_Z, plotWorld.getPlotBiome());
|
||||||
finalZ + Z + plotWorld.ROAD_OFFSET_Z, plotWorld.getPlotBiome());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ import com.plotsquared.core.PlotSquared;
|
|||||||
import com.plotsquared.core.plot.PlotArea;
|
import com.plotsquared.core.plot.PlotArea;
|
||||||
import com.plotsquared.core.plot.PlotId;
|
import com.plotsquared.core.plot.PlotId;
|
||||||
import com.plotsquared.core.plot.SetupObject;
|
import com.plotsquared.core.plot.SetupObject;
|
||||||
import com.plotsquared.core.queue.ScopedLocalBlockQueue;
|
import com.plotsquared.core.queue.ScopedQueueCoordinator;
|
||||||
import com.plotsquared.core.setup.PlotAreaBuilder;
|
import com.plotsquared.core.setup.PlotAreaBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -52,9 +52,9 @@ public abstract class IndependentPlotGenerator {
|
|||||||
* @param result
|
* @param result
|
||||||
* @param settings
|
* @param settings
|
||||||
*/
|
*/
|
||||||
public abstract void generateChunk(ScopedLocalBlockQueue result, PlotArea settings);
|
public abstract void generateChunk(ScopedQueueCoordinator result, PlotArea settings);
|
||||||
|
|
||||||
public boolean populateChunk(ScopedLocalBlockQueue result, PlotArea setting) {
|
public boolean populateChunk(ScopedQueueCoordinator result, PlotArea setting) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,8 +75,7 @@ public abstract class IndependentPlotGenerator {
|
|||||||
*
|
*
|
||||||
* @param setup
|
* @param setup
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated public void processSetup(SetupObject setup) {
|
||||||
public void processSetup(SetupObject setup) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -85,7 +84,8 @@ public abstract class IndependentPlotGenerator {
|
|||||||
*
|
*
|
||||||
* @param builder the area builder to modify
|
* @param builder the area builder to modify
|
||||||
*/
|
*/
|
||||||
public void processAreaSetup(PlotAreaBuilder builder) { }
|
public void processAreaSetup(PlotAreaBuilder builder) {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* It is preferred for the PlotArea object to do most of the initialization necessary.
|
* It is preferred for the PlotArea object to do most of the initialization necessary.
|
||||||
|
@ -32,7 +32,7 @@ import com.plotsquared.core.plot.PlotId;
|
|||||||
import com.plotsquared.core.plot.world.PlotAreaManager;
|
import com.plotsquared.core.plot.world.PlotAreaManager;
|
||||||
import com.plotsquared.core.plot.world.SinglePlotArea;
|
import com.plotsquared.core.plot.world.SinglePlotArea;
|
||||||
import com.plotsquared.core.plot.world.SinglePlotAreaManager;
|
import com.plotsquared.core.plot.world.SinglePlotAreaManager;
|
||||||
import com.plotsquared.core.queue.ScopedLocalBlockQueue;
|
import com.plotsquared.core.queue.ScopedQueueCoordinator;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeTypes;
|
import com.sk89q.worldedit.world.biome.BiomeTypes;
|
||||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ public class SingleWorldGenerator extends IndependentPlotGenerator {
|
|||||||
return "PlotSquared:single";
|
return "PlotSquared:single";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void generateChunk(ScopedLocalBlockQueue result, PlotArea settings) {
|
@Override public void generateChunk(ScopedQueueCoordinator result, PlotArea settings) {
|
||||||
SinglePlotArea area = (SinglePlotArea) settings;
|
SinglePlotArea area = (SinglePlotArea) settings;
|
||||||
if (area.VOID) {
|
if (area.VOID) {
|
||||||
Location min = result.getMin();
|
Location min = result.getMin();
|
||||||
|
@ -30,13 +30,16 @@ import com.plotsquared.core.location.Location;
|
|||||||
import com.plotsquared.core.plot.Plot;
|
import com.plotsquared.core.plot.Plot;
|
||||||
import com.plotsquared.core.plot.PlotArea;
|
import com.plotsquared.core.plot.PlotArea;
|
||||||
import com.plotsquared.core.plot.PlotId;
|
import com.plotsquared.core.plot.PlotId;
|
||||||
|
import com.plotsquared.core.queue.QueueCoordinator;
|
||||||
import com.plotsquared.core.util.HashUtil;
|
import com.plotsquared.core.util.HashUtil;
|
||||||
import com.plotsquared.core.util.RegionManager;
|
import com.plotsquared.core.util.RegionManager;
|
||||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@ -56,12 +59,14 @@ public abstract class SquarePlotManager extends GridPlotManager {
|
|||||||
this.regionManager = regionManager;
|
this.regionManager = regionManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean clearPlot(final Plot plot, final Runnable whenDone) {
|
@Override public boolean clearPlot(final @NotNull Plot plot, final @Nullable Runnable whenDone, @Nullable QueueCoordinator queue) {
|
||||||
final Set<CuboidRegion> regions = plot.getRegions();
|
final Set<CuboidRegion> regions = plot.getRegions();
|
||||||
Runnable run = new Runnable() {
|
Runnable run = new Runnable() {
|
||||||
@Override public void run() {
|
@Override public void run() {
|
||||||
if (regions.isEmpty()) {
|
if (regions.isEmpty()) {
|
||||||
|
if (whenDone != null) {
|
||||||
whenDone.run();
|
whenDone.run();
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Iterator<CuboidRegion> iterator = regions.iterator();
|
Iterator<CuboidRegion> iterator = regions.iterator();
|
||||||
@ -76,13 +81,13 @@ public abstract class SquarePlotManager extends GridPlotManager {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public Location getPlotTopLocAbs(PlotId plotId) {
|
@Override public Location getPlotTopLocAbs(@NotNull PlotId plotId) {
|
||||||
int px = plotId.getX();
|
int px = plotId.getX();
|
||||||
int pz = plotId.getY();
|
int pz = plotId.getY();
|
||||||
int x = (squarePlotWorld.ROAD_OFFSET_X + (px * (squarePlotWorld.ROAD_WIDTH
|
int x = (squarePlotWorld.ROAD_OFFSET_X + (px * (squarePlotWorld.ROAD_WIDTH + squarePlotWorld.PLOT_WIDTH))) - (int) Math
|
||||||
+ squarePlotWorld.PLOT_WIDTH))) - (int) Math.floor(squarePlotWorld.ROAD_WIDTH / 2) - 1;
|
.floor(squarePlotWorld.ROAD_WIDTH / 2) - 1;
|
||||||
int z = (squarePlotWorld.ROAD_OFFSET_Z + (pz * (squarePlotWorld.ROAD_WIDTH
|
int z = (squarePlotWorld.ROAD_OFFSET_Z + (pz * (squarePlotWorld.ROAD_WIDTH + squarePlotWorld.PLOT_WIDTH))) - (int) Math
|
||||||
+ squarePlotWorld.PLOT_WIDTH))) - (int) Math.floor(squarePlotWorld.ROAD_WIDTH / 2) - 1;
|
.floor(squarePlotWorld.ROAD_WIDTH / 2) - 1;
|
||||||
return Location.at(squarePlotWorld.getWorldName(), x, Math.min(getWorldHeight(), 255), z);
|
return Location.at(squarePlotWorld.getWorldName(), x, Math.min(getWorldHeight(), 255), z);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +135,7 @@ public abstract class SquarePlotManager extends GridPlotManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public PlotId getNearestPlotId(PlotArea plotArea, int x, int y, int z) {
|
public PlotId getNearestPlotId(@Nonnull PlotArea plotArea, int x, int y, int z) {
|
||||||
SquarePlotWorld dpw = (SquarePlotWorld) plotArea;
|
SquarePlotWorld dpw = (SquarePlotWorld) plotArea;
|
||||||
if (dpw.ROAD_OFFSET_X != 0) {
|
if (dpw.ROAD_OFFSET_X != 0) {
|
||||||
x -= dpw.ROAD_OFFSET_X;
|
x -= dpw.ROAD_OFFSET_X;
|
||||||
@ -191,8 +196,7 @@ public abstract class SquarePlotManager extends GridPlotManager {
|
|||||||
rz = z % size;
|
rz = z % size;
|
||||||
}
|
}
|
||||||
PlotId id = PlotId.of(dx, dz);
|
PlotId id = PlotId.of(dx, dz);
|
||||||
boolean[] merged =
|
boolean[] merged = new boolean[] {rz <= pathWidthLower, rx > end, rz > end, rx <= pathWidthLower};
|
||||||
new boolean[] {rz <= pathWidthLower, rx > end, rz > end, rx <= pathWidthLower};
|
|
||||||
int hash = HashUtil.hash(merged);
|
int hash = HashUtil.hash(merged);
|
||||||
// Not merged, and no need to check if it is
|
// Not merged, and no need to check if it is
|
||||||
if (hash == 0) {
|
if (hash == 0) {
|
||||||
@ -230,8 +234,7 @@ public abstract class SquarePlotManager extends GridPlotManager {
|
|||||||
return plot.getMerged(Direction.NORTHWEST) ? id : null;
|
return plot.getMerged(Direction.NORTHWEST) ? id : null;
|
||||||
}
|
}
|
||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {
|
||||||
logger.error( "Invalid plot / road width in settings.yml for world: {}", squarePlotWorld
|
logger.error("Invalid plot / road width in settings.yml for world: {}", squarePlotWorld.getWorldName());
|
||||||
.getWorldName());
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -239,15 +242,13 @@ public abstract class SquarePlotManager extends GridPlotManager {
|
|||||||
/**
|
/**
|
||||||
* Get the bottom plot loc (some basic math).
|
* Get the bottom plot loc (some basic math).
|
||||||
*/
|
*/
|
||||||
@Override public Location getPlotBottomLocAbs(PlotId plotId) {
|
@Override public Location getPlotBottomLocAbs(@NotNull PlotId plotId) {
|
||||||
int px = plotId.getX();
|
int px = plotId.getX();
|
||||||
int pz = plotId.getY();
|
int pz = plotId.getY();
|
||||||
int x = (squarePlotWorld.ROAD_OFFSET_X + (px * (squarePlotWorld.ROAD_WIDTH
|
int x = (squarePlotWorld.ROAD_OFFSET_X + (px * (squarePlotWorld.ROAD_WIDTH + squarePlotWorld.PLOT_WIDTH))) - squarePlotWorld.PLOT_WIDTH
|
||||||
+ squarePlotWorld.PLOT_WIDTH))) - squarePlotWorld.PLOT_WIDTH - (int) Math
|
- (int) Math.floor(squarePlotWorld.ROAD_WIDTH / 2);
|
||||||
.floor(squarePlotWorld.ROAD_WIDTH / 2);
|
int z = (squarePlotWorld.ROAD_OFFSET_Z + (pz * (squarePlotWorld.ROAD_WIDTH + squarePlotWorld.PLOT_WIDTH))) - squarePlotWorld.PLOT_WIDTH
|
||||||
int z = (squarePlotWorld.ROAD_OFFSET_Z + (pz * (squarePlotWorld.ROAD_WIDTH
|
- (int) Math.floor(squarePlotWorld.ROAD_WIDTH / 2);
|
||||||
+ squarePlotWorld.PLOT_WIDTH))) - squarePlotWorld.PLOT_WIDTH - (int) Math
|
|
||||||
.floor(squarePlotWorld.ROAD_WIDTH / 2);
|
|
||||||
return Location.at(squarePlotWorld.getWorldName(), x, squarePlotWorld.getMinBuildHeight(), z);
|
return Location.at(squarePlotWorld.getWorldName(), x, squarePlotWorld.getMinBuildHeight(), z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,28 +23,17 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.plotsquared.core.queue;
|
package com.plotsquared.core.inject.factory;
|
||||||
|
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
import com.google.inject.Inject;
|
||||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
import com.google.inject.assistedinject.Assisted;
|
||||||
|
import com.plotsquared.core.queue.ChunkCoordinatorBuilder;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public class OffsetLocalBlockQueue extends DelegateLocalBlockQueue {
|
import javax.annotation.Nonnull;
|
||||||
private final int ox;
|
|
||||||
private final int oy;
|
|
||||||
private final int oz;
|
|
||||||
|
|
||||||
public OffsetLocalBlockQueue(LocalBlockQueue parent, int ox, int oy, int oz) {
|
public interface ChunkCoordinatorBuilderFactory {
|
||||||
super(parent);
|
|
||||||
this.ox = ox;
|
|
||||||
this.oy = oy;
|
|
||||||
this.oz = oz;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public boolean setBiome(int x, int y, BiomeType biome) {
|
@Inject @Nonnull ChunkCoordinatorBuilder create(@Assisted @NotNull ChunkCoordinatorFactory chunkCoordinatorFactory);
|
||||||
return super.setBiome(ox + x, oy + y, biome);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public boolean setBlock(int x, int y, int z, BaseBlock id) {
|
|
||||||
return super.setBlock(ox + x, oy + y, oz + z, id);
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* _____ _ _ _____ _
|
||||||
|
* | __ \| | | | / ____| | |
|
||||||
|
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
||||||
|
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
||||||
|
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
||||||
|
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
||||||
|
* | |
|
||||||
|
* |_|
|
||||||
|
* PlotSquared plot management system for Minecraft
|
||||||
|
* Copyright (C) 2020 IntellectualSites
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.plotsquared.core.inject.factory;
|
||||||
|
|
||||||
|
import com.plotsquared.core.queue.ChunkCoordinator;
|
||||||
|
import com.sk89q.worldedit.math.BlockVector2;
|
||||||
|
import com.sk89q.worldedit.world.World;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
public interface ChunkCoordinatorFactory {
|
||||||
|
|
||||||
|
@Nonnull ChunkCoordinator create(final long maxIterationTime,
|
||||||
|
final int initialBatchSize,
|
||||||
|
@Nonnull final Consumer<BlockVector2> chunkConsumer,
|
||||||
|
@Nonnull final World world,
|
||||||
|
@Nonnull final Collection<BlockVector2> requestedChunks,
|
||||||
|
@Nonnull final Runnable whenDone,
|
||||||
|
@Nonnull final Consumer<Throwable> throwableConsumer,
|
||||||
|
final boolean unloadAfter);
|
||||||
|
|
||||||
|
}
|
@ -8,7 +8,7 @@
|
|||||||
* | |
|
* | |
|
||||||
* |_|
|
* |_|
|
||||||
* PlotSquared plot management system for Minecraft
|
* PlotSquared plot management system for Minecraft
|
||||||
* Copyright (C) ${year} IntellectualSites
|
* Copyright (C) 2020 IntellectualSites
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -139,10 +139,6 @@ public class ConsolePlayer extends PlotPlayer<Actor> {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean isPermissionSet(@Nonnull String permission) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public void sendMessage(@Nonnull final Caption caption,
|
@Override public void sendMessage(@Nonnull final Caption caption,
|
||||||
@Nonnull final Template... replacements) {
|
@Nonnull final Template... replacements) {
|
||||||
String message = caption.getComponent(this);
|
String message = caption.getComponent(this);
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -27,6 +27,7 @@ package com.plotsquared.core.plot;
|
|||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.plotsquared.core.PlotSquared;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.plotsquared.core.collection.QuadMap;
|
import com.plotsquared.core.collection.QuadMap;
|
||||||
import com.plotsquared.core.configuration.ConfigurationNode;
|
import com.plotsquared.core.configuration.ConfigurationNode;
|
||||||
@ -55,7 +56,7 @@ import com.plotsquared.core.plot.flag.PlotFlag;
|
|||||||
import com.plotsquared.core.plot.flag.implementations.DoneFlag;
|
import com.plotsquared.core.plot.flag.implementations.DoneFlag;
|
||||||
import com.plotsquared.core.plot.flag.types.DoubleFlag;
|
import com.plotsquared.core.plot.flag.types.DoubleFlag;
|
||||||
import com.plotsquared.core.queue.GlobalBlockQueue;
|
import com.plotsquared.core.queue.GlobalBlockQueue;
|
||||||
import com.plotsquared.core.queue.LocalBlockQueue;
|
import com.plotsquared.core.queue.QueueCoordinator;
|
||||||
import com.plotsquared.core.util.EconHandler;
|
import com.plotsquared.core.util.EconHandler;
|
||||||
import com.plotsquared.core.util.Expression;
|
import com.plotsquared.core.util.Expression;
|
||||||
import com.plotsquared.core.util.MathMan;
|
import com.plotsquared.core.util.MathMan;
|
||||||
@ -183,8 +184,8 @@ public abstract class PlotArea {
|
|||||||
|
|
||||||
@Nonnull protected abstract PlotManager createManager();
|
@Nonnull protected abstract PlotManager createManager();
|
||||||
|
|
||||||
public LocalBlockQueue getQueue(final boolean autoQueue) {
|
public QueueCoordinator getQueue() {
|
||||||
return this.globalBlockQueue.getNewQueue(worldName, autoQueue);
|
return this.globalBlockQueue.getNewQueue(PlotSquared.platform().getWorldUtil().getWeWorld(worldName));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -947,7 +948,8 @@ public abstract class PlotArea {
|
|||||||
final PlotId pos2 = plotIds.get(plotIds.size() - 1);
|
final PlotId pos2 = plotIds.get(plotIds.size() - 1);
|
||||||
final PlotManager manager = getPlotManager();
|
final PlotManager manager = getPlotManager();
|
||||||
|
|
||||||
manager.startPlotMerge(plotIds);
|
QueueCoordinator queue = getQueue();
|
||||||
|
manager.startPlotMerge(plotIds, queue);
|
||||||
final Set<UUID> trusted = new HashSet<>();
|
final Set<UUID> trusted = new HashSet<>();
|
||||||
final Set<UUID> members = new HashSet<>();
|
final Set<UUID> members = new HashSet<>();
|
||||||
final Set<UUID> denied = new HashSet<>();
|
final Set<UUID> denied = new HashSet<>();
|
||||||
@ -982,24 +984,25 @@ public abstract class PlotArea {
|
|||||||
if (ly) {
|
if (ly) {
|
||||||
if (!plot.getMerged(Direction.EAST) || !plot.getMerged(Direction.SOUTH)) {
|
if (!plot.getMerged(Direction.EAST) || !plot.getMerged(Direction.SOUTH)) {
|
||||||
if (removeRoads) {
|
if (removeRoads) {
|
||||||
plot.removeRoadSouthEast();
|
plot.removeRoadSouthEast(queue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!plot.getMerged(Direction.EAST)) {
|
if (!plot.getMerged(Direction.EAST)) {
|
||||||
plot2 = plot.getRelative(1, 0);
|
plot2 = plot.getRelative(1, 0);
|
||||||
plot.mergePlot(plot2, removeRoads);
|
plot.mergePlot(plot2, removeRoads, queue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ly) {
|
if (ly) {
|
||||||
if (!plot.getMerged(Direction.SOUTH)) {
|
if (!plot.getMerged(Direction.SOUTH)) {
|
||||||
plot2 = plot.getRelative(0, 1);
|
plot2 = plot.getRelative(0, 1);
|
||||||
plot.mergePlot(plot2, removeRoads);
|
plot.mergePlot(plot2, removeRoads, queue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
manager.finishPlotMerge(plotIds);
|
manager.finishPlotMerge(plotIds, queue);
|
||||||
|
queue.enqueue();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ public class PlotItemStack {
|
|||||||
* @param amount Amount of items in the stack
|
* @param amount Amount of items in the stack
|
||||||
* @param name The display name of the item stack
|
* @param name The display name of the item stack
|
||||||
* @param lore The item stack lore
|
* @param lore The item stack lore
|
||||||
* @deprecated Use {@link PlotItemStack(String, int, String, String...)}
|
* @deprecated Use {@link #PlotItemStack(String, int, String, String...)}
|
||||||
*/
|
*/
|
||||||
@Deprecated public PlotItemStack(final int id, final short data, final int amount,
|
@Deprecated public PlotItemStack(final int id, final short data, final int amount,
|
||||||
final String name, final String... lore) {
|
final String name, final String... lore) {
|
||||||
|
@ -28,9 +28,12 @@ package com.plotsquared.core.plot;
|
|||||||
import com.plotsquared.core.command.Template;
|
import com.plotsquared.core.command.Template;
|
||||||
import com.plotsquared.core.configuration.Settings;
|
import com.plotsquared.core.configuration.Settings;
|
||||||
import com.plotsquared.core.location.Location;
|
import com.plotsquared.core.location.Location;
|
||||||
|
import com.plotsquared.core.queue.QueueCoordinator;
|
||||||
import com.plotsquared.core.util.FileBytes;
|
import com.plotsquared.core.util.FileBytes;
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@ -40,7 +43,7 @@ public abstract class PlotManager {
|
|||||||
|
|
||||||
private final PlotArea plotArea;
|
private final PlotArea plotArea;
|
||||||
|
|
||||||
public PlotManager(PlotArea plotArea) {
|
public PlotManager(@Nonnull PlotArea plotArea) {
|
||||||
this.plotArea = plotArea;
|
this.plotArea = plotArea;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,19 +56,22 @@ public abstract class PlotManager {
|
|||||||
public abstract PlotId getPlotId(int x, int y, int z);
|
public abstract PlotId getPlotId(int x, int y, int z);
|
||||||
|
|
||||||
// If you have a circular plot, just return the corner if it were a square
|
// If you have a circular plot, just return the corner if it were a square
|
||||||
public abstract Location getPlotBottomLocAbs(PlotId plotId);
|
public abstract Location getPlotBottomLocAbs(@Nonnull PlotId plotId);
|
||||||
|
|
||||||
// the same applies here
|
// the same applies here
|
||||||
public abstract Location getPlotTopLocAbs(PlotId plotId);
|
public abstract Location getPlotTopLocAbs(@Nonnull PlotId plotId);
|
||||||
|
|
||||||
/*
|
public abstract boolean clearPlot(@Nonnull Plot plot, @Nullable Runnable whenDone, @Nullable QueueCoordinator queue);
|
||||||
* Plot clearing (return false if you do not support some method)
|
|
||||||
|
public abstract boolean claimPlot(@Nonnull Plot plot, @Nullable QueueCoordinator queue);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Completes block changes associated with plot unclaim.
|
||||||
|
*
|
||||||
|
* @param queue Nullable {@link QueueCoordinator}. If null, creates own queue and enqueues,
|
||||||
|
* otherwise writes to the queue but does not enqueue.
|
||||||
*/
|
*/
|
||||||
public abstract boolean clearPlot(Plot plot, Runnable whenDone);
|
public abstract boolean unClaimPlot(@Nonnull Plot plot, @Nullable Runnable whenDone, @Nullable QueueCoordinator queue);
|
||||||
|
|
||||||
public abstract boolean claimPlot(Plot plot);
|
|
||||||
|
|
||||||
public abstract boolean unClaimPlot(Plot plot, Runnable whenDone);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the location of where a sign should be for a plot.
|
* Retrieves the location of where a sign should be for a plot.
|
||||||
@ -73,44 +79,98 @@ public abstract class PlotManager {
|
|||||||
* @param plot The plot
|
* @param plot The plot
|
||||||
* @return The location where a sign should be
|
* @return The location where a sign should be
|
||||||
*/
|
*/
|
||||||
public abstract Location getSignLoc(Plot plot);
|
public abstract Location getSignLoc(@Nonnull Plot plot);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Plot set functions (return false if you do not support the specific set
|
* Plot set functions (return false if you do not support the specific set
|
||||||
* method).
|
* method).
|
||||||
*/
|
*/
|
||||||
public abstract String[] getPlotComponents(PlotId plotId);
|
public abstract String[] getPlotComponents(@Nonnull PlotId plotId);
|
||||||
|
|
||||||
public abstract boolean setComponent(PlotId plotId, String component, Pattern blocks);
|
/**
|
||||||
|
* Set the specified components to the specified Pattern on the specified plot.
|
||||||
/*
|
*
|
||||||
* PLOT MERGING (return false if your generator does not support plot
|
* @param component FLOOR, WALL, AIR, MAIN, MIDDLE, OUTLINE, BORDER, ALL (floor, air and main).
|
||||||
* merging).
|
* @param queue Nullable {@link QueueCoordinator}. If null, creates own queue and enqueues,
|
||||||
|
* otherwise writes to the queue but does not enqueue.
|
||||||
*/
|
*/
|
||||||
public abstract boolean createRoadEast(Plot plot);
|
public abstract boolean setComponent(@Nonnull PlotId plotId,
|
||||||
|
@Nonnull String component,
|
||||||
|
@Nonnull Pattern blocks,
|
||||||
|
@Nullable QueueCoordinator queue);
|
||||||
|
|
||||||
public abstract boolean createRoadSouth(Plot plot);
|
/**
|
||||||
|
* Create the road east of the plot (not schematic-based)
|
||||||
|
*
|
||||||
|
* @param queue Nullable {@link QueueCoordinator}. If null, creates own queue and enqueues,
|
||||||
|
* otherwise writes to the queue but does not enqueue.
|
||||||
|
*/
|
||||||
|
public abstract boolean createRoadEast(@Nonnull Plot plot, @Nullable QueueCoordinator queue);
|
||||||
|
|
||||||
public abstract boolean createRoadSouthEast(Plot plot);
|
/**
|
||||||
|
* Create the road south of the plot (not schematic-based)
|
||||||
|
*
|
||||||
|
* @param queue Nullable {@link QueueCoordinator}. If null, creates own queue and enqueues,
|
||||||
|
* otherwise writes to the queue but does not enqueue.
|
||||||
|
*/
|
||||||
|
public abstract boolean createRoadSouth(@Nonnull Plot plot, @Nullable QueueCoordinator queue);
|
||||||
|
|
||||||
public abstract boolean removeRoadEast(Plot plot);
|
/**
|
||||||
|
* Create the south-east corner of the road (intersection, not schematic-based)
|
||||||
|
*
|
||||||
|
* @param queue Nullable {@link QueueCoordinator}. If null, creates own queue and enqueues,
|
||||||
|
* otherwise writes to the queue but does not enqueue.
|
||||||
|
*/
|
||||||
|
public abstract boolean createRoadSouthEast(@Nonnull Plot plot, @Nullable QueueCoordinator queue);
|
||||||
|
|
||||||
public abstract boolean removeRoadSouth(Plot plot);
|
/**
|
||||||
|
* Replace the road to the east of the plot with standard plot blocks (for when merging plots)
|
||||||
|
*
|
||||||
|
* @param queue Nullable {@link QueueCoordinator}. If null, creates own queue and enqueues,
|
||||||
|
* otherwise writes to the queue but does not enqueue.
|
||||||
|
*/
|
||||||
|
public abstract boolean removeRoadEast(@Nonnull Plot plot, @Nullable QueueCoordinator queue);
|
||||||
|
|
||||||
public abstract boolean removeRoadSouthEast(Plot plot);
|
/**
|
||||||
|
* Replace the road to the south of the plot with standard plot blocks (for when merging plots)
|
||||||
|
*
|
||||||
|
* @param queue Nullable {@link QueueCoordinator}. If null, creates own queue and enqueues,
|
||||||
|
* otherwise writes to the queue but does not enqueue.
|
||||||
|
*/
|
||||||
|
public abstract boolean removeRoadSouth(@Nonnull Plot plot, @Nullable QueueCoordinator queue);
|
||||||
|
|
||||||
public abstract boolean startPlotMerge(List<PlotId> plotIds);
|
/**
|
||||||
|
* Replace the road to the south east of the plot (intersection) with standard plot blocks (for when merging plots)
|
||||||
|
*
|
||||||
|
* @param queue Nullable {@link QueueCoordinator}. If null, creates own queue and enqueues,
|
||||||
|
* otherwise writes to the queue but does not enqueue.
|
||||||
|
*/
|
||||||
|
public abstract boolean removeRoadSouthEast(@Nonnull Plot plot, @Nullable QueueCoordinator queue);
|
||||||
|
|
||||||
public abstract boolean startPlotUnlink(List<PlotId> plotIds);
|
public abstract boolean startPlotMerge(@Nonnull List<PlotId> plotIds, @Nullable QueueCoordinator queue);
|
||||||
|
|
||||||
public abstract boolean finishPlotMerge(List<PlotId> plotIds);
|
public abstract boolean startPlotUnlink(@Nonnull List<PlotId> plotIds, @Nullable QueueCoordinator queue);
|
||||||
|
|
||||||
public abstract boolean finishPlotUnlink(List<PlotId> plotIds);
|
/**
|
||||||
|
* Finishing off plot merging by adding in the walls surrounding the plot (OPTIONAL)(UNFINISHED).
|
||||||
|
*
|
||||||
|
* @param queue Nullable {@link QueueCoordinator}. If null, creates own queue and enqueues,
|
||||||
|
* otherwise writes to the queue but does not enqueue.
|
||||||
|
* @return false if part if the merge failed, otherwise true if successful.
|
||||||
|
*/
|
||||||
|
public abstract boolean finishPlotMerge(@Nonnull List<PlotId> plotIds, @Nullable QueueCoordinator queue);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finished off an unlink by resetting the top wall block for unlinked plots
|
||||||
|
*
|
||||||
|
* @param queue Nullable {@link QueueCoordinator}. If null, creates own queue and enqueues,
|
||||||
|
* otherwise writes to the queue but does not enqueue.
|
||||||
|
*/
|
||||||
|
public abstract boolean finishPlotUnlink(@Nonnull List<PlotId> plotIds, @Nullable QueueCoordinator queue);
|
||||||
|
|
||||||
public void exportTemplate() throws IOException {
|
public void exportTemplate() throws IOException {
|
||||||
HashSet<FileBytes> files = new HashSet<>(Collections.singletonList(
|
HashSet<FileBytes> files =
|
||||||
new FileBytes(Settings.Paths.TEMPLATES + "/tmp-data.yml",
|
new HashSet<>(Collections.singletonList(new FileBytes(Settings.Paths.TEMPLATES + "/tmp-data.yml", Template.getBytes(plotArea))));
|
||||||
Template.getBytes(plotArea))));
|
|
||||||
Template.zipAll(plotArea.getWorldName(), files);
|
Template.zipAll(plotArea.getWorldName(), files);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,15 +181,17 @@ public abstract class PlotManager {
|
|||||||
/**
|
/**
|
||||||
* Sets all the blocks along all the plot walls to their correct state (claimed or unclaimed).
|
* Sets all the blocks along all the plot walls to their correct state (claimed or unclaimed).
|
||||||
*
|
*
|
||||||
|
* @param queue Nullable {@link QueueCoordinator}. If null, creates own queue and enqueues,
|
||||||
|
* otherwise writes to the queue but does not enqueue.
|
||||||
* @return true if the wall blocks were successfully set
|
* @return true if the wall blocks were successfully set
|
||||||
*/
|
*/
|
||||||
public boolean regenerateAllPlotWalls() {
|
public boolean regenerateAllPlotWalls(@Nullable QueueCoordinator queue) {
|
||||||
boolean success = true;
|
boolean success = true;
|
||||||
for (Plot plot : plotArea.getPlots()) {
|
for (Plot plot : plotArea.getPlots()) {
|
||||||
if (plot.hasOwner()) {
|
if (plot.hasOwner()) {
|
||||||
success &= claimPlot(plot);
|
success &= claimPlot(plot, queue);
|
||||||
} else {
|
} else {
|
||||||
success &= unClaimPlot(plot, null);
|
success &= unClaimPlot(plot, null, queue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return success;
|
return success;
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.plotsquared.core.plot.flag;
|
package com.plotsquared.core.plot.flag;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
import com.plotsquared.core.plot.flag.implementations.AnalysisFlag;
|
import com.plotsquared.core.plot.flag.implementations.AnalysisFlag;
|
||||||
import com.plotsquared.core.plot.flag.implementations.AnimalAttackFlag;
|
import com.plotsquared.core.plot.flag.implementations.AnimalAttackFlag;
|
||||||
import com.plotsquared.core.plot.flag.implementations.AnimalCapFlag;
|
import com.plotsquared.core.plot.flag.implementations.AnimalCapFlag;
|
||||||
@ -113,7 +114,13 @@ import java.util.Map;
|
|||||||
|
|
||||||
public final class GlobalFlagContainer extends FlagContainer {
|
public final class GlobalFlagContainer extends FlagContainer {
|
||||||
|
|
||||||
private static final GlobalFlagContainer instance = new GlobalFlagContainer();
|
private static GlobalFlagContainer instance;
|
||||||
|
|
||||||
|
public static void setup() {
|
||||||
|
Preconditions.checkState(instance == null, "Cannot setup the container twice");
|
||||||
|
instance = new GlobalFlagContainer();
|
||||||
|
}
|
||||||
|
|
||||||
private static Map<String, Class<?>> stringClassMap;
|
private static Map<String, Class<?>> stringClassMap;
|
||||||
|
|
||||||
private GlobalFlagContainer() {
|
private GlobalFlagContainer() {
|
||||||
@ -123,6 +130,7 @@ public final class GlobalFlagContainer extends FlagContainer {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
stringClassMap = new HashMap<>();
|
stringClassMap = new HashMap<>();
|
||||||
|
|
||||||
// Register all default flags here
|
// Register all default flags here
|
||||||
// Boolean flags
|
// Boolean flags
|
||||||
this.addFlag(ExplosionFlag.EXPLOSION_FALSE);
|
this.addFlag(ExplosionFlag.EXPLOSION_FALSE);
|
||||||
|
@ -144,8 +144,7 @@ public abstract class PlotFlag<T, F extends PlotFlag<T, F>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the category this flag belongs to. Usually a caption from
|
* Get the category this flag belongs to. Usually a caption from {@link com.plotsquared.core.configuration.caption.TranslatableCaption}
|
||||||
* {@link Captions}
|
|
||||||
* <p>
|
* <p>
|
||||||
* These categories are used to categorize the flags when outputting
|
* These categories are used to categorize the flags when outputting
|
||||||
* flag lists to players.
|
* flag lists to players.
|
||||||
|
@ -31,11 +31,14 @@ import com.plotsquared.core.plot.Plot;
|
|||||||
import com.plotsquared.core.plot.PlotArea;
|
import com.plotsquared.core.plot.PlotArea;
|
||||||
import com.plotsquared.core.plot.PlotId;
|
import com.plotsquared.core.plot.PlotId;
|
||||||
import com.plotsquared.core.plot.PlotManager;
|
import com.plotsquared.core.plot.PlotManager;
|
||||||
|
import com.plotsquared.core.queue.QueueCoordinator;
|
||||||
import com.plotsquared.core.util.FileUtils;
|
import com.plotsquared.core.util.FileUtils;
|
||||||
import com.plotsquared.core.util.task.TaskManager;
|
import com.plotsquared.core.util.task.TaskManager;
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -53,15 +56,15 @@ public class SinglePlotManager extends PlotManager {
|
|||||||
return PlotId.of(0, 0);
|
return PlotId.of(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public Location getPlotBottomLocAbs(@Nonnull final PlotId plotId) {
|
@Override public Location getPlotBottomLocAbs(@Nonnull final @NotNull PlotId plotId) {
|
||||||
return Location.at(plotId.toCommaSeparatedString(), -30000000, 0, -30000000);
|
return Location.at(plotId.toCommaSeparatedString(), -30000000, 0, -30000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public Location getPlotTopLocAbs(@Nonnull final PlotId plotId) {
|
@Override public Location getPlotTopLocAbs(@Nonnull final @NotNull PlotId plotId) {
|
||||||
return Location.at(plotId.toCommaSeparatedString(), 30000000, 0, 30000000);
|
return Location.at(plotId.toCommaSeparatedString(), 30000000, 0, 30000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean clearPlot(Plot plot, final Runnable whenDone) {
|
@Override public boolean clearPlot(@NotNull Plot plot, final Runnable whenDone, @Nullable QueueCoordinator queue) {
|
||||||
PlotSquared.platform().getSetupUtils().unload(plot.getWorldName(), false);
|
PlotSquared.platform().getSetupUtils().unload(plot.getWorldName(), false);
|
||||||
final File worldFolder = new File(PlotSquared.platform().getWorldContainer(), plot.getWorldName());
|
final File worldFolder = new File(PlotSquared.platform().getWorldContainer(), plot.getWorldName());
|
||||||
TaskManager.getPlatformImplementation().taskAsync(() -> {
|
TaskManager.getPlatformImplementation().taskAsync(() -> {
|
||||||
@ -73,71 +76,72 @@ public class SinglePlotManager extends PlotManager {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean claimPlot(Plot plot) {
|
@Override public boolean claimPlot(@NotNull Plot plot, @Nullable QueueCoordinator queue) {
|
||||||
// TODO
|
// TODO
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean unClaimPlot(Plot plot, Runnable whenDone) {
|
@Override public boolean unClaimPlot(@NotNull Plot plot, Runnable whenDone, @Nullable QueueCoordinator queue) {
|
||||||
if (whenDone != null) {
|
if (whenDone != null) {
|
||||||
whenDone.run();
|
whenDone.run();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public Location getSignLoc(Plot plot) {
|
@Override public Location getSignLoc(@NotNull Plot plot) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public String[] getPlotComponents(PlotId plotId) {
|
@Override public String[] getPlotComponents(@NotNull PlotId plotId) {
|
||||||
return new String[0];
|
return new String[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean setComponent(PlotId plotId, String component, Pattern blocks) {
|
@Override
|
||||||
|
public boolean setComponent(@NotNull PlotId plotId, @NotNull String component, @NotNull Pattern blocks, @Nullable QueueCoordinator queue) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean createRoadEast(Plot plot) {
|
@Override public boolean createRoadEast(@NotNull Plot plot, @Nullable QueueCoordinator queue) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean createRoadSouth(Plot plot) {
|
@Override public boolean createRoadSouth(@NotNull Plot plot, @Nullable QueueCoordinator queue) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean createRoadSouthEast(Plot plot) {
|
@Override public boolean createRoadSouthEast(@NotNull Plot plot, @Nullable QueueCoordinator queue) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean removeRoadEast(Plot plot) {
|
@Override public boolean removeRoadEast(@NotNull Plot plot, @Nullable QueueCoordinator queue) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean removeRoadSouth(Plot plot) {
|
@Override public boolean removeRoadSouth(@NotNull Plot plot, @Nullable QueueCoordinator queue) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean removeRoadSouthEast(Plot plot) {
|
@Override public boolean removeRoadSouthEast(@NotNull Plot plot, @Nullable QueueCoordinator queue) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean startPlotMerge(List<PlotId> plotIds) {
|
@Override public boolean startPlotMerge(@NotNull List<PlotId> plotIds, @Nullable QueueCoordinator queue) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean startPlotUnlink(List<PlotId> plotIds) {
|
@Override public boolean startPlotUnlink(@NotNull List<PlotId> plotIds, @Nullable QueueCoordinator queue) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean finishPlotMerge(List<PlotId> plotIds) {
|
@Override public boolean finishPlotMerge(@NotNull List<PlotId> plotIds, @Nullable QueueCoordinator queue) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean finishPlotUnlink(List<PlotId> plotIds) {
|
@Override public boolean finishPlotUnlink(@NotNull List<PlotId> plotIds, @Nullable QueueCoordinator queue) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean regenerateAllPlotWalls() {
|
@Override public boolean regenerateAllPlotWalls(@Nullable QueueCoordinator queue) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
package com.plotsquared.core.queue;
|
package com.plotsquared.core.queue;
|
||||||
|
|
||||||
import com.plotsquared.core.plot.PlotArea;
|
import com.plotsquared.core.plot.PlotArea;
|
||||||
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
@ -35,45 +36,64 @@ import javax.annotation.Nonnull;
|
|||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class AreaBoundDelegateLocalBlockQueue extends DelegateLocalBlockQueue {
|
/**
|
||||||
|
* Queue Coordinator that only sets blocks with the specified PlotArea
|
||||||
|
*/
|
||||||
|
public class AreaBoundDelegateQueueCoordinator extends DelegateQueueCoordinator {
|
||||||
|
|
||||||
private final PlotArea area;
|
private final PlotArea area;
|
||||||
|
|
||||||
public AreaBoundDelegateLocalBlockQueue(@Nonnull final PlotArea area,
|
public AreaBoundDelegateQueueCoordinator(@Nonnull final PlotArea area, @Nullable final QueueCoordinator parent) {
|
||||||
@Nullable final LocalBlockQueue parent) {
|
|
||||||
super(parent);
|
super(parent);
|
||||||
this.area = Objects.requireNonNull(area);
|
this.area = Objects.requireNonNull(area);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean setBlock(int x, int y, int z, BlockState id) {
|
/**
|
||||||
|
* Gets the plot area block settings is limited to
|
||||||
|
*/
|
||||||
|
public PlotArea getArea() {
|
||||||
|
return this.area;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean setBlock(int x, int y, int z, @Nonnull BlockState id) {
|
||||||
if (area.contains(x, z)) {
|
if (area.contains(x, z)) {
|
||||||
return super.setBlock(x, y, z, id);
|
return super.setBlock(x, y, z, id);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean setBlock(int x, int y, int z, BaseBlock id) {
|
@Override public boolean setBlock(int x, int y, int z, @Nonnull BaseBlock id) {
|
||||||
if (area.contains(x, z)) {
|
if (area.contains(x, z)) {
|
||||||
return super.setBlock(x, y, z, id);
|
return super.setBlock(x, y, z, id);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean setBlock(int x, int y, int z, Pattern pattern) {
|
@Override public boolean setBlock(int x, int y, int z, @Nonnull Pattern pattern) {
|
||||||
if (area.contains(x, z)) {
|
if (area.contains(x, z)) {
|
||||||
return super.setBlock(x, y, z, pattern);
|
return super.setBlock(x, y, z, pattern);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean setBiome(int x, int z, BiomeType biome) {
|
@Override public boolean setBiome(int x, int z, @Nonnull BiomeType biome) {
|
||||||
if (area.contains(x, z)) {
|
if (area.contains(x, z)) {
|
||||||
return super.setBiome(x, z, biome);
|
return super.setBiome(x, z, biome);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PlotArea getArea() {
|
@Override public boolean setBiome(int x, int y, int z, @Nonnull BiomeType biome) {
|
||||||
return this.area;
|
if (area.contains(x, z)) {
|
||||||
|
return super.setBiome(x, y, z, biome);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean setTile(int x, int y, int z, @Nonnull CompoundTag tag) {
|
||||||
|
if (area.contains(x, z)) {
|
||||||
|
return super.setTile(x, y, z, tag);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,274 +0,0 @@
|
|||||||
/*
|
|
||||||
* _____ _ _ _____ _
|
|
||||||
* | __ \| | | | / ____| | |
|
|
||||||
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
|
||||||
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
|
||||||
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
|
||||||
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
|
||||||
* | |
|
|
||||||
* |_|
|
|
||||||
* PlotSquared plot management system for Minecraft
|
|
||||||
* Copyright (C) 2020 IntellectualSites
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package com.plotsquared.core.queue;
|
|
||||||
|
|
||||||
import com.plotsquared.core.util.ChunkUtil;
|
|
||||||
import com.plotsquared.core.util.MathMan;
|
|
||||||
import com.plotsquared.core.util.PatternUtil;
|
|
||||||
import com.plotsquared.core.util.task.TaskManager;
|
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
|
||||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.ConcurrentLinkedDeque;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
|
|
||||||
public abstract class BasicLocalBlockQueue extends LocalBlockQueue {
|
|
||||||
|
|
||||||
private final String world;
|
|
||||||
private final ConcurrentHashMap<Long, LocalChunk> blockChunks = new ConcurrentHashMap<>();
|
|
||||||
private final ConcurrentLinkedDeque<LocalChunk> chunks = new ConcurrentLinkedDeque<>();
|
|
||||||
private long modified;
|
|
||||||
private LocalChunk lastWrappedChunk;
|
|
||||||
private int lastX = Integer.MIN_VALUE;
|
|
||||||
private int lastZ = Integer.MIN_VALUE;
|
|
||||||
private boolean setbiome = false;
|
|
||||||
|
|
||||||
private GlobalBlockQueue globalBlockQueue;
|
|
||||||
|
|
||||||
public BasicLocalBlockQueue(String world) {
|
|
||||||
super(world);
|
|
||||||
this.world = world;
|
|
||||||
this.modified = System.currentTimeMillis();
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract LocalChunk getLocalChunk(int x, int z);
|
|
||||||
|
|
||||||
@Override public abstract BlockState getBlock(int x, int y, int z);
|
|
||||||
|
|
||||||
public abstract void setComponents(LocalChunk lc)
|
|
||||||
throws ExecutionException, InterruptedException;
|
|
||||||
|
|
||||||
@Override public final String getWorld() {
|
|
||||||
return world;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public final boolean next() {
|
|
||||||
lastX = Integer.MIN_VALUE;
|
|
||||||
lastZ = Integer.MIN_VALUE;
|
|
||||||
try {
|
|
||||||
if (this.blockChunks.size() == 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
synchronized (blockChunks) {
|
|
||||||
LocalChunk chunk = chunks.poll();
|
|
||||||
if (chunk != null) {
|
|
||||||
blockChunks.remove(chunk.longHash());
|
|
||||||
return this.execute(chunk);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Throwable e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final boolean execute(@Nonnull LocalChunk lc)
|
|
||||||
throws ExecutionException, InterruptedException {
|
|
||||||
this.setComponents(lc);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public void startSet(boolean parallel) {
|
|
||||||
// Do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public void endSet(boolean parallel) {
|
|
||||||
// Do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public final int size() {
|
|
||||||
return chunks.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public final long getModified() {
|
|
||||||
return modified;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public final void setModified(long modified) {
|
|
||||||
this.modified = modified;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public boolean setBlock(int x, int y, int z, @Nonnull Pattern pattern) {
|
|
||||||
return setBlock(x, y, z, PatternUtil.apply(pattern, x, y, z));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public boolean setBlock(int x, int y, int z, BaseBlock id) {
|
|
||||||
if ((y > 255) || (y < 0)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
int cx = x >> 4;
|
|
||||||
int cz = z >> 4;
|
|
||||||
if (cx != lastX || cz != lastZ) {
|
|
||||||
lastX = cx;
|
|
||||||
lastZ = cz;
|
|
||||||
long pair = (long) (cx) << 32 | (cz) & 0xFFFFFFFFL;
|
|
||||||
lastWrappedChunk = this.blockChunks.get(pair);
|
|
||||||
if (lastWrappedChunk == null) {
|
|
||||||
lastWrappedChunk = this.getLocalChunk(x >> 4, z >> 4);
|
|
||||||
lastWrappedChunk.setBlock(x & 15, y, z & 15, id);
|
|
||||||
LocalChunk previous = this.blockChunks.put(pair, lastWrappedChunk);
|
|
||||||
if (previous == null) {
|
|
||||||
return chunks.add(lastWrappedChunk);
|
|
||||||
}
|
|
||||||
this.blockChunks.put(pair, previous);
|
|
||||||
lastWrappedChunk = previous;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lastWrappedChunk.setBlock(x & 15, y, z & 15, id);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public boolean setBlock(int x, int y, int z, BlockState id) {
|
|
||||||
// Trying to mix BlockState and BaseBlock leads to all kinds of issues.
|
|
||||||
// Since BaseBlock has more features than BlockState, simply convert
|
|
||||||
// all BlockStates to BaseBlocks
|
|
||||||
return setBlock(x, y, z, id.toBaseBlock());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public final boolean setBiome(int x, int z, BiomeType biomeType) {
|
|
||||||
long pair = (long) (x >> 4) << 32 | (z >> 4) & 0xFFFFFFFFL;
|
|
||||||
LocalChunk result = this.blockChunks.get(pair);
|
|
||||||
if (result == null) {
|
|
||||||
result = this.getLocalChunk(x >> 4, z >> 4);
|
|
||||||
LocalChunk previous = this.blockChunks.put(pair, result);
|
|
||||||
if (previous != null) {
|
|
||||||
this.blockChunks.put(pair, previous);
|
|
||||||
result = previous;
|
|
||||||
} else {
|
|
||||||
chunks.add(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result.setBiome(x & 15, z & 15, biomeType);
|
|
||||||
setbiome = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public final boolean setBiome() {
|
|
||||||
return setbiome;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final void setChunk(LocalChunk chunk) {
|
|
||||||
LocalChunk previous = this.blockChunks.put(chunk.longHash(), chunk);
|
|
||||||
if (previous != null) {
|
|
||||||
chunks.remove(previous);
|
|
||||||
}
|
|
||||||
chunks.add(chunk);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public void flush() {
|
|
||||||
this.globalBlockQueue.dequeue(this);
|
|
||||||
try {
|
|
||||||
TaskManager.getPlatformImplementation().sync(() -> {
|
|
||||||
while (next()) {
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
} catch (final Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public abstract class LocalChunk {
|
|
||||||
public final BasicLocalBlockQueue parent;
|
|
||||||
public final int z;
|
|
||||||
public final int x;
|
|
||||||
|
|
||||||
public BaseBlock[][] baseblocks;
|
|
||||||
public BiomeType[][] biomes;
|
|
||||||
|
|
||||||
public LocalChunk(BasicLocalBlockQueue parent, int x, int z) {
|
|
||||||
this.parent = parent;
|
|
||||||
this.x = x;
|
|
||||||
this.z = z;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the parent queue this chunk belongs to
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public BasicLocalBlockQueue getParent() {
|
|
||||||
return parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getX() {
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getZ() {
|
|
||||||
return z;
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract void setBlock(final int x, final int y, final int z, final BaseBlock block);
|
|
||||||
|
|
||||||
public void setBiome(int x, int z, BiomeType biomeType) {
|
|
||||||
if (this.biomes == null) {
|
|
||||||
this.biomes = new BiomeType[16][];
|
|
||||||
}
|
|
||||||
BiomeType[] index = this.biomes[x];
|
|
||||||
if (index == null) {
|
|
||||||
index = this.biomes[x] = new BiomeType[16];
|
|
||||||
}
|
|
||||||
index[z] = biomeType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long longHash() {
|
|
||||||
return MathMan.pairInt(x, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public int hashCode() {
|
|
||||||
return MathMan.pair((short) x, (short) z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public class BasicLocalChunk extends LocalChunk {
|
|
||||||
|
|
||||||
public BasicLocalChunk(BasicLocalBlockQueue parent, int x, int z) {
|
|
||||||
super(parent, x, z);
|
|
||||||
baseblocks = new BaseBlock[16][];
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public void setBlock(int x, int y, int z, BaseBlock block) {
|
|
||||||
this.setInternal(x, y, z, block);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setInternal(final int x, final int y, final int z, final BaseBlock baseBlock) {
|
|
||||||
final int i = y >> 4;
|
|
||||||
final int j = ChunkUtil.getJ(x, y, z);
|
|
||||||
BaseBlock[] array = baseblocks[i];
|
|
||||||
if (array == null) {
|
|
||||||
array = (baseblocks[i] = new BaseBlock[4096]);
|
|
||||||
}
|
|
||||||
array[j] = baseBlock;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,273 @@
|
|||||||
|
/*
|
||||||
|
* _____ _ _ _____ _
|
||||||
|
* | __ \| | | | / ____| | |
|
||||||
|
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
||||||
|
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
||||||
|
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
||||||
|
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
||||||
|
* | |
|
||||||
|
* |_|
|
||||||
|
* PlotSquared plot management system for Minecraft
|
||||||
|
* Copyright (C) 2020 IntellectualSites
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.plotsquared.core.queue;
|
||||||
|
|
||||||
|
import com.plotsquared.core.util.PatternUtil;
|
||||||
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
|
import com.sk89q.worldedit.entity.Entity;
|
||||||
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
|
import com.sk89q.worldedit.math.BlockVector2;
|
||||||
|
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||||
|
import com.sk89q.worldedit.util.Location;
|
||||||
|
import com.sk89q.worldedit.world.World;
|
||||||
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
|
import com.sk89q.worldedit.world.entity.EntityTypes;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard block setting queue that allows block setting across numerous chunks, without limits.
|
||||||
|
*/
|
||||||
|
public abstract class BasicQueueCoordinator extends QueueCoordinator {
|
||||||
|
|
||||||
|
private final World world;
|
||||||
|
private final ConcurrentHashMap<BlockVector2, LocalChunk> blockChunks = new ConcurrentHashMap<>();
|
||||||
|
private final List<BlockVector2> readRegion = new ArrayList<>();
|
||||||
|
private long modified;
|
||||||
|
private LocalChunk lastWrappedChunk;
|
||||||
|
private int lastX = Integer.MIN_VALUE;
|
||||||
|
private int lastZ = Integer.MIN_VALUE;
|
||||||
|
private boolean settingBiomes = false;
|
||||||
|
private boolean settingTiles = false;
|
||||||
|
private boolean regen = false;
|
||||||
|
private int[] regenStart;
|
||||||
|
private int[] regenEnd;
|
||||||
|
private CuboidRegion regenRegion = null;
|
||||||
|
private Consumer<BlockVector2> consumer = null;
|
||||||
|
private boolean unloadAfter = true;
|
||||||
|
private Runnable whenDone;
|
||||||
|
|
||||||
|
public BasicQueueCoordinator(@Nonnull World world) {
|
||||||
|
super(world);
|
||||||
|
this.world = world;
|
||||||
|
this.modified = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public abstract BlockState getBlock(int x, int y, int z);
|
||||||
|
|
||||||
|
@Override public final @Nonnull World getWorld() {
|
||||||
|
return world;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public final int size() {
|
||||||
|
return blockChunks.size() + readRegion.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public final void setModified(long modified) {
|
||||||
|
this.modified = modified;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean setBlock(int x, int y, int z, @Nonnull Pattern pattern) {
|
||||||
|
return setBlock(x, y, z, PatternUtil.apply(pattern, x, y, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean setBlock(int x, int y, int z, @Nonnull BaseBlock id) {
|
||||||
|
if ((y > 255) || (y < 0)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
LocalChunk chunk = getChunk(x >> 4, z >> 4);
|
||||||
|
chunk.setBlock(x & 15, y, z & 15, id);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean setBlock(int x, int y, int z, @Nonnull BlockState id) {
|
||||||
|
// Trying to mix BlockState and BaseBlock leads to all kinds of issues.
|
||||||
|
// Since BaseBlock has more features than BlockState, simply convert
|
||||||
|
// all BlockStates to BaseBlocks
|
||||||
|
return setBlock(x, y, z, id.toBaseBlock());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean setBiome(int x, int z, @Nonnull BiomeType biomeType) {
|
||||||
|
LocalChunk chunk = getChunk(x >> 4, z >> 4);
|
||||||
|
for (int y = 0; y < 256; y++) {
|
||||||
|
chunk.setBiome(x & 15, y, z & 15, biomeType);
|
||||||
|
}
|
||||||
|
settingBiomes = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public final boolean setBiome(int x, int y, int z, @Nonnull BiomeType biomeType) {
|
||||||
|
LocalChunk chunk = getChunk(x >> 4, z >> 4);
|
||||||
|
chunk.setBiome(x & 15, y, z & 15, biomeType);
|
||||||
|
settingBiomes = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean isSettingBiomes() {
|
||||||
|
return this.settingBiomes;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean setTile(int x, int y, int z, @Nonnull CompoundTag tag) {
|
||||||
|
LocalChunk chunk = getChunk(x >> 4, z >> 4);
|
||||||
|
chunk.setTile(x, y, z, tag);
|
||||||
|
settingTiles = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean isSettingTiles() {
|
||||||
|
return this.settingTiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean setEntity(@Nonnull Entity entity) {
|
||||||
|
if (entity.getState() == null || entity.getState().getType() == EntityTypes.PLAYER) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Location location = entity.getLocation();
|
||||||
|
LocalChunk chunk = getChunk(location.getBlockX() >> 4, location.getBlockZ() >> 4);
|
||||||
|
chunk.setEntity(location, entity.getState());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public @Nonnull List<BlockVector2> getReadChunks() {
|
||||||
|
return this.readRegion;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void addReadChunk(@Nonnull BlockVector2 chunk) {
|
||||||
|
this.readRegion.add(chunk);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void addReadChunks(@Nonnull Set<BlockVector2> readRegion) {
|
||||||
|
this.readRegion.addAll(readRegion);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public CuboidRegion getRegenRegion() {
|
||||||
|
return this.regenRegion != null ? this.regenRegion.clone() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void setRegenRegion(@Nonnull CuboidRegion regenRegion) {
|
||||||
|
this.regenRegion = regenRegion;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void regenChunk(int x, int z) {
|
||||||
|
regen = true;
|
||||||
|
// There will never only be one nullified coordinate pair
|
||||||
|
if (regenStart == null) {
|
||||||
|
regenStart = new int[] {x, z};
|
||||||
|
regenEnd = new int[] {x, z};
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (x < regenStart[0]) {
|
||||||
|
regenStart[0] = x;
|
||||||
|
}
|
||||||
|
if (z < regenStart[1]) {
|
||||||
|
regenStart[1] = z;
|
||||||
|
}
|
||||||
|
if (x > regenEnd[0]) {
|
||||||
|
regenEnd[0] = x;
|
||||||
|
}
|
||||||
|
if (z > regenEnd[1]) {
|
||||||
|
regenEnd[1] = z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean isUnloadAfter() {
|
||||||
|
return this.unloadAfter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void setUnloadAfter(boolean unloadAfter) {
|
||||||
|
this.unloadAfter = unloadAfter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the int[x,z] chunk coordinates where regeneration should start from
|
||||||
|
*/
|
||||||
|
public int[] getRegenStart() {
|
||||||
|
return regenStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the int[x,z] chunk coordinates where regeneration should finish
|
||||||
|
*/
|
||||||
|
public int[] getRegenEnd() {
|
||||||
|
return regenEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the queue has a start/end to chunk regeneration
|
||||||
|
*/
|
||||||
|
public boolean isRegen() {
|
||||||
|
return regen;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the map of ChunkCoordinates in {@link BlockVector2} form against the {@link LocalChunk} of cached chunks to be written
|
||||||
|
*/
|
||||||
|
@Nonnull public ConcurrentHashMap<BlockVector2, LocalChunk> getBlockChunks() {
|
||||||
|
return this.blockChunks;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forces an {@link LocalChunk} into the list of chunks to be written. Overwrites existing chunks in the map
|
||||||
|
*/
|
||||||
|
public final void setChunk(@Nonnull LocalChunk chunk) {
|
||||||
|
this.blockChunks.put(BlockVector2.at(chunk.getX(), chunk.getZ()), chunk);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override @Nullable public final Consumer<BlockVector2> getChunkConsumer() {
|
||||||
|
return this.consumer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public final void setChunkConsumer(@Nonnull Consumer<BlockVector2> consumer) {
|
||||||
|
this.consumer = consumer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public Runnable getCompleteTask() {
|
||||||
|
return this.whenDone;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void setCompleteTask(Runnable whenDone) {
|
||||||
|
this.whenDone = whenDone;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the {@link LocalChunk} from the queue at the given chunk coordinates. Returns a new instance if one doesn't exist
|
||||||
|
*/
|
||||||
|
@Nonnull private LocalChunk getChunk(final int chunkX, final int chunkZ) {
|
||||||
|
if (chunkX != lastX || chunkZ != lastZ) {
|
||||||
|
lastX = chunkX;
|
||||||
|
lastZ = chunkZ;
|
||||||
|
BlockVector2 pair = BlockVector2.at(chunkX, chunkZ);
|
||||||
|
lastWrappedChunk = this.blockChunks.get(pair);
|
||||||
|
if (lastWrappedChunk == null) {
|
||||||
|
lastWrappedChunk = new LocalChunk(this, chunkX, chunkZ);
|
||||||
|
LocalChunk previous = this.blockChunks.put(pair, lastWrappedChunk);
|
||||||
|
if (previous == null) {
|
||||||
|
return lastWrappedChunk;
|
||||||
|
}
|
||||||
|
lastWrappedChunk = previous;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lastWrappedChunk;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* _____ _ _ _____ _
|
||||||
|
* | __ \| | | | / ____| | |
|
||||||
|
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
||||||
|
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
||||||
|
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
||||||
|
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
||||||
|
* | |
|
||||||
|
* |_|
|
||||||
|
* PlotSquared plot management system for Minecraft
|
||||||
|
* Copyright (C) 2020 IntellectualSites
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.plotsquared.core.queue;
|
||||||
|
|
||||||
|
import com.plotsquared.core.util.task.PlotSquaredTask;
|
||||||
|
|
||||||
|
public abstract class ChunkCoordinator implements PlotSquaredTask {
|
||||||
|
|
||||||
|
@Override public abstract void runTask();
|
||||||
|
|
||||||
|
@Override public boolean isCancelled() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void cancel() {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the chunk coordinator. This will usually (implementation-specific-permitting) mark chunks to be loaded in batches,
|
||||||
|
* then add them to a queue and apply tickets once loaded to prevent unloading. A repeating task will then iterate over loaded
|
||||||
|
* chunks, access them with a Consumer(BlockVector2) and remove the ticket once work has been completed on it.
|
||||||
|
*/
|
||||||
|
public abstract void start();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the amount of remaining chunks (at the time of the method call)
|
||||||
|
*
|
||||||
|
* @return Snapshot view of remaining chunk count
|
||||||
|
*/
|
||||||
|
public abstract int getRemainingChunks();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the amount of requested chunks
|
||||||
|
*
|
||||||
|
* @return Requested chunk count
|
||||||
|
*/
|
||||||
|
public abstract int getTotalChunks();
|
||||||
|
}
|
@ -0,0 +1,178 @@
|
|||||||
|
/*
|
||||||
|
* _____ _ _ _____ _
|
||||||
|
* | __ \| | | | / ____| | |
|
||||||
|
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
||||||
|
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
||||||
|
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
||||||
|
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
||||||
|
* | |
|
||||||
|
* |_|
|
||||||
|
* PlotSquared plot management system for Minecraft
|
||||||
|
* Copyright (C) 2020 IntellectualSites
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.plotsquared.core.queue;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.plotsquared.core.inject.factory.ChunkCoordinatorFactory;
|
||||||
|
import com.plotsquared.core.location.Location;
|
||||||
|
import com.sk89q.worldedit.math.BlockVector2;
|
||||||
|
import com.sk89q.worldedit.world.World;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds a {@link ChunkCoordinator} instance
|
||||||
|
*/
|
||||||
|
public class ChunkCoordinatorBuilder {
|
||||||
|
|
||||||
|
private final List<BlockVector2> requestedChunks = new LinkedList<>();
|
||||||
|
private final ChunkCoordinatorFactory chunkCoordinatorFactory;
|
||||||
|
private Consumer<Throwable> throwableConsumer = Throwable::printStackTrace;
|
||||||
|
private World world;
|
||||||
|
private Consumer<BlockVector2> chunkConsumer;
|
||||||
|
private Runnable whenDone = () -> {
|
||||||
|
};
|
||||||
|
private long maxIterationTime = 60; // A little over 1 tick;
|
||||||
|
private int initialBatchSize = 4;
|
||||||
|
private boolean unloadAfter = true;
|
||||||
|
|
||||||
|
@Inject public ChunkCoordinatorBuilder(@Nonnull ChunkCoordinatorFactory chunkCoordinatorFactory) {
|
||||||
|
this.chunkCoordinatorFactory = chunkCoordinatorFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the world
|
||||||
|
*/
|
||||||
|
@Nonnull public ChunkCoordinatorBuilder inWorld(@Nonnull final World world) {
|
||||||
|
this.world = Preconditions.checkNotNull(world, "World may not be null");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a chunk to be accessed
|
||||||
|
*/
|
||||||
|
@Nonnull public ChunkCoordinatorBuilder withChunk(@Nonnull final BlockVector2 chunkLocation) {
|
||||||
|
this.requestedChunks.add(Preconditions.checkNotNull(chunkLocation, "Chunk location may not be null"));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a Collection of chunks to be accessed
|
||||||
|
*/
|
||||||
|
@Nonnull public ChunkCoordinatorBuilder withChunks(@Nonnull final Collection<BlockVector2> chunkLocations) {
|
||||||
|
chunkLocations.forEach(this::withChunk);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add chunks within a region to be accessed
|
||||||
|
*/
|
||||||
|
@Nonnull public ChunkCoordinatorBuilder withRegion(@Nonnull Location pos1, @Nonnull Location pos2) {
|
||||||
|
final int p1x = pos1.getX();
|
||||||
|
final int p1z = pos1.getZ();
|
||||||
|
final int p2x = pos2.getX();
|
||||||
|
final int p2z = pos2.getZ();
|
||||||
|
final int bcx = p1x >> 4;
|
||||||
|
final int bcz = p1z >> 4;
|
||||||
|
final int tcx = p2x >> 4;
|
||||||
|
final int tcz = p2z >> 4;
|
||||||
|
final ArrayList<BlockVector2> chunks = new ArrayList<>();
|
||||||
|
|
||||||
|
for (int x = bcx; x <= tcx; x++) {
|
||||||
|
for (int z = bcz; z <= tcz; z++) {
|
||||||
|
chunks.add(BlockVector2.at(x, z));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
chunks.forEach(this::withChunk);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the consumer to be used when a chunk is loaded
|
||||||
|
*/
|
||||||
|
@Nonnull public ChunkCoordinatorBuilder withConsumer(@Nonnull final Consumer<BlockVector2> chunkConsumer) {
|
||||||
|
this.chunkConsumer = Preconditions.checkNotNull(chunkConsumer, "Chunk consumer may not be null");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the Runnable to run when all chunks have been accessed
|
||||||
|
*/
|
||||||
|
@Nonnull public ChunkCoordinatorBuilder withFinalAction(@Nullable final Runnable whenDone) {
|
||||||
|
if (whenDone == null) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
this.whenDone = whenDone;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the max time taken while iterating over and accessing loaded chunks
|
||||||
|
*/
|
||||||
|
@Nonnull public ChunkCoordinatorBuilder withMaxIterationTime(final long maxIterationTime) {
|
||||||
|
Preconditions.checkArgument(maxIterationTime > 0, "Max iteration time must be positive");
|
||||||
|
this.maxIterationTime = maxIterationTime;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the initial batch size to be used for loading chunks
|
||||||
|
*/
|
||||||
|
@Nonnull public ChunkCoordinatorBuilder withInitialBatchSize(final int initialBatchSize) {
|
||||||
|
Preconditions.checkArgument(initialBatchSize > 0, "Initial batch size must be positive");
|
||||||
|
this.initialBatchSize = initialBatchSize;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the consumer to be used to handle {@link Throwable}s
|
||||||
|
*/
|
||||||
|
@Nonnull public ChunkCoordinatorBuilder withThrowableConsumer(@Nonnull final Consumer<Throwable> throwableConsumer) {
|
||||||
|
this.throwableConsumer = Preconditions.checkNotNull(throwableConsumer, "Throwable consumer may not be null");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set whether the chunks should be allow to unload after being accessed. This should only be used where the chunks are read from
|
||||||
|
* and then written to from a separate queue where they're consequently unloaded.
|
||||||
|
*/
|
||||||
|
@Nonnull public ChunkCoordinatorBuilder unloadAfter(final boolean unloadAfter) {
|
||||||
|
this.unloadAfter = unloadAfter;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link ChunkCoordinator} instance based on the values in the Builder instance.
|
||||||
|
*/
|
||||||
|
@Nonnull public ChunkCoordinator build() {
|
||||||
|
Preconditions.checkNotNull(this.world, "No world was supplied");
|
||||||
|
Preconditions.checkNotNull(this.chunkConsumer, "No chunk consumer was supplied");
|
||||||
|
Preconditions.checkNotNull(this.whenDone, "No final action was supplied");
|
||||||
|
Preconditions.checkNotNull(this.throwableConsumer, "No throwable consumer was supplied");
|
||||||
|
return chunkCoordinatorFactory
|
||||||
|
.create(this.maxIterationTime, this.initialBatchSize, this.chunkConsumer, this.world, this.requestedChunks, this.whenDone,
|
||||||
|
this.throwableConsumer, this.unloadAfter);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -28,65 +28,69 @@ package com.plotsquared.core.queue;
|
|||||||
import com.plotsquared.core.location.Location;
|
import com.plotsquared.core.location.Location;
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
|
import com.sk89q.worldedit.world.World;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
public class ChunkBlockQueue extends ScopedLocalBlockQueue {
|
/**
|
||||||
|
* Queue that is limited to a single chunk
|
||||||
|
*/
|
||||||
|
public class ChunkQueueCoordinator extends ScopedQueueCoordinator {
|
||||||
|
|
||||||
public final BiomeType[] biomeGrid;
|
public final BiomeType[][][] biomeResult;
|
||||||
public final BlockState[][][] result;
|
public final BlockState[][][] result;
|
||||||
private final int width;
|
private final int width;
|
||||||
private final int length;
|
private final int length;
|
||||||
@Deprecated private final int area;
|
|
||||||
private final BlockVector3 bot;
|
private final BlockVector3 bot;
|
||||||
private final BlockVector3 top;
|
private final BlockVector3 top;
|
||||||
|
|
||||||
public ChunkBlockQueue(BlockVector3 bot, BlockVector3 top, boolean biomes) {
|
public ChunkQueueCoordinator(@Nonnull BlockVector3 bot, @Nonnull BlockVector3 top, boolean biomes) {
|
||||||
super(null, Location.at("", 0, 0, 0), Location.at("", 15, 255, 15));
|
super(null, Location.at("", 0, 0, 0), Location.at("", 15, 255, 15));
|
||||||
this.width = top.getX() - bot.getX() + 1;
|
this.width = top.getX() - bot.getX() + 1;
|
||||||
this.length = top.getZ() - bot.getZ() + 1;
|
this.length = top.getZ() - bot.getZ() + 1;
|
||||||
this.area = width * length;
|
|
||||||
this.result = new BlockState[256][][];
|
this.result = new BlockState[256][][];
|
||||||
this.biomeGrid = biomes ? new BiomeType[width * length] : null;
|
this.biomeResult = biomes ? new BiomeType[256][][] : null;
|
||||||
this.bot = bot;
|
this.bot = bot;
|
||||||
this.top = top;
|
this.top = top;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BlockState[][][] getBlocks() {
|
@Nonnull public BlockState[][][] getBlocks() {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void fillBiome(BiomeType biomeType) {
|
@Override public boolean setBiome(int x, int z, @Nonnull BiomeType biomeType) {
|
||||||
if (biomeGrid == null) {
|
if (this.biomeResult != null) {
|
||||||
return;
|
for (int y = 0; y < 256; y++) {
|
||||||
|
this.storeCacheBiome(x, y, z, biomeType);
|
||||||
}
|
}
|
||||||
Arrays.fill(biomeGrid, biomeType);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public boolean setBiome(int x, int z, BiomeType biomeType) {
|
|
||||||
if (this.biomeGrid != null) {
|
|
||||||
biomeGrid[(z * width) + x] = biomeType;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean setBlock(int x, int y, int z, BlockState id) {
|
@Override public boolean setBiome(int x, int y, int z, @Nonnull BiomeType biomeType) {
|
||||||
|
if (this.biomeResult != null) {
|
||||||
|
this.storeCacheBiome(x, y, z, biomeType);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean setBlock(int x, int y, int z, @Nonnull BlockState id) {
|
||||||
this.storeCache(x, y, z, id);
|
this.storeCache(x, y, z, id);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean setBlock(int x, int y, int z, Pattern pattern) {
|
@Override public boolean setBlock(int x, int y, int z, @Nonnull Pattern pattern) {
|
||||||
this.storeCache(x, y, z, pattern.apply(BlockVector3.at(x, y, z)).toImmutableState());
|
this.storeCache(x, y, z, pattern.apply(BlockVector3.at(x, y, z)).toImmutableState());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void storeCache(final int x, final int y, final int z, final BlockState id) {
|
private void storeCache(final int x, final int y, final int z, @Nonnull final BlockState id) {
|
||||||
BlockState[][] resultY = result[y];
|
BlockState[][] resultY = result[y];
|
||||||
if (resultY == null) {
|
if (resultY == null) {
|
||||||
result[y] = resultY = new BlockState[length][];
|
result[y] = resultY = new BlockState[length][];
|
||||||
@ -98,7 +102,19 @@ public class ChunkBlockQueue extends ScopedLocalBlockQueue {
|
|||||||
resultYZ[x] = id;
|
resultYZ[x] = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean setBlock(int x, int y, int z, BaseBlock id) {
|
private void storeCacheBiome(final int x, final int y, final int z, @Nonnull final BiomeType id) {
|
||||||
|
BiomeType[][] resultY = biomeResult[y];
|
||||||
|
if (resultY == null) {
|
||||||
|
biomeResult[y] = resultY = new BiomeType[length][];
|
||||||
|
}
|
||||||
|
BiomeType[] resultYZ = resultY[z];
|
||||||
|
if (resultYZ == null) {
|
||||||
|
resultY[z] = resultYZ = new BiomeType[width];
|
||||||
|
}
|
||||||
|
resultYZ[x] = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean setBlock(int x, int y, int z, @Nonnull final BaseBlock id) {
|
||||||
this.storeCache(x, y, z, id.toImmutableState());
|
this.storeCache(x, y, z, id.toImmutableState());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -114,15 +130,15 @@ public class ChunkBlockQueue extends ScopedLocalBlockQueue {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override @Nonnull public String getWorld() {
|
@Override @Nullable public World getWorld() {
|
||||||
return "";
|
return super.getWorld();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public Location getMax() {
|
@Override @Nonnull public Location getMax() {
|
||||||
return Location.at(getWorld(), top.getX(), top.getY(), top.getZ());
|
return Location.at(getWorld().getName(), top.getX(), top.getY(), top.getZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public Location getMin() {
|
@Override @Nonnull public Location getMin() {
|
||||||
return Location.at(getWorld(), bot.getX(), bot.getY(), bot.getZ());
|
return Location.at(getWorld().getName(), bot.getX(), bot.getY(), bot.getZ());
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,151 +0,0 @@
|
|||||||
/*
|
|
||||||
* _____ _ _ _____ _
|
|
||||||
* | __ \| | | | / ____| | |
|
|
||||||
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
|
||||||
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
|
||||||
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
|
||||||
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
|
||||||
* | |
|
|
||||||
* |_|
|
|
||||||
* PlotSquared plot management system for Minecraft
|
|
||||||
* Copyright (C) 2020 IntellectualSites
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package com.plotsquared.core.queue;
|
|
||||||
|
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
|
||||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
|
||||||
|
|
||||||
public class DelegateLocalBlockQueue extends LocalBlockQueue {
|
|
||||||
|
|
||||||
private final LocalBlockQueue parent;
|
|
||||||
|
|
||||||
public DelegateLocalBlockQueue(LocalBlockQueue parent) {
|
|
||||||
super(parent == null ? null : parent.getWorld());
|
|
||||||
this.parent = parent;
|
|
||||||
|
|
||||||
if (parent != null) {
|
|
||||||
this.setForceSync(parent.isForceSync());
|
|
||||||
this.setChunkObject(parent.getChunkObject());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalBlockQueue getParent() {
|
|
||||||
return parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public boolean next() {
|
|
||||||
return parent.next();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public void startSet(boolean parallel) {
|
|
||||||
if (parent != null) {
|
|
||||||
parent.startSet(parallel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public void endSet(boolean parallel) {
|
|
||||||
if (parent != null) {
|
|
||||||
parent.endSet(parallel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public int size() {
|
|
||||||
if (parent != null) {
|
|
||||||
return parent.size();
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public void optimize() {
|
|
||||||
if (parent != null) {
|
|
||||||
parent.optimize();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public long getModified() {
|
|
||||||
if (parent != null) {
|
|
||||||
return parent.getModified();
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public void setModified(long modified) {
|
|
||||||
if (parent != null) {
|
|
||||||
parent.setModified(modified);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public boolean setBlock(int x, int y, int z, Pattern pattern) {
|
|
||||||
return parent.setBlock(x, y, z, pattern);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public boolean setBlock(int x, int y, int z, BaseBlock id) {
|
|
||||||
return parent.setBlock(x, y, z, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public boolean setBlock(int x, int y, int z, BlockState id) {
|
|
||||||
return parent.setBlock(x, y, z, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public BlockState getBlock(int x, int y, int z) {
|
|
||||||
return parent.getBlock(x, y, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public boolean setBiome(int x, int z, BiomeType biome) {
|
|
||||||
return parent.setBiome(x, z, biome);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public boolean setBiome() {
|
|
||||||
return parent.setBiome();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public String getWorld() {
|
|
||||||
return parent.getWorld();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public void flush() {
|
|
||||||
if (parent != null) {
|
|
||||||
parent.flush();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public void refreshChunk(int x, int z) {
|
|
||||||
if (parent != null) {
|
|
||||||
parent.refreshChunk(x, z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public void fixChunkLighting(int x, int z) {
|
|
||||||
if (parent != null) {
|
|
||||||
parent.fixChunkLighting(x, z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public void regenChunk(int x, int z) {
|
|
||||||
if (parent != null) {
|
|
||||||
parent.regenChunk(x, z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public boolean enqueue() {
|
|
||||||
if (parent != null) {
|
|
||||||
return parent.enqueue();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,251 @@
|
|||||||
|
/*
|
||||||
|
* _____ _ _ _____ _
|
||||||
|
* | __ \| | | | / ____| | |
|
||||||
|
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
||||||
|
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
||||||
|
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
||||||
|
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
||||||
|
* | |
|
||||||
|
* |_|
|
||||||
|
* PlotSquared plot management system for Minecraft
|
||||||
|
* Copyright (C) 2020 IntellectualSites
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.plotsquared.core.queue;
|
||||||
|
|
||||||
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
|
import com.sk89q.worldedit.entity.Entity;
|
||||||
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
|
import com.sk89q.worldedit.math.BlockVector2;
|
||||||
|
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||||
|
import com.sk89q.worldedit.world.World;
|
||||||
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue that delegates to a parent queue.
|
||||||
|
*/
|
||||||
|
public class DelegateQueueCoordinator extends QueueCoordinator {
|
||||||
|
|
||||||
|
private final QueueCoordinator parent;
|
||||||
|
|
||||||
|
public DelegateQueueCoordinator(QueueCoordinator parent) {
|
||||||
|
super(parent == null ? null : parent.getWorld());
|
||||||
|
this.parent = parent;
|
||||||
|
|
||||||
|
if (parent != null) {
|
||||||
|
this.setForceSync(parent.isForceSync());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public QueueCoordinator getParent() {
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public int size() {
|
||||||
|
if (parent != null) {
|
||||||
|
return parent.size();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void setModified(long modified) {
|
||||||
|
if (parent != null) {
|
||||||
|
parent.setModified(modified);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean setBlock(int x, int y, int z, @Nonnull Pattern pattern) {
|
||||||
|
if (parent != null) {
|
||||||
|
return parent.setBlock(x, y, z, pattern);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean setBlock(int x, int y, int z, @Nonnull BaseBlock id) {
|
||||||
|
if (parent != null) {
|
||||||
|
return parent.setBlock(x, y, z, id);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean setBlock(int x, int y, int z, @Nonnull BlockState id) {
|
||||||
|
if (parent != null) {
|
||||||
|
return parent.setBlock(x, y, z, id);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override @Nullable public BlockState getBlock(int x, int y, int z) {
|
||||||
|
if (parent != null) {
|
||||||
|
return parent.getBlock(x, y, z);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean setBiome(int x, int z, @Nonnull BiomeType biome) {
|
||||||
|
if (parent != null) {
|
||||||
|
return parent.setBiome(x, z, biome);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean setBiome(int x, int y, int z, @Nonnull BiomeType biome) {
|
||||||
|
if (parent != null) {
|
||||||
|
return parent.setBiome(x, y, z, biome);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean isSettingBiomes() {
|
||||||
|
if (parent != null) {
|
||||||
|
return parent.isSettingBiomes();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean setEntity(@Nonnull Entity entity) {
|
||||||
|
if (parent != null) {
|
||||||
|
return parent.setEntity(entity);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void regenChunk(int x, int z) {
|
||||||
|
if (parent != null) {
|
||||||
|
parent.regenChunk(x, z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override @Nullable public World getWorld() {
|
||||||
|
if (parent != null) {
|
||||||
|
return parent.getWorld();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean setTile(int x, int y, int z, @Nonnull CompoundTag tag) {
|
||||||
|
if (parent != null) {
|
||||||
|
return parent.setTile(x, y, z, tag);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean isSettingTiles() {
|
||||||
|
if (parent != null) {
|
||||||
|
return parent.isSettingTiles();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean enqueue() {
|
||||||
|
if (parent != null) {
|
||||||
|
return parent.enqueue();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void start() {
|
||||||
|
if (parent != null) {
|
||||||
|
parent.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void cancel() {
|
||||||
|
if (parent != null) {
|
||||||
|
parent.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public Runnable getCompleteTask() {
|
||||||
|
if (parent != null) {
|
||||||
|
return parent.getCompleteTask();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void setCompleteTask(Runnable whenDone) {
|
||||||
|
if (parent != null) {
|
||||||
|
parent.setCompleteTask(whenDone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable @Override public Consumer<BlockVector2> getChunkConsumer() {
|
||||||
|
if (parent != null) {
|
||||||
|
return parent.getChunkConsumer();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void setChunkConsumer(@Nonnull Consumer<BlockVector2> consumer) {
|
||||||
|
if (parent != null) {
|
||||||
|
parent.setChunkConsumer(consumer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override @Nonnull public List<BlockVector2> getReadChunks() {
|
||||||
|
if (parent != null) {
|
||||||
|
return parent.getReadChunks();
|
||||||
|
}
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void addReadChunks(@Nonnull Set<BlockVector2> readChunks) {
|
||||||
|
if (parent != null) {
|
||||||
|
parent.addReadChunks(readChunks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void addReadChunk(@Nonnull BlockVector2 chunk) {
|
||||||
|
if (parent != null) {
|
||||||
|
parent.addReadChunk(chunk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean isUnloadAfter() {
|
||||||
|
if (parent != null) {
|
||||||
|
return parent.isUnloadAfter();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void setUnloadAfter(boolean setUnloadAfter) {
|
||||||
|
if (parent != null) {
|
||||||
|
parent.setUnloadAfter(setUnloadAfter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override @Nullable public CuboidRegion getRegenRegion() {
|
||||||
|
if (parent != null) {
|
||||||
|
return parent.getRegenRegion();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void setRegenRegion(@Nonnull CuboidRegion regenRegion) {
|
||||||
|
if (parent != null) {
|
||||||
|
parent.setRegenRegion(regenRegion);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -26,326 +26,67 @@
|
|||||||
package com.plotsquared.core.queue;
|
package com.plotsquared.core.queue;
|
||||||
|
|
||||||
import com.plotsquared.core.PlotSquared;
|
import com.plotsquared.core.PlotSquared;
|
||||||
import com.plotsquared.core.util.task.RunnableVal2;
|
import com.sk89q.worldedit.world.World;
|
||||||
import com.plotsquared.core.util.task.TaskManager;
|
|
||||||
import com.plotsquared.core.util.task.TaskTime;
|
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.ConcurrentModificationException;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.ConcurrentLinkedDeque;
|
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
|
|
||||||
public class GlobalBlockQueue {
|
public class GlobalBlockQueue {
|
||||||
|
|
||||||
private final int PARALLEL_THREADS;
|
private final ConcurrentLinkedDeque<QueueCoordinator> activeQueues;
|
||||||
private final ConcurrentLinkedDeque<LocalBlockQueue> activeQueues;
|
|
||||||
private final ConcurrentLinkedDeque<LocalBlockQueue> inactiveQueues;
|
|
||||||
private final ConcurrentLinkedDeque<Runnable> runnables;
|
|
||||||
private final AtomicBoolean running;
|
|
||||||
private final int targetTime;
|
|
||||||
private QueueProvider provider;
|
private QueueProvider provider;
|
||||||
/**
|
|
||||||
* Used to calculate elapsed time in milliseconds and ensure block placement doesn't lag the
|
|
||||||
* server
|
|
||||||
*/
|
|
||||||
private long last;
|
|
||||||
private long secondLast;
|
|
||||||
private long lastSuccess;
|
|
||||||
private double lastPeriod = 0;
|
|
||||||
private final RunnableVal2<Long, LocalBlockQueue> SET_TASK =
|
|
||||||
new RunnableVal2<Long, LocalBlockQueue>() {
|
|
||||||
@Override public void run(Long free, LocalBlockQueue queue) {
|
|
||||||
do {
|
|
||||||
boolean more = queue.next();
|
|
||||||
if (!more) {
|
|
||||||
lastSuccess = last;
|
|
||||||
if (inactiveQueues.size() == 0 && activeQueues.size() == 0) {
|
|
||||||
runEmptyTasks();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} while ((lastPeriod =
|
|
||||||
((GlobalBlockQueue.this.secondLast = System.currentTimeMillis())
|
|
||||||
- GlobalBlockQueue.this.last)) < free);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public GlobalBlockQueue(QueueProvider provider, int threads, int targetTime) {
|
public GlobalBlockQueue(@Nonnull QueueProvider provider) {
|
||||||
this.provider = provider;
|
this.provider = provider;
|
||||||
this.activeQueues = new ConcurrentLinkedDeque<>();
|
this.activeQueues = new ConcurrentLinkedDeque<>();
|
||||||
this.inactiveQueues = new ConcurrentLinkedDeque<>();
|
|
||||||
this.runnables = new ConcurrentLinkedDeque<>();
|
|
||||||
this.running = new AtomicBoolean();
|
|
||||||
this.targetTime = targetTime;
|
|
||||||
this.PARALLEL_THREADS = threads;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public QueueProvider getProvider() {
|
/**
|
||||||
return provider;
|
* Get a new {@link QueueCoordinator} for the given world.
|
||||||
}
|
*/
|
||||||
|
@Nonnull public QueueCoordinator getNewQueue(@Nonnull World world) {
|
||||||
public void setProvider(QueueProvider provider) {
|
QueueCoordinator queue = provider.getNewQueue(world);
|
||||||
this.provider = provider;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalBlockQueue getNewQueue(String world, boolean autoQueue) {
|
|
||||||
LocalBlockQueue queue = provider.getNewQueue(world);
|
|
||||||
// Auto-inject into the queue
|
// Auto-inject into the queue
|
||||||
PlotSquared.platform().getInjector().injectMembers(queue);
|
PlotSquared.platform().getInjector().injectMembers(queue);
|
||||||
if (autoQueue) {
|
|
||||||
inactiveQueues.add(queue);
|
|
||||||
}
|
|
||||||
return queue;
|
return queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean stop() {
|
public QueueProvider getProvider() {
|
||||||
if (!running.get()) {
|
return this.provider;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
running.set(false);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean runTask() {
|
public void setQueueProvider(@Nonnull QueueProvider provider) {
|
||||||
if (running.get()) {
|
this.provider = provider;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
running.set(true);
|
|
||||||
TaskManager.runTaskRepeat(new Runnable() {
|
|
||||||
@Override public void run() {
|
|
||||||
if (inactiveQueues.isEmpty() && activeQueues.isEmpty()) {
|
|
||||||
lastSuccess = System.currentTimeMillis();
|
|
||||||
lastPeriod = 0;
|
|
||||||
GlobalBlockQueue.this.runEmptyTasks();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Server laggy? Skip.
|
|
||||||
if (lastPeriod > targetTime) {
|
|
||||||
lastPeriod -= targetTime;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
SET_TASK.value1 = 50 + Math.min(
|
|
||||||
(50 + GlobalBlockQueue.this.last) - (GlobalBlockQueue.this.last =
|
|
||||||
System.currentTimeMillis()),
|
|
||||||
GlobalBlockQueue.this.secondLast - System.currentTimeMillis());
|
|
||||||
SET_TASK.value2 = GlobalBlockQueue.this.getNextQueue();
|
|
||||||
if (SET_TASK.value2 == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!PlotSquared.get().isMainThread(Thread.currentThread())) {
|
|
||||||
throw new IllegalStateException(
|
|
||||||
"This shouldn't be possible for placement to occur off the main thread");
|
|
||||||
}
|
|
||||||
// Disable the async catcher as it can't discern async vs parallel
|
|
||||||
SET_TASK.value2.startSet(true);
|
|
||||||
try {
|
|
||||||
if (PARALLEL_THREADS <= 1) {
|
|
||||||
SET_TASK.run();
|
|
||||||
} else {
|
|
||||||
ArrayList<Thread> threads = new ArrayList<>();
|
|
||||||
for (int i = 0; i < PARALLEL_THREADS; i++) {
|
|
||||||
threads.add(new Thread(SET_TASK));
|
|
||||||
}
|
|
||||||
for (Thread thread : threads) {
|
|
||||||
thread.start();
|
|
||||||
}
|
|
||||||
for (Thread thread : threads) {
|
|
||||||
try {
|
|
||||||
thread.join();
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Throwable e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} finally {
|
|
||||||
// Enable it again (note that we are still on the main thread)
|
|
||||||
SET_TASK.value2.endSet(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, TaskTime.ticks(1L));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public QueueStage getStage(LocalBlockQueue queue) {
|
|
||||||
if (activeQueues.contains(queue)) {
|
|
||||||
return QueueStage.ACTIVE;
|
|
||||||
} else if (inactiveQueues.contains(queue)) {
|
|
||||||
return QueueStage.INACTIVE;
|
|
||||||
}
|
|
||||||
return QueueStage.NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isStage(LocalBlockQueue queue, QueueStage stage) {
|
|
||||||
switch (stage) {
|
|
||||||
case ACTIVE:
|
|
||||||
return activeQueues.contains(queue);
|
|
||||||
case INACTIVE:
|
|
||||||
return inactiveQueues.contains(queue);
|
|
||||||
case NONE:
|
|
||||||
return !activeQueues.contains(queue) && !inactiveQueues.contains(queue);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO Documentation needed.
|
* Place an instance of {@link QueueCoordinator} into a list incase access is needed
|
||||||
|
* and then start it.
|
||||||
*
|
*
|
||||||
* @param queue todo
|
* @param queue {@link QueueCoordinator} instance to start.
|
||||||
* @return true if added to queue, false otherwise
|
* @return true if added to queue, false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean enqueue(LocalBlockQueue queue) {
|
public boolean enqueue(@Nonnull QueueCoordinator queue) {
|
||||||
boolean success = false;
|
boolean success = false;
|
||||||
success = inactiveQueues.remove(queue);
|
|
||||||
if (queue.size() > 0 && !activeQueues.contains(queue)) {
|
if (queue.size() > 0 && !activeQueues.contains(queue)) {
|
||||||
queue.optimize();
|
|
||||||
success = activeQueues.add(queue);
|
success = activeQueues.add(queue);
|
||||||
|
queue.start();
|
||||||
}
|
}
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dequeue(LocalBlockQueue queue) {
|
public void dequeue(@Nonnull QueueCoordinator queue) {
|
||||||
inactiveQueues.remove(queue);
|
queue.cancel();
|
||||||
activeQueues.remove(queue);
|
activeQueues.remove(queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<LocalBlockQueue> getAllQueues() {
|
@Nonnull public List<QueueCoordinator> getActiveQueues() {
|
||||||
ArrayList<LocalBlockQueue> list =
|
|
||||||
new ArrayList<>(activeQueues.size() + inactiveQueues.size());
|
|
||||||
list.addAll(inactiveQueues);
|
|
||||||
list.addAll(activeQueues);
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<LocalBlockQueue> getActiveQueues() {
|
|
||||||
return new ArrayList<>(activeQueues);
|
return new ArrayList<>(activeQueues);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<LocalBlockQueue> getInactiveQueues() {
|
|
||||||
return new ArrayList<>(inactiveQueues);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void flush(LocalBlockQueue queue) {
|
|
||||||
SET_TASK.value1 = Long.MAX_VALUE;
|
|
||||||
SET_TASK.value2 = queue;
|
|
||||||
if (SET_TASK.value2 == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (PlotSquared.get().isMainThread(Thread.currentThread())) {
|
|
||||||
throw new IllegalStateException("Must be flushed on the main thread!");
|
|
||||||
}
|
|
||||||
// Disable the async catcher as it can't discern async vs parallel
|
|
||||||
SET_TASK.value2.startSet(true);
|
|
||||||
try {
|
|
||||||
if (PARALLEL_THREADS <= 1) {
|
|
||||||
SET_TASK.run();
|
|
||||||
} else {
|
|
||||||
ArrayList<Thread> threads = new ArrayList<>();
|
|
||||||
for (int i = 0; i < PARALLEL_THREADS; i++) {
|
|
||||||
Thread thread = new Thread(SET_TASK);
|
|
||||||
thread.setName("PlotSquared Flush Task");
|
|
||||||
threads.add(thread);
|
|
||||||
}
|
|
||||||
for (Thread thread : threads) {
|
|
||||||
thread.start();
|
|
||||||
}
|
|
||||||
for (Thread thread : threads) {
|
|
||||||
try {
|
|
||||||
thread.join();
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Throwable e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} finally {
|
|
||||||
// Enable it again (note that we are still on the main thread)
|
|
||||||
SET_TASK.value2.endSet(true);
|
|
||||||
dequeue(queue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalBlockQueue getNextQueue() {
|
|
||||||
long now = System.currentTimeMillis();
|
|
||||||
while (!activeQueues.isEmpty()) {
|
|
||||||
LocalBlockQueue queue = activeQueues.peek();
|
|
||||||
if (queue != null && queue.size() > 0) {
|
|
||||||
queue.setModified(now);
|
|
||||||
return queue;
|
|
||||||
} else {
|
|
||||||
activeQueues.poll();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int size = inactiveQueues.size();
|
|
||||||
if (size > 0) {
|
|
||||||
Iterator<LocalBlockQueue> iter = inactiveQueues.iterator();
|
|
||||||
try {
|
|
||||||
int total = 0;
|
|
||||||
LocalBlockQueue firstNonEmpty = null;
|
|
||||||
while (iter.hasNext()) {
|
|
||||||
LocalBlockQueue queue = iter.next();
|
|
||||||
long age = now - queue.getModified();
|
|
||||||
total += queue.size();
|
|
||||||
if (queue.size() == 0) {
|
|
||||||
if (age > 60000) {
|
|
||||||
iter.remove();
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (firstNonEmpty == null) {
|
|
||||||
firstNonEmpty = queue;
|
|
||||||
}
|
|
||||||
if (total > 64) {
|
|
||||||
firstNonEmpty.setModified(now);
|
|
||||||
return firstNonEmpty;
|
|
||||||
}
|
|
||||||
if (age > 1000) {
|
|
||||||
queue.setModified(now);
|
|
||||||
return queue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (ConcurrentModificationException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isDone() {
|
public boolean isDone() {
|
||||||
return activeQueues.size() == 0 && inactiveQueues.size() == 0;
|
return activeQueues.size() == 0;
|
||||||
}
|
|
||||||
|
|
||||||
public boolean addEmptyTask(final Runnable whenDone) {
|
|
||||||
if (this.isDone()) {
|
|
||||||
// Run
|
|
||||||
this.runEmptyTasks();
|
|
||||||
if (whenDone != null) {
|
|
||||||
whenDone.run();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (whenDone != null) {
|
|
||||||
this.runnables.add(whenDone);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private synchronized void runEmptyTasks() {
|
|
||||||
if (this.runnables.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final ConcurrentLinkedDeque<Runnable> tmp = new ConcurrentLinkedDeque<>(this.runnables);
|
|
||||||
this.runnables.clear();
|
|
||||||
for (final Runnable runnable : tmp) {
|
|
||||||
runnable.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum QueueStage {
|
|
||||||
INACTIVE, ACTIVE, NONE
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,192 +0,0 @@
|
|||||||
/*
|
|
||||||
* _____ _ _ _____ _
|
|
||||||
* | __ \| | | | / ____| | |
|
|
||||||
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
|
||||||
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
|
||||||
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
|
||||||
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
|
||||||
* | |
|
|
||||||
* |_|
|
|
||||||
* PlotSquared plot management system for Minecraft
|
|
||||||
* Copyright (C) 2020 IntellectualSites
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package com.plotsquared.core.queue;
|
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
|
||||||
import com.plotsquared.core.PlotSquared;
|
|
||||||
import com.plotsquared.core.location.Location;
|
|
||||||
import com.plotsquared.core.player.PlotPlayer;
|
|
||||||
import com.plotsquared.core.util.PatternUtil;
|
|
||||||
import com.plotsquared.core.util.SchematicHandler;
|
|
||||||
import com.plotsquared.core.util.StringMan;
|
|
||||||
import com.plotsquared.core.util.WorldUtil;
|
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
|
||||||
import com.sk89q.worldedit.math.BlockVector2;
|
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
|
||||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
public abstract class LocalBlockQueue {
|
|
||||||
|
|
||||||
private boolean forceSync = false;
|
|
||||||
@Nullable private Object chunkObject;
|
|
||||||
|
|
||||||
@Inject private SchematicHandler schematicHandler;
|
|
||||||
@Inject private WorldUtil worldUtil;
|
|
||||||
@Inject private GlobalBlockQueue blockQueue;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Needed for compatibility with FAWE.
|
|
||||||
*
|
|
||||||
* @param world unused
|
|
||||||
*/
|
|
||||||
@Deprecated public LocalBlockQueue(String world) {
|
|
||||||
PlotSquared.platform().getInjector().injectMembers(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ScopedLocalBlockQueue getForChunk(int x, int z) {
|
|
||||||
int bx = x << 4;
|
|
||||||
int bz = z << 4;
|
|
||||||
return new ScopedLocalBlockQueue(this, Location.at(getWorld(), bx, 0, bz),
|
|
||||||
Location.at(getWorld(), bx + 15, 255, bz + 255));
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract boolean next();
|
|
||||||
|
|
||||||
public abstract void startSet(boolean parallel);
|
|
||||||
|
|
||||||
public abstract void endSet(boolean parallel);
|
|
||||||
|
|
||||||
public abstract int size();
|
|
||||||
|
|
||||||
public abstract void optimize();
|
|
||||||
|
|
||||||
public abstract long getModified();
|
|
||||||
|
|
||||||
public abstract void setModified(long modified);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the block at the coordinates provided to the given id.
|
|
||||||
*
|
|
||||||
* @param x the x coordinate from from 0 to 15 inclusive
|
|
||||||
* @param y the y coordinate from from 0 (inclusive) - maxHeight(exclusive)
|
|
||||||
* @param z the z coordinate from 0 to 15 inclusive
|
|
||||||
* @param id the id to set the block to
|
|
||||||
*/
|
|
||||||
public abstract boolean setBlock(final int x, final int y, final int z, final BlockState id);
|
|
||||||
|
|
||||||
public abstract boolean setBlock(final int x, final int y, final int z, final BaseBlock id);
|
|
||||||
|
|
||||||
public boolean setBlock(final int x, final int y, final int z, @Nonnull final Pattern pattern) {
|
|
||||||
return setBlock(x, y, z, PatternUtil.apply(pattern, x, y, z));
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean setTile(int x, int y, int z, CompoundTag tag) {
|
|
||||||
this.schematicHandler.restoreTile(this, tag, x, y, z);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract BlockState getBlock(int x, int y, int z);
|
|
||||||
|
|
||||||
public abstract boolean setBiome(int x, int z, BiomeType biome);
|
|
||||||
|
|
||||||
public abstract boolean setBiome();
|
|
||||||
|
|
||||||
public abstract String getWorld();
|
|
||||||
|
|
||||||
public abstract void flush();
|
|
||||||
|
|
||||||
public final void setModified() {
|
|
||||||
setModified(System.currentTimeMillis());
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract void refreshChunk(int x, int z);
|
|
||||||
|
|
||||||
public abstract void fixChunkLighting(int x, int z);
|
|
||||||
|
|
||||||
public abstract void regenChunk(int x, int z);
|
|
||||||
|
|
||||||
public final void regenChunkSafe(int x, int z) {
|
|
||||||
regenChunk(x, z);
|
|
||||||
fixChunkLighting(x, z);
|
|
||||||
BlockVector2 loc = BlockVector2.at(x, z);
|
|
||||||
|
|
||||||
for (final PlotPlayer<?> pp : PlotSquared.platform().getPlayerManager().getPlayers()) {
|
|
||||||
Location pLoc = pp.getLocation();
|
|
||||||
if (!StringMan.isEqual(getWorld(), pLoc.getWorldName()) || !pLoc.getChunkLocation()
|
|
||||||
.equals(loc)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
pp.teleport(pLoc.withY(this.worldUtil.getHighestBlockSynchronous(getWorld(), pLoc.getX(), pLoc.getZ())));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean enqueue() {
|
|
||||||
return blockQueue.enqueue(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCuboid(Location pos1, Location pos2, BlockState block) {
|
|
||||||
int yMin = Math.min(pos1.getY(), pos2.getY());
|
|
||||||
int yMax = Math.min(255, Math.max(pos1.getY(), pos2.getY()));
|
|
||||||
int xMin = Math.min(pos1.getX(), pos2.getX());
|
|
||||||
int xMax = Math.max(pos1.getX(), pos2.getX());
|
|
||||||
int zMin = Math.min(pos1.getZ(), pos2.getZ());
|
|
||||||
int zMax = Math.max(pos1.getZ(), pos2.getZ());
|
|
||||||
for (int y = yMin; y <= yMax; y++) {
|
|
||||||
for (int x = xMin; x <= xMax; x++) {
|
|
||||||
for (int z = zMin; z <= zMax; z++) {
|
|
||||||
setBlock(x, y, z, block);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCuboid(Location pos1, Location pos2, Pattern blocks) {
|
|
||||||
int yMin = Math.min(pos1.getY(), pos2.getY());
|
|
||||||
int yMax = Math.min(255, Math.max(pos1.getY(), pos2.getY()));
|
|
||||||
int xMin = Math.min(pos1.getX(), pos2.getX());
|
|
||||||
int xMax = Math.max(pos1.getX(), pos2.getX());
|
|
||||||
int zMin = Math.min(pos1.getZ(), pos2.getZ());
|
|
||||||
int zMax = Math.max(pos1.getZ(), pos2.getZ());
|
|
||||||
for (int y = yMin; y <= yMax; y++) {
|
|
||||||
for (int x = xMin; x <= xMax; x++) {
|
|
||||||
for (int z = zMin; z <= zMax; z++) {
|
|
||||||
setBlock(x, y, z, blocks);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isForceSync() {
|
|
||||||
return this.forceSync;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable public Object getChunkObject() {
|
|
||||||
return this.chunkObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setForceSync(boolean forceSync) {
|
|
||||||
this.forceSync = forceSync;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setChunkObject(@Nullable Object chunkObject) {
|
|
||||||
this.chunkObject = chunkObject;
|
|
||||||
}
|
|
||||||
}
|
|
117
Core/src/main/java/com/plotsquared/core/queue/LocalChunk.java
Normal file
117
Core/src/main/java/com/plotsquared/core/queue/LocalChunk.java
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
/*
|
||||||
|
* _____ _ _ _____ _
|
||||||
|
* | __ \| | | | / ____| | |
|
||||||
|
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
||||||
|
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
||||||
|
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
||||||
|
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
||||||
|
* | |
|
||||||
|
* |_|
|
||||||
|
* PlotSquared plot management system for Minecraft
|
||||||
|
* Copyright (C) 2020 IntellectualSites
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.plotsquared.core.queue;
|
||||||
|
|
||||||
|
import com.plotsquared.core.util.ChunkUtil;
|
||||||
|
import com.plotsquared.core.util.MathMan;
|
||||||
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
|
import com.sk89q.worldedit.entity.BaseEntity;
|
||||||
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
|
import com.sk89q.worldedit.util.Location;
|
||||||
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
public class LocalChunk {
|
||||||
|
private final QueueCoordinator parent;
|
||||||
|
private final int x;
|
||||||
|
private final int z;
|
||||||
|
|
||||||
|
private final BaseBlock[][] baseblocks;
|
||||||
|
private final BiomeType[][] biomes;
|
||||||
|
private final HashMap<BlockVector3, CompoundTag> tiles = new HashMap<>();
|
||||||
|
private final HashMap<Location, BaseEntity> entities = new HashMap<>();
|
||||||
|
|
||||||
|
public LocalChunk(@Nonnull QueueCoordinator parent, int x, int z) {
|
||||||
|
this.parent = parent;
|
||||||
|
this.x = x;
|
||||||
|
this.z = z;
|
||||||
|
baseblocks = new BaseBlock[16][];
|
||||||
|
biomes = new BiomeType[16][];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull public QueueCoordinator getParent() {
|
||||||
|
return this.parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getX() {
|
||||||
|
return this.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getZ() {
|
||||||
|
return this.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull public BaseBlock[][] getBaseblocks() {
|
||||||
|
return this.baseblocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull public BiomeType[][] getBiomes() {
|
||||||
|
return this.biomes;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull public HashMap<BlockVector3, CompoundTag> getTiles() {
|
||||||
|
return this.tiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBiome(final int x, final int y, final int z, @Nonnull final BiomeType biomeType) {
|
||||||
|
final int i = y >> 4;
|
||||||
|
final int j = ChunkUtil.getJ(x, y, z);
|
||||||
|
BiomeType[] array = this.biomes[i];
|
||||||
|
if (array == null) {
|
||||||
|
array = this.biomes[i] = new BiomeType[4096];
|
||||||
|
}
|
||||||
|
array[j] = biomeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public int hashCode() {
|
||||||
|
return MathMan.pair((short) x, (short) z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBlock(final int x, final int y, final int z, @Nonnull final BaseBlock baseBlock) {
|
||||||
|
final int i = y >> 4;
|
||||||
|
final int j = ChunkUtil.getJ(x, y, z);
|
||||||
|
BaseBlock[] array = baseblocks[i];
|
||||||
|
if (array == null) {
|
||||||
|
array = (baseblocks[i] = new BaseBlock[4096]);
|
||||||
|
}
|
||||||
|
array[j] = baseBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTile(final int x, final int y, final int z, @Nonnull final CompoundTag tag) {
|
||||||
|
tiles.put(BlockVector3.at(x, y, z), tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEntity(@Nonnull Location location, @Nonnull BaseEntity entity) {
|
||||||
|
this.entities.put(location, entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull public HashMap<Location, BaseEntity> getEntities() {
|
||||||
|
return this.entities;
|
||||||
|
}
|
||||||
|
}
|
@ -25,40 +25,33 @@
|
|||||||
*/
|
*/
|
||||||
package com.plotsquared.core.queue;
|
package com.plotsquared.core.queue;
|
||||||
|
|
||||||
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public class LocationOffsetDelegateLocalBlockQueue extends DelegateLocalBlockQueue {
|
/**
|
||||||
|
* Offsets input coordinates and delegates to a parent queue
|
||||||
private static final Logger logger = LoggerFactory.getLogger("P2/" + LocationOffsetDelegateLocalBlockQueue.class.getSimpleName());
|
*/
|
||||||
|
public class LocationOffsetDelegateQueueCoordinator extends DelegateQueueCoordinator {
|
||||||
|
|
||||||
private final boolean[][] canPlace;
|
private final boolean[][] canPlace;
|
||||||
private final int blockX;
|
private final int blockX;
|
||||||
private final int blockZ;
|
private final int blockZ;
|
||||||
|
|
||||||
public LocationOffsetDelegateLocalBlockQueue(final boolean[][] canPlace, final int blockX,
|
public LocationOffsetDelegateQueueCoordinator(final boolean[][] canPlace, final int blockX, final int blockZ, @Nullable QueueCoordinator parent) {
|
||||||
final int blockZ, @Nullable LocalBlockQueue parent) {
|
|
||||||
super(parent);
|
super(parent);
|
||||||
this.canPlace = canPlace;
|
this.canPlace = canPlace;
|
||||||
this.blockX = blockX;
|
this.blockX = blockX;
|
||||||
this.blockZ = blockZ;
|
this.blockZ = blockZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean setBlock(int x, int y, int z, BlockState id) {
|
@Override public boolean setBlock(int x, int y, int z, @Nonnull BlockState id) {
|
||||||
if (canPlace[x - blockX][z - blockZ]) {
|
|
||||||
return super.setBlock(x, y, z, id);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public boolean setBlock(int x, int y, int z, BaseBlock id) {
|
|
||||||
try {
|
try {
|
||||||
if (canPlace[x - blockX][z - blockZ]) {
|
if (canPlace[x - blockX][z - blockZ]) {
|
||||||
return super.setBlock(x, y, z, id);
|
return super.setBlock(x, y, z, id);
|
||||||
@ -69,13 +62,49 @@ public class LocationOffsetDelegateLocalBlockQueue extends DelegateLocalBlockQue
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean setBlock(int x, int y, int z, Pattern pattern) {
|
@Override public boolean setBlock(int x, int y, int z, @Nonnull BaseBlock id) {
|
||||||
|
try {
|
||||||
|
if (canPlace[x - blockX][z - blockZ]) {
|
||||||
|
return super.setBlock(x, y, z, id);
|
||||||
|
}
|
||||||
|
} catch (final Exception e) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean setBlock(int x, int y, int z, @Nonnull Pattern pattern) {
|
||||||
final BlockVector3 blockVector3 = BlockVector3.at(x + blockX, y, z + blockZ);
|
final BlockVector3 blockVector3 = BlockVector3.at(x + blockX, y, z + blockZ);
|
||||||
return this.setBlock(x, y, z, pattern.apply(blockVector3));
|
return this.setBlock(x, y, z, pattern.apply(blockVector3));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean setBiome(int x, int y, BiomeType biome) {
|
@Override public boolean setBiome(int x, int z, @Nonnull BiomeType biome) {
|
||||||
return super.setBiome(x, y, biome);
|
boolean result = true;
|
||||||
|
for (int y = 0; y < 256; y++) {
|
||||||
|
result &= this.setBiome(x, z, biome);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override public boolean setBiome(int x, int y, int z, @Nonnull BiomeType biome) {
|
||||||
|
try {
|
||||||
|
if (canPlace[x - blockX][z - blockZ]) {
|
||||||
|
return super.setBiome(x, y, z, biome);
|
||||||
|
}
|
||||||
|
} catch (final Exception e) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean setTile(int x, int y, int z, @Nonnull CompoundTag tag) {
|
||||||
|
try {
|
||||||
|
if (canPlace[x - blockX][z - blockZ]) {
|
||||||
|
return super.setTile(x, y, z, tag);
|
||||||
|
}
|
||||||
|
} catch (final Exception e) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
@ -0,0 +1,336 @@
|
|||||||
|
/*
|
||||||
|
* _____ _ _ _____ _
|
||||||
|
* | __ \| | | | / ____| | |
|
||||||
|
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
||||||
|
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
||||||
|
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
||||||
|
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
||||||
|
* | |
|
||||||
|
* |_|
|
||||||
|
* PlotSquared plot management system for Minecraft
|
||||||
|
* Copyright (C) 2020 IntellectualSites
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.plotsquared.core.queue;
|
||||||
|
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.plotsquared.core.PlotSquared;
|
||||||
|
import com.plotsquared.core.location.Location;
|
||||||
|
import com.plotsquared.core.util.PatternUtil;
|
||||||
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
|
import com.sk89q.worldedit.entity.Entity;
|
||||||
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
|
import com.sk89q.worldedit.math.BlockVector2;
|
||||||
|
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||||
|
import com.sk89q.worldedit.world.World;
|
||||||
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
public abstract class QueueCoordinator {
|
||||||
|
|
||||||
|
private boolean forceSync = false;
|
||||||
|
@Nullable private Object chunkObject;
|
||||||
|
|
||||||
|
@Inject private GlobalBlockQueue blockQueue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor requires world to indicate any extents given to {@link QueueCoordinator} also need this constructor.
|
||||||
|
*/
|
||||||
|
public QueueCoordinator(@Nullable World world) {
|
||||||
|
PlotSquared.platform().getInjector().injectMembers(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a {@link ScopedQueueCoordinator} limited to the chunk at the specific chunk Coordinates
|
||||||
|
*/
|
||||||
|
public ScopedQueueCoordinator getForChunk(int x, int z) {
|
||||||
|
int bx = x << 4;
|
||||||
|
int bz = z << 4;
|
||||||
|
return new ScopedQueueCoordinator(this, Location.at(getWorld().getName(), bx, 0, bz),
|
||||||
|
Location.at(getWorld().getName(), bx + 15, 255, bz + 255));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the size of the queue in chunks
|
||||||
|
*/
|
||||||
|
public abstract int size();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set when the queue was last modified
|
||||||
|
*/
|
||||||
|
public abstract void setModified(long modified);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the queue should be forced to be synchronous when enqueued.
|
||||||
|
*/
|
||||||
|
public boolean isForceSync() {
|
||||||
|
return forceSync;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set whether the queue should be forced to be synchronous
|
||||||
|
*/
|
||||||
|
public void setForceSync(boolean forceSync) {
|
||||||
|
this.forceSync = forceSync;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Chunk Object set to the queue
|
||||||
|
*/
|
||||||
|
@Nullable public Object getChunkObject() {
|
||||||
|
return chunkObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a chunk object (e.g. the Bukkit Chunk object) to the queue
|
||||||
|
*/
|
||||||
|
public void setChunkObject(@Nonnull Object chunkObject) {
|
||||||
|
this.chunkObject = chunkObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the block at the coordinates provided to the given id.
|
||||||
|
*
|
||||||
|
* @param x the x coordinate from from 0 to 15 inclusive
|
||||||
|
* @param y the y coordinate from from 0 (inclusive) - maxHeight(exclusive)
|
||||||
|
* @param z the z coordinate from 0 to 15 inclusive
|
||||||
|
* @param id the BlockState to set the block to
|
||||||
|
*/
|
||||||
|
public abstract boolean setBlock(final int x, final int y, final int z, @Nonnull final BlockState id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the block at the coordinates provided to the given id.
|
||||||
|
*
|
||||||
|
* @param x the x coordinate from from 0 to 15 inclusive
|
||||||
|
* @param y the y coordinate from from 0 (inclusive) - maxHeight(exclusive)
|
||||||
|
* @param z the z coordinate from 0 to 15 inclusive
|
||||||
|
* @param id the BaseBlock to set the block to
|
||||||
|
*/
|
||||||
|
public abstract boolean setBlock(final int x, final int y, final int z, @Nonnull final BaseBlock id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the block at the coordinates provided to the given id.
|
||||||
|
*
|
||||||
|
* @param x the x coordinate from from 0 to 15 inclusive
|
||||||
|
* @param y the y coordinate from from 0 (inclusive) - maxHeight(exclusive)
|
||||||
|
* @param z the z coordinate from 0 to 15 inclusive
|
||||||
|
* @param pattern the pattern to set the block to
|
||||||
|
*/
|
||||||
|
public boolean setBlock(final int x, final int y, final int z, @Nonnull final Pattern pattern) {
|
||||||
|
return setBlock(x, y, z, PatternUtil.apply(pattern, x, y, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a tile entity at the coordinates provided to the given CompoundTag
|
||||||
|
*
|
||||||
|
* @param x the x coordinate from from 0 to 15 inclusive
|
||||||
|
* @param y the y coordinate from from 0 (inclusive) - maxHeight(exclusive)
|
||||||
|
* @param z the z coordinate from 0 to 15 inclusive
|
||||||
|
* @param tag the CompoundTag to set the tile to
|
||||||
|
*/
|
||||||
|
public abstract boolean setTile(int x, int y, int z, @Nonnull CompoundTag tag);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the queue has any tiles being set
|
||||||
|
*/
|
||||||
|
public abstract boolean isSettingTiles();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a block at the given coordinates.
|
||||||
|
*/
|
||||||
|
@Nullable public abstract BlockState getBlock(int x, int y, int z);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a biome in XZ. This will likely set to the whole column
|
||||||
|
*/
|
||||||
|
@Deprecated public abstract boolean setBiome(int x, int z, @Nonnull BiomeType biome);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a biome in XYZ
|
||||||
|
*/
|
||||||
|
public abstract boolean setBiome(int x, int y, int z, @Nonnull BiomeType biome);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the queue has any biomes to be set
|
||||||
|
*/
|
||||||
|
public abstract boolean isSettingBiomes();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add entities to be created
|
||||||
|
*/
|
||||||
|
public void addEntities(@Nonnull List<? extends Entity> entities) {
|
||||||
|
for (Entity e : entities) {
|
||||||
|
this.setEntity(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an entity to be created
|
||||||
|
*/
|
||||||
|
public abstract boolean setEntity(@Nonnull Entity entity);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of chunks that are added manually. This usually indicated the queue is "read only".
|
||||||
|
*/
|
||||||
|
@Nonnull public abstract List<BlockVector2> getReadChunks();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a set of {@link BlockVector2} Chunk coordinates to the Read Chunks list
|
||||||
|
*/
|
||||||
|
public abstract void addReadChunks(@Nonnull Set<BlockVector2> readChunks);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a {@link BlockVector2} Chunk coordinate to the Read Chunks list
|
||||||
|
*/
|
||||||
|
public abstract void addReadChunk(@Nonnull BlockVector2 chunk);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether chunks should be unloaded after being accessed
|
||||||
|
*/
|
||||||
|
public abstract boolean isUnloadAfter();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set whether chunks should be unloaded after being accessed
|
||||||
|
*/
|
||||||
|
public abstract void setUnloadAfter(boolean unloadAfter);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the {@link CuboidRegion} designated for direct regeneration
|
||||||
|
*/
|
||||||
|
@Nullable public abstract CuboidRegion getRegenRegion();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the {@link CuboidRegion} designated for direct regeneration
|
||||||
|
*/
|
||||||
|
public abstract void setRegenRegion(@Nonnull CuboidRegion regenRegion);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a specific chunk at the chunk coordinates XZ to be regenerated.
|
||||||
|
*/
|
||||||
|
public abstract void regenChunk(int x, int z);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the world the queue is writing to
|
||||||
|
*/
|
||||||
|
@Nullable public abstract World getWorld();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the queue as having been modified now
|
||||||
|
*/
|
||||||
|
public final void setModified() {
|
||||||
|
setModified(System.currentTimeMillis());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enqueue the queue with the {@link GlobalBlockQueue}
|
||||||
|
*/
|
||||||
|
public boolean enqueue() {
|
||||||
|
return blockQueue.enqueue(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start the queue
|
||||||
|
*/
|
||||||
|
public abstract void start();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancel the queue. Not yet implemented.
|
||||||
|
*/
|
||||||
|
public abstract void cancel();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the task to be run when all chunks have been accessed
|
||||||
|
*/
|
||||||
|
public abstract Runnable getCompleteTask();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the task to be run when all chunks have been accessed
|
||||||
|
*/
|
||||||
|
public abstract void setCompleteTask(@Nullable Runnable whenDone);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the chunk consumer set to the queue or null if one is not set
|
||||||
|
*/
|
||||||
|
@Nullable public abstract Consumer<BlockVector2> getChunkConsumer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the Consumer that will
|
||||||
|
*/
|
||||||
|
public abstract void setChunkConsumer(@Nonnull Consumer<BlockVector2> consumer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fill a cuboid between two positions with a BlockState
|
||||||
|
*/
|
||||||
|
public void setCuboid(@Nonnull Location pos1, @Nonnull Location pos2, @Nonnull BlockState block) {
|
||||||
|
int yMin = Math.min(pos1.getY(), pos2.getY());
|
||||||
|
int yMax = Math.min(255, Math.max(pos1.getY(), pos2.getY()));
|
||||||
|
int xMin = Math.min(pos1.getX(), pos2.getX());
|
||||||
|
int xMax = Math.max(pos1.getX(), pos2.getX());
|
||||||
|
int zMin = Math.min(pos1.getZ(), pos2.getZ());
|
||||||
|
int zMax = Math.max(pos1.getZ(), pos2.getZ());
|
||||||
|
for (int y = yMin; y <= yMax; y++) {
|
||||||
|
for (int x = xMin; x <= xMax; x++) {
|
||||||
|
for (int z = zMin; z <= zMax; z++) {
|
||||||
|
setBlock(x, y, z, block);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fill a cuboid between two positions with a Pattern
|
||||||
|
*/
|
||||||
|
public void setCuboid(@Nonnull Location pos1, @Nonnull Location pos2, @Nonnull Pattern blocks) {
|
||||||
|
int yMin = Math.min(pos1.getY(), pos2.getY());
|
||||||
|
int yMax = Math.min(255, Math.max(pos1.getY(), pos2.getY()));
|
||||||
|
int xMin = Math.min(pos1.getX(), pos2.getX());
|
||||||
|
int xMax = Math.max(pos1.getX(), pos2.getX());
|
||||||
|
int zMin = Math.min(pos1.getZ(), pos2.getZ());
|
||||||
|
int zMax = Math.max(pos1.getZ(), pos2.getZ());
|
||||||
|
for (int y = yMin; y <= yMax; y++) {
|
||||||
|
for (int x = xMin; x <= xMax; x++) {
|
||||||
|
for (int z = zMin; z <= zMax; z++) {
|
||||||
|
setBlock(x, y, z, blocks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fill a cuboid between two positions with a BiomeType
|
||||||
|
*/
|
||||||
|
public void setBiomeCuboid(@Nonnull Location pos1, @Nonnull Location pos2, @Nonnull BiomeType biome) {
|
||||||
|
int yMin = Math.min(pos1.getY(), pos2.getY());
|
||||||
|
int yMax = Math.min(255, Math.max(pos1.getY(), pos2.getY()));
|
||||||
|
int xMin = Math.min(pos1.getX(), pos2.getX());
|
||||||
|
int xMax = Math.max(pos1.getX(), pos2.getX());
|
||||||
|
int zMin = Math.min(pos1.getZ(), pos2.getZ());
|
||||||
|
int zMax = Math.max(pos1.getZ(), pos2.getZ());
|
||||||
|
for (int y = yMin; y <= yMax; y++) {
|
||||||
|
for (int x = xMin; x <= xMax; x++) {
|
||||||
|
for (int z = zMin; z <= zMax; z++) {
|
||||||
|
setBiome(x, y, z, biome);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -25,25 +25,29 @@
|
|||||||
*/
|
*/
|
||||||
package com.plotsquared.core.queue;
|
package com.plotsquared.core.queue;
|
||||||
|
|
||||||
|
import com.plotsquared.core.PlotSquared;
|
||||||
|
import com.sk89q.worldedit.world.World;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
public abstract class QueueProvider {
|
public abstract class QueueProvider {
|
||||||
public static QueueProvider of(final Class<? extends LocalBlockQueue> primary,
|
|
||||||
final Class<? extends LocalBlockQueue> fallback) {
|
private static final Logger logger = LoggerFactory.getLogger("P2/" + PlotSquared.class.getSimpleName());
|
||||||
|
|
||||||
|
public static QueueProvider of(@Nonnull final Class<? extends QueueCoordinator> primary) {
|
||||||
return new QueueProvider() {
|
return new QueueProvider() {
|
||||||
|
|
||||||
private boolean failed = false;
|
@Override public QueueCoordinator getNewQueue(@Nonnull World world) {
|
||||||
|
|
||||||
@Override public LocalBlockQueue getNewQueue(String world) {
|
|
||||||
if (!failed) {
|
|
||||||
try {
|
try {
|
||||||
return (LocalBlockQueue) primary.getConstructors()[0].newInstance(world);
|
return (QueueCoordinator) primary.getConstructors()[0].newInstance(world);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
logger.error("Error creating Queue: {} - Does it have the correct constructor(s)?", primary.getName());
|
||||||
failed = true;
|
if (!primary.getName().contains("com.plotsquared")) {
|
||||||
|
logger.error("It looks like {} is a custom queue. Please look for a plugin in its classpath and report to them.",
|
||||||
|
primary.getSimpleName());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
try {
|
|
||||||
return (LocalBlockQueue) fallback.getConstructors()[0].newInstance(world);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@ -51,5 +55,8 @@ public abstract class QueueProvider {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract LocalBlockQueue getNewQueue(String world);
|
/**
|
||||||
|
* Get a queue for the given world
|
||||||
|
*/
|
||||||
|
public abstract QueueCoordinator getNewQueue(@Nonnull World world);
|
||||||
}
|
}
|
||||||
|
@ -26,12 +26,19 @@
|
|||||||
package com.plotsquared.core.queue;
|
package com.plotsquared.core.queue;
|
||||||
|
|
||||||
import com.plotsquared.core.location.Location;
|
import com.plotsquared.core.location.Location;
|
||||||
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
|
|
||||||
public class ScopedLocalBlockQueue extends DelegateLocalBlockQueue {
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue that only sets blocks with a designated area
|
||||||
|
*/
|
||||||
|
public class ScopedQueueCoordinator extends DelegateQueueCoordinator {
|
||||||
private final int minX;
|
private final int minX;
|
||||||
private final int minY;
|
private final int minY;
|
||||||
private final int minZ;
|
private final int minZ;
|
||||||
@ -44,7 +51,7 @@ public class ScopedLocalBlockQueue extends DelegateLocalBlockQueue {
|
|||||||
private final int dy;
|
private final int dy;
|
||||||
private final int dz;
|
private final int dz;
|
||||||
|
|
||||||
public ScopedLocalBlockQueue(LocalBlockQueue parent, Location min, Location max) {
|
public ScopedQueueCoordinator(@Nullable QueueCoordinator parent, @Nonnull Location min, @Nonnull Location max) {
|
||||||
super(parent);
|
super(parent);
|
||||||
this.minX = min.getX();
|
this.minX = min.getX();
|
||||||
this.minY = min.getY();
|
this.minY = min.getY();
|
||||||
@ -59,39 +66,46 @@ public class ScopedLocalBlockQueue extends DelegateLocalBlockQueue {
|
|||||||
this.dz = maxZ - minZ;
|
this.dz = maxZ - minZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean setBiome(int x, int z, BiomeType biome) {
|
@Override public boolean setBiome(int x, int z, @Nonnull BiomeType biome) {
|
||||||
return x >= 0 && x <= dx && z >= 0 && z <= dz && super.setBiome(x + minX, z + minZ, biome);
|
return x >= 0 && x <= dx && z >= 0 && z <= dz && super.setBiome(x + minX, z + minZ, biome);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override public boolean setBiome(int x, int y, int z, @Nonnull BiomeType biome) {
|
||||||
|
return x >= 0 && x <= dx && y >= 0 && y <= dy && z >= 0 && z <= dz && super.setBiome(x + minX, y + minY, z + minZ, biome);
|
||||||
|
}
|
||||||
|
|
||||||
public void fillBiome(BiomeType biome) {
|
public void fillBiome(BiomeType biome) {
|
||||||
|
for (int y = 0; y <= dy; y++) {
|
||||||
for (int x = 0; x <= dx; x++) {
|
for (int x = 0; x <= dx; x++) {
|
||||||
for (int z = 0; z < dz; z++) {
|
for (int z = 0; z < dz; z++) {
|
||||||
setBiome(x, z, biome);
|
setBiome(x, y, z, biome);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean setBlock(int x, int y, int z, BaseBlock id) {
|
@Override public boolean setBlock(int x, int y, int z, @Nonnull BaseBlock id) {
|
||||||
return x >= 0 && x <= dx && y >= 0 && y <= dy && z >= 0 && z <= dz && super
|
return x >= 0 && x <= dx && y >= 0 && y <= dy && z >= 0 && z <= dz && super.setBlock(x + minX, y + minY, z + minZ, id);
|
||||||
.setBlock(x + minX, y + minY, z + minZ, id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean setBlock(int x, int y, int z, BlockState id) {
|
@Override public boolean setBlock(int x, int y, int z, @Nonnull BlockState id) {
|
||||||
return x >= 0 && x <= dx && y >= 0 && y <= dy && z >= 0 && z <= dz && super
|
return x >= 0 && x <= dx && y >= 0 && y <= dy && z >= 0 && z <= dz && super.setBlock(x + minX, y + minY, z + minZ, id);
|
||||||
.setBlock(x + minX, y + minY, z + minZ, id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean setBlock(int x, int y, int z, Pattern pattern) {
|
@Override public boolean setBlock(int x, int y, int z, @Nonnull Pattern pattern) {
|
||||||
return x >= 0 && x <= dx && y >= 0 && y <= dy && z >= 0 && z <= dz && super
|
return x >= 0 && x <= dx && y >= 0 && y <= dy && z >= 0 && z <= dz && super.setBlock(x + minX, y + minY, z + minZ, pattern);
|
||||||
.setBlock(x + minX, y + minY, z + minZ, pattern);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Location getMin() {
|
@Override public boolean setTile(int x, int y, int z, @Nonnull CompoundTag tag) {
|
||||||
return Location.at(this.getWorld(), this.minX, this.minY, this.minZ);
|
return x >= 0 && x <= dx && y >= 0 && y <= dy && z >= 0 && z <= dz && super.setTile(x + minX, y + minY, z + minZ, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Location getMax() {
|
@Nonnull public Location getMin() {
|
||||||
return Location.at(this.getWorld(), this.maxX, this.maxY, this.maxZ);
|
return Location.at(this.getWorld().getName(), this.minX, this.minY, this.minZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull public Location getMax() {
|
||||||
|
return Location.at(this.getWorld().getName(), this.maxX, this.maxY, this.maxZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -27,36 +27,30 @@ package com.plotsquared.core.util;
|
|||||||
|
|
||||||
import com.plotsquared.core.PlotSquared;
|
import com.plotsquared.core.PlotSquared;
|
||||||
import com.plotsquared.core.location.Location;
|
import com.plotsquared.core.location.Location;
|
||||||
import com.plotsquared.core.plot.Plot;
|
import com.plotsquared.core.queue.QueueCoordinator;
|
||||||
import com.plotsquared.core.queue.LocalBlockQueue;
|
import com.plotsquared.core.queue.ScopedQueueCoordinator;
|
||||||
import com.plotsquared.core.queue.ScopedLocalBlockQueue;
|
|
||||||
import com.plotsquared.core.util.task.RunnableVal;
|
import com.plotsquared.core.util.task.RunnableVal;
|
||||||
import com.plotsquared.core.util.task.TaskManager;
|
|
||||||
import com.plotsquared.core.util.task.TaskTime;
|
|
||||||
import com.sk89q.worldedit.math.BlockVector2;
|
import com.sk89q.worldedit.math.BlockVector2;
|
||||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
public abstract class ChunkManager {
|
public abstract class ChunkManager {
|
||||||
|
|
||||||
private static final Map<BlockVector2, RunnableVal<ScopedLocalBlockQueue>> forceChunks =
|
private static final Map<BlockVector2, RunnableVal<ScopedQueueCoordinator>> forceChunks = new ConcurrentHashMap<>();
|
||||||
new ConcurrentHashMap<>();
|
private static final Map<BlockVector2, RunnableVal<ScopedQueueCoordinator>> addChunks = new ConcurrentHashMap<>();
|
||||||
private static final Map<BlockVector2, RunnableVal<ScopedLocalBlockQueue>> addChunks =
|
|
||||||
new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
public static void setChunkInPlotArea(RunnableVal<ScopedLocalBlockQueue> force,
|
public static void setChunkInPlotArea(RunnableVal<ScopedQueueCoordinator> force,
|
||||||
RunnableVal<ScopedLocalBlockQueue> add, String world, BlockVector2 loc) {
|
RunnableVal<ScopedQueueCoordinator> add,
|
||||||
LocalBlockQueue queue = PlotSquared.platform().getGlobalBlockQueue().getNewQueue(world, false);
|
String world,
|
||||||
|
BlockVector2 loc) {
|
||||||
|
QueueCoordinator queue = PlotSquared.platform().getGlobalBlockQueue().getNewQueue(PlotSquared.platform().getWorldUtil().getWeWorld(world));
|
||||||
if (PlotSquared.get().getPlotAreaManager().isAugmented(world) && PlotSquared.get().isNonStandardGeneration(world, loc)) {
|
if (PlotSquared.get().getPlotAreaManager().isAugmented(world) && PlotSquared.get().isNonStandardGeneration(world, loc)) {
|
||||||
int blockX = loc.getX() << 4;
|
int blockX = loc.getX() << 4;
|
||||||
int blockZ = loc.getZ() << 4;
|
int blockZ = loc.getZ() << 4;
|
||||||
ScopedLocalBlockQueue scoped =
|
ScopedQueueCoordinator scoped =
|
||||||
new ScopedLocalBlockQueue(queue, Location.at(world, blockX, 0, blockZ),
|
new ScopedQueueCoordinator(queue, Location.at(world, blockX, 0, blockZ), Location.at(world, blockX + 15, 255, blockZ + 15));
|
||||||
Location.at(world, blockX + 15, 255, blockZ + 15));
|
|
||||||
if (force != null) {
|
if (force != null) {
|
||||||
force.run(scoped);
|
force.run(scoped);
|
||||||
} else {
|
} else {
|
||||||
@ -65,7 +59,7 @@ public abstract class ChunkManager {
|
|||||||
add.run(scoped);
|
add.run(scoped);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
queue.flush();
|
queue.enqueue();
|
||||||
} else {
|
} else {
|
||||||
if (force != null) {
|
if (force != null) {
|
||||||
forceChunks.put(loc, force);
|
forceChunks.put(loc, force);
|
||||||
@ -77,8 +71,8 @@ public abstract class ChunkManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean preProcessChunk(BlockVector2 loc, ScopedLocalBlockQueue queue) {
|
public static boolean preProcessChunk(BlockVector2 loc, ScopedQueueCoordinator queue) {
|
||||||
final RunnableVal<ScopedLocalBlockQueue> forceChunk = forceChunks.get(loc);
|
final RunnableVal<ScopedQueueCoordinator> forceChunk = forceChunks.get(loc);
|
||||||
if (forceChunk != null) {
|
if (forceChunk != null) {
|
||||||
forceChunk.run(queue);
|
forceChunk.run(queue);
|
||||||
forceChunks.remove(loc);
|
forceChunks.remove(loc);
|
||||||
@ -87,8 +81,8 @@ public abstract class ChunkManager {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean postProcessChunk(BlockVector2 loc, ScopedLocalBlockQueue queue) {
|
public static boolean postProcessChunk(BlockVector2 loc, ScopedQueueCoordinator queue) {
|
||||||
final RunnableVal<ScopedLocalBlockQueue> addChunk = forceChunks.get(loc);
|
final RunnableVal<ScopedQueueCoordinator> addChunk = forceChunks.get(loc);
|
||||||
if (addChunk != null) {
|
if (addChunk != null) {
|
||||||
addChunk.run(queue);
|
addChunk.run(queue);
|
||||||
addChunks.remove(loc);
|
addChunks.remove(loc);
|
||||||
@ -97,107 +91,6 @@ public abstract class ChunkManager {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void chunkTask(final Plot plot, final RunnableVal<int[]> task,
|
@Deprecated public abstract CompletableFuture loadChunk(String world, BlockVector2 loc, boolean force);
|
||||||
final Runnable whenDone, final int allocate) {
|
|
||||||
final ArrayList<CuboidRegion> regions = new ArrayList<>(plot.getRegions());
|
|
||||||
Runnable smallTask = new Runnable() {
|
|
||||||
@Override public void run() {
|
|
||||||
if (regions.isEmpty()) {
|
|
||||||
TaskManager.runTask(whenDone);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
CuboidRegion value = regions.remove(0);
|
|
||||||
Location pos1 = Location.at(plot.getWorldName(), value.getMinimumPoint().getX(), 0,
|
|
||||||
value.getMinimumPoint().getZ());
|
|
||||||
Location pos2 = Location.at(plot.getWorldName(), value.getMaximumPoint().getX(), 0,
|
|
||||||
value.getMaximumPoint().getZ());
|
|
||||||
chunkTask(pos1, pos2, task, this, allocate);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
smallTask.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The int[] will be in the form: [chunkX, chunkZ, pos1x, pos1z, pos2x, pos2z, isEdge] and will represent the bottom and top parts of the chunk
|
|
||||||
*
|
|
||||||
* @param pos1
|
|
||||||
* @param pos2
|
|
||||||
* @param task
|
|
||||||
* @param whenDone
|
|
||||||
*/
|
|
||||||
public static void chunkTask(Location pos1, Location pos2, final RunnableVal<int[]> task,
|
|
||||||
final Runnable whenDone, final int allocate) {
|
|
||||||
final int p1x = pos1.getX();
|
|
||||||
final int p1z = pos1.getZ();
|
|
||||||
final int p2x = pos2.getX();
|
|
||||||
final int p2z = pos2.getZ();
|
|
||||||
final int bcx = p1x >> 4;
|
|
||||||
final int bcz = p1z >> 4;
|
|
||||||
final int tcx = p2x >> 4;
|
|
||||||
final int tcz = p2z >> 4;
|
|
||||||
final ArrayList<BlockVector2> chunks = new ArrayList<>();
|
|
||||||
|
|
||||||
for (int x = bcx; x <= tcx; x++) {
|
|
||||||
for (int z = bcz; z <= tcz; z++) {
|
|
||||||
chunks.add(BlockVector2.at(x, z));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TaskManager.runTask(new Runnable() {
|
|
||||||
@Override public void run() {
|
|
||||||
long start = System.currentTimeMillis();
|
|
||||||
while (!chunks.isEmpty() && ((System.currentTimeMillis() - start) < allocate)) {
|
|
||||||
BlockVector2 chunk = chunks.remove(0);
|
|
||||||
task.value = new int[7];
|
|
||||||
task.value[0] = chunk.getX();
|
|
||||||
task.value[1] = chunk.getZ();
|
|
||||||
task.value[2] = task.value[0] << 4;
|
|
||||||
task.value[3] = task.value[1] << 4;
|
|
||||||
task.value[4] = task.value[2] + 15;
|
|
||||||
task.value[5] = task.value[3] + 15;
|
|
||||||
if (task.value[0] == bcx) {
|
|
||||||
task.value[2] = p1x;
|
|
||||||
task.value[6] = 1;
|
|
||||||
}
|
|
||||||
if (task.value[0] == tcx) {
|
|
||||||
task.value[4] = p2x;
|
|
||||||
task.value[6] = 1;
|
|
||||||
}
|
|
||||||
if (task.value[1] == bcz) {
|
|
||||||
task.value[3] = p1z;
|
|
||||||
task.value[6] = 1;
|
|
||||||
}
|
|
||||||
if (task.value[1] == tcz) {
|
|
||||||
task.value[5] = p2z;
|
|
||||||
task.value[6] = 1;
|
|
||||||
}
|
|
||||||
task.run();
|
|
||||||
}
|
|
||||||
if (!chunks.isEmpty()) {
|
|
||||||
TaskManager.runTaskLater(this, TaskTime.ticks(1L));
|
|
||||||
} else {
|
|
||||||
TaskManager.runTask(whenDone);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract CompletableFuture loadChunk(String world, BlockVector2 loc, boolean force);
|
|
||||||
|
|
||||||
public abstract void unloadChunk(String world, BlockVector2 loc, boolean save);
|
|
||||||
|
|
||||||
public Plot hasPlot(String world, BlockVector2 chunk) {
|
|
||||||
int x1 = chunk.getX() << 4;
|
|
||||||
int z1 = chunk.getZ() << 4;
|
|
||||||
int x2 = x1 + 15;
|
|
||||||
int z2 = z1 + 15;
|
|
||||||
Location bot = Location.at(world, x1, 0, z1);
|
|
||||||
Plot plot = bot.getOwnedPlotAbs();
|
|
||||||
if (plot != null) {
|
|
||||||
return plot;
|
|
||||||
}
|
|
||||||
Location top = Location.at(world, x2, 0, z2);
|
|
||||||
plot = top.getOwnedPlotAbs();
|
|
||||||
return plot;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,10 @@
|
|||||||
*/
|
*/
|
||||||
package com.plotsquared.core.util;
|
package com.plotsquared.core.util;
|
||||||
|
|
||||||
|
import com.plotsquared.core.location.Location;
|
||||||
|
import com.sk89q.worldedit.math.BlockVector2;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
/**
|
/**
|
||||||
* This cache is used for world generation and just saves a bit of calculation time when checking if something is in the plot area.
|
* This cache is used for world generation and just saves a bit of calculation time when checking if something is in the plot area.
|
||||||
*/
|
*/
|
||||||
@ -34,10 +38,10 @@ public class ChunkUtil {
|
|||||||
* Cache of mapping x,y,z coordinates to the chunk array<br>
|
* Cache of mapping x,y,z coordinates to the chunk array<br>
|
||||||
* - Used for efficient world generation<br>
|
* - Used for efficient world generation<br>
|
||||||
*/
|
*/
|
||||||
private static short[] x_loc;
|
private static final short[] x_loc;
|
||||||
private static short[][] y_loc;
|
private static final short[][] y_loc;
|
||||||
private static short[] z_loc;
|
private static final short[] z_loc;
|
||||||
private static short[][][] CACHE_J = null;
|
private static final short[][][] CACHE_J;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
x_loc = new short[4096];
|
x_loc = new short[4096];
|
||||||
@ -78,8 +82,7 @@ public class ChunkUtil {
|
|||||||
* @param z Relative z coordinate
|
* @param z Relative z coordinate
|
||||||
* @return J value for xyz position in Array[4096].
|
* @return J value for xyz position in Array[4096].
|
||||||
*/
|
*/
|
||||||
public static int getJ(int x, int y,
|
public static int getJ(int x, int y, int z) {
|
||||||
int z) {
|
|
||||||
return CACHE_J[y][x][z];
|
return CACHE_J[y][x][z];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,4 +116,22 @@ public class ChunkUtil {
|
|||||||
public static int getZ(int j) {
|
public static int getZ(int j) {
|
||||||
return z_loc[j];
|
return z_loc[j];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the region pos1-pos2 contains the chunk
|
||||||
|
*
|
||||||
|
* @param pos1 Region minimum point
|
||||||
|
* @param pos2 Region maximum point
|
||||||
|
* @param chunk BlockVector2 of chunk coordinates
|
||||||
|
* @return true if the region pos1-pos2 contains the chunk
|
||||||
|
*/
|
||||||
|
public static boolean isWholeChunk(@Nonnull Location pos1, @Nonnull Location pos2, @Nonnull BlockVector2 chunk) {
|
||||||
|
int x1 = pos1.getX();
|
||||||
|
int z1 = pos1.getZ();
|
||||||
|
int x2 = pos2.getX();
|
||||||
|
int z2 = pos2.getZ();
|
||||||
|
int cx = chunk.getX() << 4;
|
||||||
|
int cz = chunk.getZ() << 4;
|
||||||
|
return cx > x1 && cz > z1 && cx < x2 && cz < z2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ import static com.plotsquared.core.util.entity.EntityCategories.CAP_VEHICLE;
|
|||||||
/**
|
/**
|
||||||
* Entity related general utility methods
|
* Entity related general utility methods
|
||||||
*/
|
*/
|
||||||
public final class EntityUtil {
|
public class EntityUtil {
|
||||||
|
|
||||||
private EntityUtil() {
|
private EntityUtil() {
|
||||||
throw new UnsupportedOperationException(
|
throw new UnsupportedOperationException(
|
||||||
|
@ -106,6 +106,9 @@ public class EventDispatcher {
|
|||||||
eventBus.unregister(listener);
|
eventBus.unregister(listener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public void callGenericEvent(@Nonnull final Object event) {
|
||||||
|
eventBus.post(event);
|
||||||
|
}
|
||||||
|
|
||||||
public void callEvent(@Nonnull final PlotEvent event) {
|
public void callEvent(@Nonnull final PlotEvent event) {
|
||||||
eventBus.post(event);
|
eventBus.post(event);
|
||||||
|
@ -107,7 +107,7 @@ public abstract class PlayerManager<P extends PlotPlayer<? extends T>, T> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of names given a list of UUIDs.
|
* Get a list of names given a list of UUIDs.
|
||||||
* - Uses the format {@link Captions#PLOT_USER_LIST} for the returned string
|
* - Uses the format {@link TranslatableCaption#of(String)} of "info.plot_user_list" for the returned string
|
||||||
*
|
*
|
||||||
* @param uuids UUIDs
|
* @param uuids UUIDs
|
||||||
* @return Name list
|
* @return Name list
|
||||||
|
@ -25,26 +25,31 @@
|
|||||||
*/
|
*/
|
||||||
package com.plotsquared.core.util;
|
package com.plotsquared.core.util;
|
||||||
|
|
||||||
|
import com.google.inject.Inject;
|
||||||
import com.plotsquared.core.PlotSquared;
|
import com.plotsquared.core.PlotSquared;
|
||||||
import com.plotsquared.core.location.Location;
|
import com.plotsquared.core.location.Location;
|
||||||
import com.plotsquared.core.plot.Plot;
|
import com.plotsquared.core.plot.Plot;
|
||||||
import com.plotsquared.core.plot.PlotArea;
|
import com.plotsquared.core.plot.PlotArea;
|
||||||
import com.plotsquared.core.plot.PlotManager;
|
import com.plotsquared.core.plot.PlotManager;
|
||||||
import com.plotsquared.core.queue.LocalBlockQueue;
|
import com.plotsquared.core.queue.BasicQueueCoordinator;
|
||||||
import com.plotsquared.core.util.task.RunnableVal;
|
import com.plotsquared.core.queue.GlobalBlockQueue;
|
||||||
|
import com.plotsquared.core.queue.QueueCoordinator;
|
||||||
import com.plotsquared.core.util.task.TaskManager;
|
import com.plotsquared.core.util.task.TaskManager;
|
||||||
import com.plotsquared.core.util.task.TaskTime;
|
import com.sk89q.worldedit.entity.Entity;
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
import com.sk89q.worldedit.math.BlockVector2;
|
import com.sk89q.worldedit.math.BlockVector2;
|
||||||
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||||
|
import com.sk89q.worldedit.regions.Region;
|
||||||
|
import com.sk89q.worldedit.world.World;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public abstract class RegionManager {
|
public abstract class RegionManager {
|
||||||
@ -52,6 +57,13 @@ public abstract class RegionManager {
|
|||||||
private static final Logger logger = LoggerFactory.getLogger("P2/" + RegionManager.class.getSimpleName());
|
private static final Logger logger = LoggerFactory.getLogger("P2/" + RegionManager.class.getSimpleName());
|
||||||
|
|
||||||
public static RegionManager manager = null;
|
public static RegionManager manager = null;
|
||||||
|
private final WorldUtil worldUtil;
|
||||||
|
private final GlobalBlockQueue blockQueue;
|
||||||
|
|
||||||
|
@Inject public RegionManager(@Nonnull WorldUtil worldUtil, @Nonnull GlobalBlockQueue blockQueue) {
|
||||||
|
this.worldUtil = worldUtil;
|
||||||
|
this.blockQueue = blockQueue;
|
||||||
|
}
|
||||||
|
|
||||||
public static BlockVector2 getRegion(Location location) {
|
public static BlockVector2 getRegion(Location location) {
|
||||||
int x = location.getX() >> 9;
|
int x = location.getX() >> 9;
|
||||||
@ -59,52 +71,6 @@ public abstract class RegionManager {
|
|||||||
return BlockVector2.at(x, z);
|
return BlockVector2.at(x, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final ChunkManager chunkManager;
|
|
||||||
|
|
||||||
public RegionManager(@Nonnull final ChunkManager chunkManager) {
|
|
||||||
this.chunkManager = chunkManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void largeRegionTask(final String world, final CuboidRegion region,
|
|
||||||
final RunnableVal<BlockVector2> task, final Runnable whenDone) {
|
|
||||||
TaskManager.runTaskAsync(() -> {
|
|
||||||
HashSet<BlockVector2> chunks = new HashSet<>();
|
|
||||||
Set<BlockVector2> mcrs = this.getChunkChunks(world);
|
|
||||||
for (BlockVector2 mcr : mcrs) {
|
|
||||||
int bx = mcr.getX() << 9;
|
|
||||||
int bz = mcr.getZ() << 9;
|
|
||||||
int tx = bx + 511;
|
|
||||||
int tz = bz + 511;
|
|
||||||
if (bx <= region.getMaximumPoint().getX() && tx >= region.getMinimumPoint().getX()
|
|
||||||
&& bz <= region.getMaximumPoint().getZ() && tz >= region.getMinimumPoint()
|
|
||||||
.getZ()) {
|
|
||||||
for (int x = bx >> 4; x <= (tx >> 4); x++) {
|
|
||||||
int cbx = x << 4;
|
|
||||||
int ctx = cbx + 15;
|
|
||||||
if (cbx <= region.getMaximumPoint().getX() && ctx >= region
|
|
||||||
.getMinimumPoint().getX()) {
|
|
||||||
for (int z = bz >> 4; z <= (tz >> 4); z++) {
|
|
||||||
int cbz = z << 4;
|
|
||||||
int ctz = cbz + 15;
|
|
||||||
if (cbz <= region.getMaximumPoint().getZ() && ctz >= region
|
|
||||||
.getMinimumPoint().getZ()) {
|
|
||||||
chunks.add(BlockVector2.at(x, z));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TaskManager.getPlatformImplementation().objectTask(chunks, new RunnableVal<BlockVector2>() {
|
|
||||||
@Override public void run(BlockVector2 value) {
|
|
||||||
chunkManager.loadChunk(world, value, false)
|
|
||||||
.thenRun(() -> task.run(value));
|
|
||||||
}
|
|
||||||
}).thenAccept(ignore ->
|
|
||||||
TaskManager.getPlatformImplementation().taskLater(whenDone, TaskTime.ticks(1L)));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 0 = Entity
|
* 0 = Entity
|
||||||
* 1 = Animal
|
* 1 = Animal
|
||||||
@ -112,48 +78,13 @@ public abstract class RegionManager {
|
|||||||
* 3 = Mob
|
* 3 = Mob
|
||||||
* 4 = Boat
|
* 4 = Boat
|
||||||
* 5 = Misc
|
* 5 = Misc
|
||||||
*
|
|
||||||
* @param plot
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
public abstract int[] countEntities(Plot plot);
|
public abstract int[] countEntities(Plot plot);
|
||||||
|
|
||||||
public Set<BlockVector2> getChunkChunks(String world) {
|
public void deleteRegionFiles(final String world, final Collection<BlockVector2> chunks, final Runnable whenDone) {
|
||||||
File folder =
|
|
||||||
new File(PlotSquared.platform().getWorldContainer(), world + File.separator + "region");
|
|
||||||
File[] regionFiles = folder.listFiles();
|
|
||||||
if (regionFiles == null) {
|
|
||||||
throw new RuntimeException(
|
|
||||||
"Could not find worlds folder: " + folder + " ? (no read access?)");
|
|
||||||
}
|
|
||||||
HashSet<BlockVector2> chunks = new HashSet<>();
|
|
||||||
for (File file : regionFiles) {
|
|
||||||
String name = file.getName();
|
|
||||||
if (name.endsWith("mca")) {
|
|
||||||
String[] split = name.split("\\.");
|
|
||||||
try {
|
|
||||||
int x = Integer.parseInt(split[1]);
|
|
||||||
int z = Integer.parseInt(split[2]);
|
|
||||||
BlockVector2 loc = BlockVector2.at(x, z);
|
|
||||||
chunks.add(loc);
|
|
||||||
} catch (NumberFormatException ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return chunks;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void deleteRegionFiles(String world, Collection<BlockVector2> chunks) {
|
|
||||||
deleteRegionFiles(world, chunks, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void deleteRegionFiles(final String world, final Collection<BlockVector2> chunks,
|
|
||||||
final Runnable whenDone) {
|
|
||||||
TaskManager.runTaskAsync(() -> {
|
TaskManager.runTaskAsync(() -> {
|
||||||
for (BlockVector2 loc : chunks) {
|
for (BlockVector2 loc : chunks) {
|
||||||
String directory =
|
String directory = world + File.separator + "region" + File.separator + "r." + loc.getX() + "." + loc.getZ() + ".mca";
|
||||||
world + File.separator + "region" + File.separator + "r." + loc.getX() + "."
|
|
||||||
+ loc.getZ() + ".mca";
|
|
||||||
File file = new File(PlotSquared.platform().getWorldContainer(), directory);
|
File file = new File(PlotSquared.platform().getWorldContainer(), directory);
|
||||||
logger.info("[P2] - Deleting file: {} (max 1024 chunks)", file.getName());
|
logger.info("[P2] - Deleting file: {} (max 1024 chunks)", file.getName());
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
@ -164,17 +95,30 @@ public abstract class RegionManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean setCuboids(final PlotArea area, final Set<CuboidRegion> regions,
|
/**
|
||||||
final Pattern blocks, int minY, int maxY) {
|
* Set a number of cuboids to a certain block between two y values.
|
||||||
LocalBlockQueue queue = area.getQueue(false);
|
*
|
||||||
|
* @param queue Nullable {@link QueueCoordinator}. If null, creates own queue and enqueues,
|
||||||
|
* otherwise writes to the queue but does not enqueue.
|
||||||
|
* @return true if not enqueued, otherwise whether the created queue enqueued.
|
||||||
|
*/
|
||||||
|
public boolean setCuboids(final PlotArea area,
|
||||||
|
final Set<CuboidRegion> regions,
|
||||||
|
final Pattern blocks,
|
||||||
|
int minY,
|
||||||
|
int maxY,
|
||||||
|
@Nullable QueueCoordinator queue) {
|
||||||
|
boolean enqueue = false;
|
||||||
|
if (queue == null) {
|
||||||
|
queue = area.getQueue();
|
||||||
|
enqueue = true;
|
||||||
|
}
|
||||||
for (CuboidRegion region : regions) {
|
for (CuboidRegion region : regions) {
|
||||||
Location pos1 = Location.at(area.getWorldName(), region.getMinimumPoint().getX(), minY,
|
Location pos1 = Location.at(area.getWorldName(), region.getMinimumPoint().getX(), minY, region.getMinimumPoint().getZ());
|
||||||
region.getMinimumPoint().getZ());
|
Location pos2 = Location.at(area.getWorldName(), region.getMaximumPoint().getX(), maxY, region.getMaximumPoint().getZ());
|
||||||
Location pos2 = Location.at(area.getWorldName(), region.getMaximumPoint().getX(), maxY,
|
|
||||||
region.getMaximumPoint().getZ());
|
|
||||||
queue.setCuboid(pos1, pos2, blocks);
|
queue.setCuboid(pos1, pos2, blocks);
|
||||||
}
|
}
|
||||||
return queue.enqueue();
|
return !enqueue || queue.enqueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -196,27 +140,113 @@ public abstract class RegionManager {
|
|||||||
/**
|
/**
|
||||||
* Copy a region to a new location (in the same world)
|
* Copy a region to a new location (in the same world)
|
||||||
*/
|
*/
|
||||||
public abstract boolean copyRegion(Location pos1, Location pos2, Location newPos,
|
public boolean copyRegion(final Location pos1, final Location pos2, final Location newPos, final Runnable whenDone) {
|
||||||
Runnable whenDone);
|
final int relX = newPos.getX() - pos1.getX();
|
||||||
|
final int relZ = newPos.getZ() - pos1.getZ();
|
||||||
|
final com.sk89q.worldedit.world.World oldWorld = worldUtil.getWeWorld(pos1.getWorldName());
|
||||||
|
final com.sk89q.worldedit.world.World newWorld = worldUtil.getWeWorld(newPos.getWorldName());
|
||||||
|
final QueueCoordinator copyFrom = blockQueue.getNewQueue(oldWorld);
|
||||||
|
final BasicQueueCoordinator copyTo = (BasicQueueCoordinator) blockQueue.getNewQueue(newWorld);
|
||||||
|
copyFromTo(pos1, pos2, relX, relZ, oldWorld, copyFrom, copyTo, false);
|
||||||
|
copyFrom.setCompleteTask(copyTo::enqueue);
|
||||||
|
copyFrom
|
||||||
|
.addReadChunks(new CuboidRegion(BlockVector3.at(pos1.getX(), 0, pos1.getZ()), BlockVector3.at(pos2.getX(), 0, pos2.getZ())).getChunks());
|
||||||
|
copyTo.setCompleteTask(whenDone);
|
||||||
|
copyFrom.enqueue();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assumptions:<br>
|
* Assumptions:<br>
|
||||||
* - pos1 and pos2 are in the same plot<br>
|
* - pos1 and pos2 are in the same plot<br>
|
||||||
* It can be harmful to the world if parameters outside this scope are provided
|
* It can be harmful to the world if parameters outside this scope are provided
|
||||||
*
|
|
||||||
* @param pos1
|
|
||||||
* @param pos2
|
|
||||||
* @param whenDone
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
public abstract boolean regenerateRegion(Location pos1, Location pos2, boolean ignoreAugment,
|
public abstract boolean regenerateRegion(Location pos1, Location pos2, boolean ignoreAugment, Runnable whenDone);
|
||||||
Runnable whenDone);
|
|
||||||
|
|
||||||
public abstract void clearAllEntities(Location pos1, Location pos2);
|
public abstract void clearAllEntities(Location pos1, Location pos2);
|
||||||
|
|
||||||
public abstract void swap(Location bot1, Location top1, Location bot2, Location top2,
|
public void swap(Location pos1, Location pos2, Location swapPos, final Runnable whenDone) {
|
||||||
Runnable whenDone);
|
int relX = swapPos.getX() - pos1.getX();
|
||||||
|
int relZ = swapPos.getZ() - pos1.getZ();
|
||||||
|
|
||||||
public abstract void setBiome(CuboidRegion region, int extendBiome, BiomeType biome,
|
World world1 = worldUtil.getWeWorld(pos1.getWorldName());
|
||||||
String world, Runnable whenDone);
|
World world2 = worldUtil.getWeWorld(swapPos.getWorldName());
|
||||||
|
|
||||||
|
QueueCoordinator fromQueue1 = blockQueue.getNewQueue(world1);
|
||||||
|
QueueCoordinator fromQueue2 = blockQueue.getNewQueue(world2);
|
||||||
|
fromQueue1.setUnloadAfter(false);
|
||||||
|
fromQueue2.setUnloadAfter(false);
|
||||||
|
fromQueue1.addReadChunks(new CuboidRegion(pos1.getBlockVector3(), pos2.getBlockVector3()).getChunks());
|
||||||
|
fromQueue2.addReadChunks(new CuboidRegion(swapPos.getBlockVector3(),
|
||||||
|
BlockVector3.at(swapPos.getX() + pos2.getX() - pos1.getX(), 0, swapPos.getZ() + pos2.getZ() - pos1.getZ())).getChunks());
|
||||||
|
QueueCoordinator toQueue1 = blockQueue.getNewQueue(world1);
|
||||||
|
QueueCoordinator toQueue2 = blockQueue.getNewQueue(world2);
|
||||||
|
|
||||||
|
copyFromTo(pos1, pos2, relX, relZ, world1, fromQueue1, toQueue2, true);
|
||||||
|
copyFromTo(pos1, pos2, relX, relZ, world1, fromQueue2, toQueue1, true);
|
||||||
|
fromQueue1.setCompleteTask(fromQueue2::enqueue);
|
||||||
|
fromQueue2.setCompleteTask(toQueue1::enqueue);
|
||||||
|
toQueue1.setCompleteTask(toQueue2::enqueue);
|
||||||
|
toQueue2.setCompleteTask(whenDone);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void copyFromTo(Location pos1,
|
||||||
|
Location pos2,
|
||||||
|
int relX,
|
||||||
|
int relZ,
|
||||||
|
World world1,
|
||||||
|
QueueCoordinator fromQueue,
|
||||||
|
QueueCoordinator toQueue,
|
||||||
|
boolean removeEntities) {
|
||||||
|
fromQueue.setChunkConsumer(chunk -> {
|
||||||
|
int cx = chunk.getX();
|
||||||
|
int cz = chunk.getZ();
|
||||||
|
int cbx = cx << 4;
|
||||||
|
int cbz = cz << 4;
|
||||||
|
int bx = Math.max(pos1.getX() & 15, 0);
|
||||||
|
int bz = Math.max(pos1.getZ() & 15, 0);
|
||||||
|
int tx = Math.min(pos2.getX() & 15, 15);
|
||||||
|
int tz = Math.min(pos2.getZ() & 15, 15);
|
||||||
|
for (int y = 0; y < 256; y++) {
|
||||||
|
for (int x = bx; x <= tx; x++) {
|
||||||
|
for (int z = bz; z <= tz; z++) {
|
||||||
|
int rx = cbx + x;
|
||||||
|
int rz = cbz + z;
|
||||||
|
BlockVector3 loc = BlockVector3.at(rx, y, rz);
|
||||||
|
toQueue.setBlock(rx + relX, y, rz + relZ, world1.getFullBlock(loc));
|
||||||
|
toQueue.setBiome(rx + relX, y, rz + relZ, world1.getBiome(loc));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Region region = new CuboidRegion(BlockVector3.at(cbx + bx, 0, cbz + bz), BlockVector3.at(cbx + tx, 255, cbz + tz));
|
||||||
|
toQueue.addEntities(world1.getEntities(region));
|
||||||
|
if (removeEntities) {
|
||||||
|
for (Entity entity : world1.getEntities(region)) {
|
||||||
|
entity.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBiome(final CuboidRegion region, final int extendBiome, final BiomeType biome, final String world, final Runnable whenDone) {
|
||||||
|
Location pos1 = Location
|
||||||
|
.at(world, region.getMinimumPoint().getX() - extendBiome, region.getMinimumPoint().getY(), region.getMinimumPoint().getZ() - extendBiome);
|
||||||
|
Location pos2 = Location
|
||||||
|
.at(world, region.getMaximumPoint().getX() + extendBiome, region.getMaximumPoint().getY(), region.getMaximumPoint().getZ() + extendBiome);
|
||||||
|
final QueueCoordinator queue = blockQueue.getNewQueue(worldUtil.getWeWorld(world));
|
||||||
|
|
||||||
|
final int minX = pos1.getX();
|
||||||
|
final int minZ = pos1.getZ();
|
||||||
|
final int maxX = pos2.getX();
|
||||||
|
final int maxZ = pos2.getZ();
|
||||||
|
queue.addReadChunks(region.getChunks());
|
||||||
|
queue.setChunkConsumer(blockVector2 -> {
|
||||||
|
final int cx = blockVector2.getX() << 4;
|
||||||
|
final int cz = blockVector2.getZ() << 4;
|
||||||
|
WorldUtil.setBiome(world, Math.max(minX, cx), Math.max(minZ, cz), Math.min(maxX, cx + 15), Math.min(maxZ, cz + 15), biome);
|
||||||
|
worldUtil.refreshChunk(blockVector2.getBlockX(), blockVector2.getBlockZ(), world);
|
||||||
|
});
|
||||||
|
queue.setCompleteTask(whenDone);
|
||||||
|
queue.enqueue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ import com.plotsquared.core.location.Location;
|
|||||||
import com.plotsquared.core.plot.Plot;
|
import com.plotsquared.core.plot.Plot;
|
||||||
import com.plotsquared.core.plot.PlotArea;
|
import com.plotsquared.core.plot.PlotArea;
|
||||||
import com.plotsquared.core.plot.schematic.Schematic;
|
import com.plotsquared.core.plot.schematic.Schematic;
|
||||||
import com.plotsquared.core.queue.LocalBlockQueue;
|
import com.plotsquared.core.queue.QueueCoordinator;
|
||||||
import com.plotsquared.core.util.net.AbstractDelegateOutputStream;
|
import com.plotsquared.core.util.net.AbstractDelegateOutputStream;
|
||||||
import com.plotsquared.core.util.task.RunnableVal;
|
import com.plotsquared.core.util.task.RunnableVal;
|
||||||
import com.plotsquared.core.util.task.TaskManager;
|
import com.plotsquared.core.util.task.TaskManager;
|
||||||
@ -107,17 +107,17 @@ public abstract class SchematicHandler {
|
|||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger("P2/" + SchematicHandler.class.getSimpleName());
|
private static final Logger logger = LoggerFactory.getLogger("P2/" + SchematicHandler.class.getSimpleName());
|
||||||
public static SchematicHandler manager;
|
public static SchematicHandler manager;
|
||||||
|
|
||||||
private boolean exportAll = false;
|
|
||||||
|
|
||||||
private final WorldUtil worldUtil;
|
private final WorldUtil worldUtil;
|
||||||
|
private boolean exportAll = false;
|
||||||
|
|
||||||
public SchematicHandler(@Nonnull final WorldUtil worldUtil) {
|
public SchematicHandler(@Nonnull final WorldUtil worldUtil) {
|
||||||
this.worldUtil = worldUtil;
|
this.worldUtil = worldUtil;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void upload(@Nullable UUID uuid, @Nullable final String file,
|
public static void upload(@Nullable UUID uuid,
|
||||||
@Nonnull final String extension, @Nullable final RunnableVal<OutputStream> writeTask,
|
@Nullable final String file,
|
||||||
|
@Nonnull final String extension,
|
||||||
|
@Nullable final RunnableVal<OutputStream> writeTask,
|
||||||
@Nonnull final RunnableVal<URL> whenDone) {
|
@Nonnull final RunnableVal<URL> whenDone) {
|
||||||
if (writeTask == null) {
|
if (writeTask == null) {
|
||||||
TaskManager.runTask(whenDone);
|
TaskManager.runTask(whenDone);
|
||||||
@ -148,23 +148,16 @@ public abstract class SchematicHandler {
|
|||||||
con.setDoOutput(true);
|
con.setDoOutput(true);
|
||||||
con.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
|
con.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
|
||||||
try (OutputStream output = con.getOutputStream();
|
try (OutputStream output = con.getOutputStream();
|
||||||
PrintWriter writer = new PrintWriter(
|
PrintWriter writer = new PrintWriter(new OutputStreamWriter(output, StandardCharsets.UTF_8), true)) {
|
||||||
new OutputStreamWriter(output, StandardCharsets.UTF_8), true)) {
|
|
||||||
String CRLF = "\r\n";
|
String CRLF = "\r\n";
|
||||||
writer.append("--" + boundary).append(CRLF);
|
writer.append("--" + boundary).append(CRLF);
|
||||||
writer.append("Content-Disposition: form-data; name=\"param\"").append(CRLF);
|
writer.append("Content-Disposition: form-data; name=\"param\"").append(CRLF);
|
||||||
writer.append(
|
writer.append("Content-Type: text/plain; charset=" + StandardCharsets.UTF_8.displayName()).append(CRLF);
|
||||||
"Content-Type: text/plain; charset=" + StandardCharsets.UTF_8.displayName())
|
|
||||||
.append(CRLF);
|
|
||||||
String param = "value";
|
String param = "value";
|
||||||
writer.append(CRLF).append(param).append(CRLF).flush();
|
writer.append(CRLF).append(param).append(CRLF).flush();
|
||||||
writer.append("--" + boundary).append(CRLF);
|
writer.append("--" + boundary).append(CRLF);
|
||||||
writer.append(
|
writer.append("Content-Disposition: form-data; name=\"schematicFile\"; filename=\"" + filename + '"').append(CRLF);
|
||||||
"Content-Disposition: form-data; name=\"schematicFile\"; filename=\""
|
writer.append("Content-Type: " + URLConnection.guessContentTypeFromName(filename)).append(CRLF);
|
||||||
+ filename + '"').append(CRLF);
|
|
||||||
writer
|
|
||||||
.append("Content-Type: " + URLConnection.guessContentTypeFromName(filename))
|
|
||||||
.append(CRLF);
|
|
||||||
writer.append("Content-Transfer-Encoding: binary").append(CRLF);
|
writer.append("Content-Transfer-Encoding: binary").append(CRLF);
|
||||||
writer.append(CRLF).flush();
|
writer.append(CRLF).flush();
|
||||||
writeTask.value = new AbstractDelegateOutputStream(output) {
|
writeTask.value = new AbstractDelegateOutputStream(output) {
|
||||||
@ -194,8 +187,7 @@ public abstract class SchematicHandler {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean exportAll(Collection<Plot> collection, final File outputDir,
|
public boolean exportAll(Collection<Plot> collection, final File outputDir, final String namingScheme, final Runnable ifSuccess) {
|
||||||
final String namingScheme, final Runnable ifSuccess) {
|
|
||||||
if (this.exportAll) {
|
if (this.exportAll) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -224,13 +216,10 @@ public abstract class SchematicHandler {
|
|||||||
|
|
||||||
final String name;
|
final String name;
|
||||||
if (namingScheme == null) {
|
if (namingScheme == null) {
|
||||||
name =
|
name = plot.getId().getX() + ";" + plot.getId().getY() + ',' + plot.getArea() + ',' + owner;
|
||||||
plot.getId().getX() + ";" + plot.getId().getY() + ',' + plot.getArea() + ',' + owner;
|
|
||||||
} else {
|
} else {
|
||||||
name = namingScheme.replaceAll("%id%", plot.getId().toString())
|
name = namingScheme.replaceAll("%id%", plot.getId().toString()).replaceAll("%idx%", plot.getId().getX() + "")
|
||||||
.replaceAll("%idx%", plot.getId().getX() + "")
|
.replaceAll("%idy%", plot.getId().getY() + "").replaceAll("%world%", plot.getArea().toString());
|
||||||
.replaceAll("%idy%", plot.getId().getY() + "")
|
|
||||||
.replaceAll("%world%", plot.getArea().toString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final String directory;
|
final String directory;
|
||||||
@ -267,8 +256,12 @@ public abstract class SchematicHandler {
|
|||||||
* @param xOffset offset x to paste it from plot origin
|
* @param xOffset offset x to paste it from plot origin
|
||||||
* @param zOffset offset z to paste it from plot origin
|
* @param zOffset offset z to paste it from plot origin
|
||||||
*/
|
*/
|
||||||
public void paste(final Schematic schematic, final Plot plot, final int xOffset,
|
public void paste(final Schematic schematic,
|
||||||
final int yOffset, final int zOffset, final boolean autoHeight,
|
final Plot plot,
|
||||||
|
final int xOffset,
|
||||||
|
final int yOffset,
|
||||||
|
final int zOffset,
|
||||||
|
final boolean autoHeight,
|
||||||
final RunnableVal<Boolean> whenDone) {
|
final RunnableVal<Boolean> whenDone) {
|
||||||
|
|
||||||
TaskManager.runTask(() -> {
|
TaskManager.runTask(() -> {
|
||||||
@ -280,17 +273,14 @@ public abstract class SchematicHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
final LocalBlockQueue queue = plot.getArea().getQueue(false);
|
|
||||||
BlockVector3 dimension = schematic.getClipboard().getDimensions();
|
BlockVector3 dimension = schematic.getClipboard().getDimensions();
|
||||||
final int WIDTH = dimension.getX();
|
final int WIDTH = dimension.getX();
|
||||||
final int LENGTH = dimension.getZ();
|
final int LENGTH = dimension.getZ();
|
||||||
final int HEIGHT = dimension.getY();
|
final int HEIGHT = dimension.getY();
|
||||||
// Validate dimensions
|
// Validate dimensions
|
||||||
CuboidRegion region = plot.getLargestRegion();
|
CuboidRegion region = plot.getLargestRegion();
|
||||||
if (((region.getMaximumPoint().getX() - region.getMinimumPoint().getX() + xOffset
|
if (((region.getMaximumPoint().getX() - region.getMinimumPoint().getX() + xOffset + 1) < WIDTH) || (
|
||||||
+ 1) < WIDTH) || (
|
(region.getMaximumPoint().getZ() - region.getMinimumPoint().getZ() + zOffset + 1) < LENGTH) || (HEIGHT > 256)) {
|
||||||
(region.getMaximumPoint().getZ() - region.getMinimumPoint().getZ() + zOffset
|
|
||||||
+ 1) < LENGTH) || (HEIGHT > 256)) {
|
|
||||||
TaskManager.runTask(whenDone);
|
TaskManager.runTask(whenDone);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -307,8 +297,7 @@ public abstract class SchematicHandler {
|
|||||||
y_offset_actual = yOffset + ((ClassicPlotWorld) pw).PLOT_HEIGHT;
|
y_offset_actual = yOffset + ((ClassicPlotWorld) pw).PLOT_HEIGHT;
|
||||||
} else {
|
} else {
|
||||||
y_offset_actual = yOffset + 1 + this.worldUtil
|
y_offset_actual = yOffset + 1 + this.worldUtil
|
||||||
.getHighestBlockSynchronous(plot.getWorldName(),
|
.getHighestBlockSynchronous(plot.getWorldName(), region.getMinimumPoint().getX() + 1,
|
||||||
region.getMinimumPoint().getX() + 1,
|
|
||||||
region.getMinimumPoint().getZ() + 1);
|
region.getMinimumPoint().getZ() + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -316,8 +305,8 @@ public abstract class SchematicHandler {
|
|||||||
y_offset_actual = yOffset;
|
y_offset_actual = yOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
final Location pos1 = Location.at(plot.getWorldName(), region.getMinimumPoint().getX() + xOffset, y_offset_actual,
|
final Location pos1 = Location
|
||||||
region.getMinimumPoint().getZ() + zOffset);
|
.at(plot.getWorldName(), region.getMinimumPoint().getX() + xOffset, y_offset_actual, region.getMinimumPoint().getZ() + zOffset);
|
||||||
final Location pos2 = pos1.add(WIDTH - 1, HEIGHT - 1, LENGTH - 1);
|
final Location pos2 = pos1.add(WIDTH - 1, HEIGHT - 1, LENGTH - 1);
|
||||||
|
|
||||||
final int p1x = pos1.getX();
|
final int p1x = pos1.getX();
|
||||||
@ -328,58 +317,32 @@ public abstract class SchematicHandler {
|
|||||||
final int bcz = p1z >> 4;
|
final int bcz = p1z >> 4;
|
||||||
final int tcx = p2x >> 4;
|
final int tcx = p2x >> 4;
|
||||||
final int tcz = p2z >> 4;
|
final int tcz = p2z >> 4;
|
||||||
|
|
||||||
ChunkManager.chunkTask(pos1, pos2, new RunnableVal<int[]>() {
|
|
||||||
@Override public void run(int[] value) {
|
|
||||||
BlockVector2 chunk = BlockVector2.at(value[0], value[1]);
|
|
||||||
int x = chunk.getX();
|
|
||||||
int z = chunk.getZ();
|
|
||||||
int xxb = x << 4;
|
|
||||||
int zzb = z << 4;
|
|
||||||
int xxt = xxb + 15;
|
|
||||||
int zzt = zzb + 15;
|
|
||||||
if (x == bcx) {
|
|
||||||
xxb = p1x;
|
|
||||||
}
|
|
||||||
if (x == tcx) {
|
|
||||||
xxt = p2x;
|
|
||||||
}
|
|
||||||
if (z == bcz) {
|
|
||||||
zzb = p1z;
|
|
||||||
}
|
|
||||||
if (z == tcz) {
|
|
||||||
zzt = p2z;
|
|
||||||
}
|
|
||||||
// Paste schematic here
|
// Paste schematic here
|
||||||
|
final QueueCoordinator queue = plot.getArea().getQueue();
|
||||||
|
|
||||||
for (int ry = 0; ry < Math.min(256, HEIGHT); ry++) {
|
for (int ry = 0; ry < Math.min(256, HEIGHT); ry++) {
|
||||||
int yy = y_offset_actual + ry;
|
int yy = y_offset_actual + ry;
|
||||||
if (yy > 255) {
|
if (yy > 255) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (int rz = zzb - p1z; rz <= (zzt - p1z); rz++) {
|
for (int rz = 0; rz <= blockArrayClipboard.getDimensions().getZ(); rz++) {
|
||||||
for (int rx = xxb - p1x; rx <= (xxt - p1x); rx++) {
|
for (int rx = 0; rx < blockArrayClipboard.getDimensions().getX(); rx++) {
|
||||||
int xx = p1x + xOffset + rx;
|
int xx = p1x + xOffset + rx;
|
||||||
int zz = p1z + zOffset + rz;
|
int zz = p1z + zOffset + rz;
|
||||||
BaseBlock id = blockArrayClipboard
|
BaseBlock id = blockArrayClipboard.getFullBlock(BlockVector3.at(rx, ry, rz));
|
||||||
.getFullBlock(BlockVector3.at(rx, ry, rz));
|
|
||||||
queue.setBlock(xx, yy, zz, id);
|
queue.setBlock(xx, yy, zz, id);
|
||||||
if (ry == 0) {
|
if (ry == 0) {
|
||||||
BiomeType biome =
|
BiomeType biome = blockArrayClipboard.getBiome(BlockVector3.at(rx, ry, rz));
|
||||||
blockArrayClipboard.getBiome(BlockVector2.at(rx, rz));
|
queue.setBiome(xx, yy, zz, biome);
|
||||||
queue.setBiome(xx, zz, biome);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
queue.enqueue();
|
|
||||||
}
|
|
||||||
}, () -> {
|
|
||||||
if (whenDone != null) {
|
if (whenDone != null) {
|
||||||
whenDone.value = true;
|
whenDone.value = true;
|
||||||
whenDone.run();
|
|
||||||
}
|
}
|
||||||
}, 10);
|
queue.setCompleteTask(whenDone);
|
||||||
|
queue.enqueue();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
TaskManager.runTask(whenDone);
|
TaskManager.runTask(whenDone);
|
||||||
@ -387,8 +350,7 @@ public abstract class SchematicHandler {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract boolean restoreTile(LocalBlockQueue queue, CompoundTag tag, int x, int y,
|
public abstract boolean restoreTile(QueueCoordinator queue, CompoundTag tag, int x, int y, int z);
|
||||||
int z);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a schematic
|
* Get a schematic
|
||||||
@ -397,8 +359,7 @@ public abstract class SchematicHandler {
|
|||||||
* @return schematic if found, else null
|
* @return schematic if found, else null
|
||||||
*/
|
*/
|
||||||
public Schematic getSchematic(String name) throws UnsupportedFormatException {
|
public Schematic getSchematic(String name) throws UnsupportedFormatException {
|
||||||
File parent =
|
File parent = FileUtils.getFile(PlotSquared.platform().getDirectory(), Settings.Paths.SCHEMATICS);
|
||||||
FileUtils.getFile(PlotSquared.platform().getDirectory(), Settings.Paths.SCHEMATICS);
|
|
||||||
if (!parent.exists()) {
|
if (!parent.exists()) {
|
||||||
if (!parent.mkdir()) {
|
if (!parent.mkdir()) {
|
||||||
throw new RuntimeException("Could not create schematic parent directory");
|
throw new RuntimeException("Could not create schematic parent directory");
|
||||||
@ -407,11 +368,9 @@ public abstract class SchematicHandler {
|
|||||||
if (!name.endsWith(".schem") && !name.endsWith(".schematic")) {
|
if (!name.endsWith(".schem") && !name.endsWith(".schematic")) {
|
||||||
name = name + ".schem";
|
name = name + ".schem";
|
||||||
}
|
}
|
||||||
File file = FileUtils.getFile(PlotSquared.platform().getDirectory(),
|
File file = FileUtils.getFile(PlotSquared.platform().getDirectory(), Settings.Paths.SCHEMATICS + File.separator + name);
|
||||||
Settings.Paths.SCHEMATICS + File.separator + name);
|
|
||||||
if (!file.exists()) {
|
if (!file.exists()) {
|
||||||
file = FileUtils.getFile(PlotSquared.platform().getDirectory(),
|
file = FileUtils.getFile(PlotSquared.platform().getDirectory(), Settings.Paths.SCHEMATICS + File.separator + name);
|
||||||
Settings.Paths.SCHEMATICS + File.separator + name);
|
|
||||||
}
|
}
|
||||||
return getSchematic(file);
|
return getSchematic(file);
|
||||||
}
|
}
|
||||||
@ -422,12 +381,10 @@ public abstract class SchematicHandler {
|
|||||||
* @return Immutable collection with schematic names
|
* @return Immutable collection with schematic names
|
||||||
*/
|
*/
|
||||||
public Collection<String> getSchematicNames() {
|
public Collection<String> getSchematicNames() {
|
||||||
final File parent =
|
final File parent = FileUtils.getFile(PlotSquared.platform().getDirectory(), Settings.Paths.SCHEMATICS);
|
||||||
FileUtils.getFile(PlotSquared.platform().getDirectory(), Settings.Paths.SCHEMATICS);
|
|
||||||
final List<String> names = new ArrayList<>();
|
final List<String> names = new ArrayList<>();
|
||||||
if (parent.exists()) {
|
if (parent.exists()) {
|
||||||
final String[] rawNames =
|
final String[] rawNames = parent.list((dir, name) -> name.endsWith(".schematic") || name.endsWith(".schem"));
|
||||||
parent.list((dir, name) -> name.endsWith(".schematic") || name.endsWith(".schem"));
|
|
||||||
if (rawNames != null) {
|
if (rawNames != null) {
|
||||||
final List<String> transformed = Arrays.stream(rawNames)
|
final List<String> transformed = Arrays.stream(rawNames)
|
||||||
//.map(rawName -> rawName.substring(0, rawName.length() - 10))
|
//.map(rawName -> rawName.substring(0, rawName.length() - 10))
|
||||||
@ -457,8 +414,7 @@ public abstract class SchematicHandler {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new UnsupportedFormatException(
|
throw new UnsupportedFormatException("This schematic format is not recognised or supported.");
|
||||||
"This schematic format is not recognised or supported.");
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -476,14 +432,12 @@ public abstract class SchematicHandler {
|
|||||||
|
|
||||||
public Schematic getSchematic(@Nonnull InputStream is) {
|
public Schematic getSchematic(@Nonnull InputStream is) {
|
||||||
try {
|
try {
|
||||||
SpongeSchematicReader schematicReader =
|
SpongeSchematicReader schematicReader = new SpongeSchematicReader(new NBTInputStream(new GZIPInputStream(is)));
|
||||||
new SpongeSchematicReader(new NBTInputStream(new GZIPInputStream(is)));
|
|
||||||
Clipboard clip = schematicReader.read();
|
Clipboard clip = schematicReader.read();
|
||||||
return new Schematic(clip);
|
return new Schematic(clip);
|
||||||
} catch (IOException ignored) {
|
} catch (IOException ignored) {
|
||||||
try {
|
try {
|
||||||
MCEditSchematicReader schematicReader =
|
MCEditSchematicReader schematicReader = new MCEditSchematicReader(new NBTInputStream(new GZIPInputStream(is)));
|
||||||
new MCEditSchematicReader(new NBTInputStream(new GZIPInputStream(is)));
|
|
||||||
Clipboard clip = schematicReader.read();
|
Clipboard clip = schematicReader.read();
|
||||||
return new Schematic(clip);
|
return new Schematic(clip);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@ -500,8 +454,7 @@ public abstract class SchematicHandler {
|
|||||||
URL url = new URL(website);
|
URL url = new URL(website);
|
||||||
URLConnection connection = new URL(url.toString()).openConnection();
|
URLConnection connection = new URL(url.toString()).openConnection();
|
||||||
connection.setRequestProperty("User-Agent", "Mozilla/5.0");
|
connection.setRequestProperty("User-Agent", "Mozilla/5.0");
|
||||||
try (BufferedReader reader = new BufferedReader(
|
try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
|
||||||
new InputStreamReader(connection.getInputStream()))) {
|
|
||||||
rawJSON = reader.lines().collect(Collectors.joining());
|
rawJSON = reader.lines().collect(Collectors.joining());
|
||||||
}
|
}
|
||||||
JSONArray array = new JSONArray(rawJSON);
|
JSONArray array = new JSONArray(rawJSON);
|
||||||
@ -524,8 +477,7 @@ public abstract class SchematicHandler {
|
|||||||
}
|
}
|
||||||
upload(uuid, file, "schem", new RunnableVal<OutputStream>() {
|
upload(uuid, file, "schem", new RunnableVal<OutputStream>() {
|
||||||
@Override public void run(OutputStream output) {
|
@Override public void run(OutputStream output) {
|
||||||
try (NBTOutputStream nos = new NBTOutputStream(
|
try (NBTOutputStream nos = new NBTOutputStream(new GZIPOutputStream(output, true))) {
|
||||||
new GZIPOutputStream(output, true))) {
|
|
||||||
nos.writeNamedTag("Schematic", tag);
|
nos.writeNamedTag("Schematic", tag);
|
||||||
} catch (IOException e1) {
|
} catch (IOException e1) {
|
||||||
e1.printStackTrace();
|
e1.printStackTrace();
|
||||||
@ -548,8 +500,7 @@ public abstract class SchematicHandler {
|
|||||||
try {
|
try {
|
||||||
File tmp = FileUtils.getFile(PlotSquared.platform().getDirectory(), path);
|
File tmp = FileUtils.getFile(PlotSquared.platform().getDirectory(), path);
|
||||||
tmp.getParentFile().mkdirs();
|
tmp.getParentFile().mkdirs();
|
||||||
try (NBTOutputStream nbtStream = new NBTOutputStream(
|
try (NBTOutputStream nbtStream = new NBTOutputStream(new GZIPOutputStream(new FileOutputStream(tmp)))) {
|
||||||
new GZIPOutputStream(new FileOutputStream(tmp)))) {
|
|
||||||
nbtStream.writeNamedTag("Schematic", tag);
|
nbtStream.writeNamedTag("Schematic", tag);
|
||||||
}
|
}
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
@ -561,8 +512,7 @@ public abstract class SchematicHandler {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void getCompoundTag(final String world, final Set<CuboidRegion> regions,
|
public void getCompoundTag(final String world, final Set<CuboidRegion> regions, final RunnableVal<CompoundTag> whenDone) {
|
||||||
final RunnableVal<CompoundTag> whenDone) {
|
|
||||||
// async
|
// async
|
||||||
TaskManager.runTaskAsync(() -> {
|
TaskManager.runTaskAsync(() -> {
|
||||||
// Main positions
|
// Main positions
|
||||||
@ -570,17 +520,15 @@ public abstract class SchematicHandler {
|
|||||||
final Location bot = corners[0];
|
final Location bot = corners[0];
|
||||||
final Location top = corners[1];
|
final Location top = corners[1];
|
||||||
|
|
||||||
CuboidRegion cuboidRegion =
|
CuboidRegion cuboidRegion = new CuboidRegion(this.worldUtil.getWeWorld(world), bot.getBlockVector3(), top.getBlockVector3());
|
||||||
new CuboidRegion(this.worldUtil.getWeWorld(world), bot.getBlockVector3(),
|
|
||||||
top.getBlockVector3());
|
|
||||||
|
|
||||||
final int width = cuboidRegion.getWidth();
|
final int width = cuboidRegion.getWidth();
|
||||||
int height = cuboidRegion.getHeight();
|
int height = cuboidRegion.getHeight();
|
||||||
final int length = cuboidRegion.getLength();
|
final int length = cuboidRegion.getLength();
|
||||||
Map<String, Tag> schematic = new HashMap<>();
|
Map<String, Tag> schematic = new HashMap<>();
|
||||||
schematic.put("Version", new IntTag(2));
|
schematic.put("Version", new IntTag(2));
|
||||||
schematic.put("DataVersion", new IntTag(WorldEdit.getInstance().getPlatformManager()
|
schematic.put("DataVersion",
|
||||||
.queryCapability(Capability.WORLD_EDITING).getDataVersion()));
|
new IntTag(WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING).getDataVersion()));
|
||||||
|
|
||||||
Map<String, Tag> metadata = new HashMap<>();
|
Map<String, Tag> metadata = new HashMap<>();
|
||||||
metadata.put("WEOffsetX", new IntTag(0));
|
metadata.put("WEOffsetX", new IntTag(0));
|
||||||
@ -615,14 +563,12 @@ public abstract class SchematicHandler {
|
|||||||
|
|
||||||
schematic.put("Palette", new CompoundTag(paletteTag));
|
schematic.put("Palette", new CompoundTag(paletteTag));
|
||||||
schematic.put("BlockData", new ByteArrayTag(buffer.toByteArray()));
|
schematic.put("BlockData", new ByteArrayTag(buffer.toByteArray()));
|
||||||
schematic
|
schematic.put("TileEntities", new ListTag(CompoundTag.class, tileEntities));
|
||||||
.put("TileEntities", new ListTag(CompoundTag.class, tileEntities));
|
|
||||||
|
|
||||||
schematic.put("BiomePaletteMax", new IntTag(biomePalette.size()));
|
schematic.put("BiomePaletteMax", new IntTag(biomePalette.size()));
|
||||||
|
|
||||||
Map<String, Tag> biomePaletteTag = new HashMap<>();
|
Map<String, Tag> biomePaletteTag = new HashMap<>();
|
||||||
biomePalette.forEach(
|
biomePalette.forEach((key, value) -> biomePaletteTag.put(key, new IntTag(value)));
|
||||||
(key, value) -> biomePaletteTag.put(key, new IntTag(value)));
|
|
||||||
|
|
||||||
schematic.put("BiomePalette", new CompoundTag(biomePaletteTag));
|
schematic.put("BiomePalette", new CompoundTag(biomePaletteTag));
|
||||||
schematic.put("BiomeData", new ByteArrayTag(biomeBuffer.toByteArray()));
|
schematic.put("BiomeData", new ByteArrayTag(biomeBuffer.toByteArray()));
|
||||||
@ -653,33 +599,23 @@ public abstract class SchematicHandler {
|
|||||||
final Runnable zTask = new Runnable() {
|
final Runnable zTask = new Runnable() {
|
||||||
@Override public void run() {
|
@Override public void run() {
|
||||||
long zstart = System.currentTimeMillis();
|
long zstart = System.currentTimeMillis();
|
||||||
while (ziter.hasNext()
|
while (ziter.hasNext() && System.currentTimeMillis() - zstart < 20) {
|
||||||
&& System.currentTimeMillis() - zstart < 20) {
|
|
||||||
final int z = ziter.next();
|
final int z = ziter.next();
|
||||||
Iterator<Integer> xiter =
|
Iterator<Integer> xiter = IntStream.range(p1x, p2x + 1).iterator();
|
||||||
IntStream.range(p1x, p2x + 1).iterator();
|
|
||||||
final Runnable xTask = new Runnable() {
|
final Runnable xTask = new Runnable() {
|
||||||
@Override public void run() {
|
@Override public void run() {
|
||||||
long xstart = System.currentTimeMillis();
|
long xstart = System.currentTimeMillis();
|
||||||
final int ry = y - sy;
|
final int ry = y - sy;
|
||||||
final int rz = z - p1z;
|
final int rz = z - p1z;
|
||||||
while (xiter.hasNext()
|
while (xiter.hasNext() && System.currentTimeMillis() - xstart < 20) {
|
||||||
&& System.currentTimeMillis() - xstart
|
|
||||||
< 20) {
|
|
||||||
final int x = xiter.next();
|
final int x = xiter.next();
|
||||||
final int rx = x - p1x;
|
final int rx = x - p1x;
|
||||||
BlockVector3 point =
|
BlockVector3 point = BlockVector3.at(x, y, z);
|
||||||
BlockVector3.at(x, y, z);
|
BaseBlock block = cuboidRegion.getWorld().getFullBlock(point);
|
||||||
BaseBlock block = cuboidRegion.getWorld()
|
|
||||||
.getFullBlock(point);
|
|
||||||
if (block.getNbtData() != null) {
|
if (block.getNbtData() != null) {
|
||||||
Map<String, Tag> values =
|
Map<String, Tag> values = new HashMap<>();
|
||||||
new HashMap<>();
|
for (Map.Entry<String, Tag> entry : block.getNbtData().getValue().entrySet()) {
|
||||||
for (Map.Entry<String, Tag> entry : block
|
values.put(entry.getKey(), entry.getValue());
|
||||||
.getNbtData().getValue()
|
|
||||||
.entrySet()) {
|
|
||||||
values.put(entry.getKey(),
|
|
||||||
entry.getValue());
|
|
||||||
}
|
}
|
||||||
// Remove 'id' if it exists. We want 'Id'
|
// Remove 'id' if it exists. We want 'Id'
|
||||||
values.remove("id");
|
values.remove("id");
|
||||||
@ -689,16 +625,12 @@ public abstract class SchematicHandler {
|
|||||||
values.remove("y");
|
values.remove("y");
|
||||||
values.remove("z");
|
values.remove("z");
|
||||||
|
|
||||||
values.put("Id",
|
values.put("Id", new StringTag(block.getNbtId()));
|
||||||
new StringTag(block.getNbtId()));
|
values.put("Pos", new IntArrayTag(new int[] {rx, ry, rz}));
|
||||||
values.put("Pos", new IntArrayTag(
|
|
||||||
new int[] {rx, ry, rz}));
|
|
||||||
|
|
||||||
tileEntities
|
tileEntities.add(new CompoundTag(values));
|
||||||
.add(new CompoundTag(values));
|
|
||||||
}
|
}
|
||||||
String blockKey =
|
String blockKey = block.toImmutableState().getAsString();
|
||||||
block.toImmutableState().getAsString();
|
|
||||||
int blockId;
|
int blockId;
|
||||||
if (palette.containsKey(blockKey)) {
|
if (palette.containsKey(blockKey)) {
|
||||||
blockId = palette.get(blockKey);
|
blockId = palette.get(blockKey);
|
||||||
@ -717,8 +649,7 @@ public abstract class SchematicHandler {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
BlockVector2 pt = BlockVector2.at(x, z);
|
BlockVector2 pt = BlockVector2.at(x, z);
|
||||||
BiomeType biome =
|
BiomeType biome = cuboidRegion.getWorld().getBiome(pt);
|
||||||
cuboidRegion.getWorld().getBiome(pt);
|
|
||||||
String biomeStr = biome.getId();
|
String biomeStr = biome.getId();
|
||||||
int biomeId;
|
int biomeId;
|
||||||
if (biomePalette.containsKey(biomeStr)) {
|
if (biomePalette.containsKey(biomeStr)) {
|
||||||
|
@ -56,6 +56,7 @@ import java.io.IOException;
|
|||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@ -68,12 +69,6 @@ import java.util.zip.ZipOutputStream;
|
|||||||
|
|
||||||
public abstract class WorldUtil {
|
public abstract class WorldUtil {
|
||||||
|
|
||||||
private final RegionManager regionManager;
|
|
||||||
|
|
||||||
public WorldUtil(@Nonnull final RegionManager regionManager) {
|
|
||||||
this.regionManager = regionManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the biome in a region
|
* Set the biome in a region
|
||||||
*
|
*
|
||||||
@ -135,8 +130,7 @@ public abstract class WorldUtil {
|
|||||||
* @param name Block name
|
* @param name Block name
|
||||||
* @return Comparison result containing the closets matching block
|
* @return Comparison result containing the closets matching block
|
||||||
*/
|
*/
|
||||||
@Nonnull public abstract StringComparison<BlockState>.ComparisonResult getClosestBlock(
|
@Nonnull public abstract StringComparison<BlockState>.ComparisonResult getClosestBlock(@Nonnull String name);
|
||||||
@Nonnull String name);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the block at the specified location to a sign, with given text
|
* Set the block at the specified location to a sign, with given text
|
||||||
@ -156,8 +150,7 @@ public abstract class WorldUtil {
|
|||||||
* @param z Chunk Z coordinate
|
* @param z Chunk Z coordinate
|
||||||
* @param result Result consumer
|
* @param result Result consumer
|
||||||
*/
|
*/
|
||||||
public abstract void getBiome(@Nonnull String world, int x, int z,
|
public abstract void getBiome(@Nonnull String world, int x, int z, @Nonnull Consumer<BiomeType> result);
|
||||||
@Nonnull Consumer<BiomeType> result);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the biome in a given chunk, asynchronously
|
* Get the biome in a given chunk, asynchronously
|
||||||
@ -168,8 +161,7 @@ public abstract class WorldUtil {
|
|||||||
* @return Biome
|
* @return Biome
|
||||||
* @deprecated Use {@link #getBiome(String, int, int, Consumer)}
|
* @deprecated Use {@link #getBiome(String, int, int, Consumer)}
|
||||||
*/
|
*/
|
||||||
@Deprecated @Nonnull public abstract BiomeType getBiomeSynchronous(@Nonnull String world, int x,
|
@Deprecated @Nonnull public abstract BiomeType getBiomeSynchronous(@Nonnull String world, int x, int z);
|
||||||
int z);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the block at a given location (asynchronously)
|
* Get the block at a given location (asynchronously)
|
||||||
@ -196,8 +188,7 @@ public abstract class WorldUtil {
|
|||||||
* @param z Z coordinate
|
* @param z Z coordinate
|
||||||
* @param result Result consumer
|
* @param result Result consumer
|
||||||
*/
|
*/
|
||||||
public abstract void getHighestBlock(@Nonnull String world, int x, int z,
|
public abstract void getHighestBlock(@Nonnull String world, int x, int z, @Nonnull IntConsumer result);
|
||||||
@Nonnull IntConsumer result);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -209,8 +200,7 @@ public abstract class WorldUtil {
|
|||||||
* @return Result
|
* @return Result
|
||||||
* @deprecated Use {@link #getHighestBlock(String, int, int, IntConsumer)}
|
* @deprecated Use {@link #getHighestBlock(String, int, int, IntConsumer)}
|
||||||
*/
|
*/
|
||||||
@Deprecated @Nonnegative
|
@Deprecated @Nonnegative public abstract int getHighestBlockSynchronous(@Nonnull String world, int x, int z);
|
||||||
public abstract int getHighestBlockSynchronous(@Nonnull String world, int x, int z);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the biome in a region
|
* Set the biome in a region
|
||||||
@ -219,8 +209,7 @@ public abstract class WorldUtil {
|
|||||||
* @param region Region
|
* @param region Region
|
||||||
* @param biome New biome
|
* @param biome New biome
|
||||||
*/
|
*/
|
||||||
public abstract void setBiomes(@Nonnull String world, @Nonnull CuboidRegion region,
|
public abstract void setBiomes(@Nonnull String world, @Nonnull CuboidRegion region, @Nonnull BiomeType biome);
|
||||||
@Nonnull BiomeType biome);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the WorldEdit {@link com.sk89q.worldedit.world.World} corresponding to a world name
|
* Get the WorldEdit {@link com.sk89q.worldedit.world.World} corresponding to a world name
|
||||||
@ -230,8 +219,16 @@ public abstract class WorldUtil {
|
|||||||
*/
|
*/
|
||||||
@Nonnull public abstract com.sk89q.worldedit.world.World getWeWorld(@Nonnull String world);
|
@Nonnull public abstract com.sk89q.worldedit.world.World getWeWorld(@Nonnull String world);
|
||||||
|
|
||||||
public void upload(@Nonnull final Plot plot, @Nullable final UUID uuid,
|
/**
|
||||||
@Nullable final String file, @Nonnull final RunnableVal<URL> whenDone) {
|
* Refresh (resend) chunk to player. Usually after setting the biome
|
||||||
|
*
|
||||||
|
* @param x Chunk x location
|
||||||
|
* @param z Chunk z location
|
||||||
|
* @param world World of the chunk
|
||||||
|
*/
|
||||||
|
public abstract void refreshChunk(int x, int z, String world);
|
||||||
|
|
||||||
|
public void upload(@Nonnull final Plot plot, @Nullable final UUID uuid, @Nullable final String file, @Nonnull final RunnableVal<URL> whenDone) {
|
||||||
plot.getHome(home -> SchematicHandler.upload(uuid, file, "zip", new RunnableVal<OutputStream>() {
|
plot.getHome(home -> SchematicHandler.upload(uuid, file, "zip", new RunnableVal<OutputStream>() {
|
||||||
@Override public void run(OutputStream output) {
|
@Override public void run(OutputStream output) {
|
||||||
try (final ZipOutputStream zos = new ZipOutputStream(output)) {
|
try (final ZipOutputStream zos = new ZipOutputStream(output)) {
|
||||||
@ -240,8 +237,7 @@ public abstract class WorldUtil {
|
|||||||
if (dat != null) {
|
if (dat != null) {
|
||||||
ZipEntry ze = new ZipEntry("world" + File.separator + dat.getName());
|
ZipEntry ze = new ZipEntry("world" + File.separator + dat.getName());
|
||||||
zos.putNextEntry(ze);
|
zos.putNextEntry(ze);
|
||||||
try (NBTInputStream nis = new NBTInputStream(
|
try (NBTInputStream nis = new NBTInputStream(new GZIPInputStream(new FileInputStream(dat)))) {
|
||||||
new GZIPInputStream(new FileInputStream(dat)))) {
|
|
||||||
CompoundTag tag = (CompoundTag) nis.readNamedTag().getTag();
|
CompoundTag tag = (CompoundTag) nis.readNamedTag().getTag();
|
||||||
CompoundTag data = (CompoundTag) tag.getValue().get("Data");
|
CompoundTag data = (CompoundTag) tag.getValue().get("Data");
|
||||||
Map<String, Tag> map = ReflectionUtils.getMap(data.getValue());
|
Map<String, Tag> map = ReflectionUtils.getMap(data.getValue());
|
||||||
@ -249,8 +245,7 @@ public abstract class WorldUtil {
|
|||||||
map.put("SpawnY", new IntTag(home.getY()));
|
map.put("SpawnY", new IntTag(home.getY()));
|
||||||
map.put("SpawnZ", new IntTag(home.getZ()));
|
map.put("SpawnZ", new IntTag(home.getZ()));
|
||||||
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
|
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
|
||||||
try (NBTOutputStream out = new NBTOutputStream(
|
try (NBTOutputStream out = new NBTOutputStream(new GZIPOutputStream(baos, true))) {
|
||||||
new GZIPOutputStream(baos, true))) {
|
|
||||||
//TODO Find what this should be called
|
//TODO Find what this should be called
|
||||||
out.writeNamedTag("Schematic????", tag);
|
out.writeNamedTag("Schematic????", tag);
|
||||||
}
|
}
|
||||||
@ -267,18 +262,14 @@ public abstract class WorldUtil {
|
|||||||
int brz = bot.getZ() >> 9;
|
int brz = bot.getZ() >> 9;
|
||||||
int trx = top.getX() >> 9;
|
int trx = top.getX() >> 9;
|
||||||
int trz = top.getZ() >> 9;
|
int trz = top.getZ() >> 9;
|
||||||
Set<BlockVector2> files = regionManager.getChunkChunks(bot.getWorldName());
|
Set<BlockVector2> files = getChunkChunks(bot.getWorldName());
|
||||||
for (BlockVector2 mca : files) {
|
for (BlockVector2 mca : files) {
|
||||||
if (mca.getX() >= brx && mca.getX() <= trx && mca.getZ() >= brz
|
if (mca.getX() >= brx && mca.getX() <= trx && mca.getZ() >= brz && mca.getZ() <= trz) {
|
||||||
&& mca.getZ() <= trz) {
|
final File file = getMcr(plot.getWorldName(), mca.getX(), mca.getZ());
|
||||||
final File file =
|
|
||||||
getMcr(plot.getWorldName(), mca.getX(), mca.getZ());
|
|
||||||
if (file != null) {
|
if (file != null) {
|
||||||
//final String name = "r." + (x - cx) + "." + (z - cz) + ".mca";
|
//final String name = "r." + (x - cx) + "." + (z - cz) + ".mca";
|
||||||
String name = file.getName();
|
String name = file.getName();
|
||||||
final ZipEntry ze = new ZipEntry(
|
final ZipEntry ze = new ZipEntry("world" + File.separator + "region" + File.separator + name);
|
||||||
"world" + File.separator + "region" + File.separator
|
|
||||||
+ name);
|
|
||||||
zos.putNextEntry(ze);
|
zos.putNextEntry(ze);
|
||||||
try (FileInputStream in = new FileInputStream(file)) {
|
try (FileInputStream in = new FileInputStream(file)) {
|
||||||
int len;
|
int len;
|
||||||
@ -302,9 +293,7 @@ public abstract class WorldUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable final File getDat(@Nonnull final String world) {
|
@Nullable final File getDat(@Nonnull final String world) {
|
||||||
File file = new File(
|
File file = new File(PlotSquared.platform().getWorldContainer() + File.separator + world + File.separator + "level.dat");
|
||||||
PlotSquared.platform().getWorldContainer() + File.separator + world + File.separator
|
|
||||||
+ "level.dat");
|
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
@ -312,14 +301,38 @@ public abstract class WorldUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable private File getMcr(@Nonnull final String world, final int x, final int z) {
|
@Nullable private File getMcr(@Nonnull final String world, final int x, final int z) {
|
||||||
final File file = new File(PlotSquared.platform().getWorldContainer(),
|
final File file =
|
||||||
world + File.separator + "region" + File.separator + "r." + x + '.' + z + ".mca");
|
new File(PlotSquared.platform().getWorldContainer(), world + File.separator + "region" + File.separator + "r." + x + '.' + z + ".mca");
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Set<BlockVector2> getChunkChunks(String world) {
|
||||||
|
File folder = new File(PlotSquared.platform().getWorldContainer(), world + File.separator + "region");
|
||||||
|
File[] regionFiles = folder.listFiles();
|
||||||
|
if (regionFiles == null) {
|
||||||
|
throw new RuntimeException("Could not find worlds folder: " + folder + " ? (no read access?)");
|
||||||
|
}
|
||||||
|
HashSet<BlockVector2> chunks = new HashSet<>();
|
||||||
|
for (File file : regionFiles) {
|
||||||
|
String name = file.getName();
|
||||||
|
if (name.endsWith("mca")) {
|
||||||
|
String[] split = name.split("\\.");
|
||||||
|
try {
|
||||||
|
int x = Integer.parseInt(split[1]);
|
||||||
|
int z = Integer.parseInt(split[2]);
|
||||||
|
BlockVector2 loc = BlockVector2.at(x, z);
|
||||||
|
chunks.add(loc);
|
||||||
|
} catch (NumberFormatException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return chunks;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if two blocks are the same type)
|
* Check if two blocks are the same type)
|
||||||
*
|
*
|
||||||
@ -383,7 +396,6 @@ public abstract class WorldUtil {
|
|||||||
* @param chunk Chunk coordinates
|
* @param chunk Chunk coordinates
|
||||||
* @return Tile entity count
|
* @return Tile entity count
|
||||||
*/
|
*/
|
||||||
@Nonnegative public abstract int getTileEntityCount(@Nonnull String world,
|
@Nonnegative public abstract int getTileEntityCount(@Nonnull String world, @Nonnull BlockVector2 chunk);
|
||||||
@Nonnull BlockVector2 chunk);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* _____ _ _ _____ _
|
||||||
|
* | __ \| | | | / ____| | |
|
||||||
|
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
||||||
|
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
||||||
|
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
||||||
|
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
||||||
|
* | |
|
||||||
|
* |_|
|
||||||
|
* PlotSquared plot management system for Minecraft
|
||||||
|
* Copyright (C) 2020 IntellectualSites
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.plotsquared.core.util.placeholders;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
import com.plotsquared.core.player.PlotPlayer;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A placeholder is a keyed value that gets replaced by a {@link PlotPlayer player}-specific value at runtime
|
||||||
|
*/
|
||||||
|
public abstract class Placeholder {
|
||||||
|
|
||||||
|
private final String key;
|
||||||
|
|
||||||
|
public Placeholder(@NotNull final String key) {
|
||||||
|
this.key = Preconditions.checkNotNull(key, "Key may not be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of the placeholder for a particular player
|
||||||
|
*
|
||||||
|
* @param player Player
|
||||||
|
* @return Placeholder value. Return {@code ""} if no placeholder value can be returned
|
||||||
|
*/
|
||||||
|
@NotNull public abstract String getValue(@NotNull final PlotPlayer<?> player);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the placeholder key
|
||||||
|
*
|
||||||
|
* @return Placeholder key
|
||||||
|
*/
|
||||||
|
@NotNull public final String getKey() {
|
||||||
|
return this.key;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,234 @@
|
|||||||
|
/*
|
||||||
|
* _____ _ _ _____ _
|
||||||
|
* | __ \| | | | / ____| | |
|
||||||
|
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
||||||
|
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
||||||
|
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
||||||
|
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
||||||
|
* | |
|
||||||
|
* |_|
|
||||||
|
* PlotSquared plot management system for Minecraft
|
||||||
|
* Copyright (C) 2020 IntellectualSites
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.plotsquared.core.util.placeholders;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import com.plotsquared.core.player.PlotPlayer;
|
||||||
|
import com.plotsquared.core.plot.Plot;
|
||||||
|
import com.plotsquared.core.plot.flag.GlobalFlagContainer;
|
||||||
|
import com.plotsquared.core.plot.flag.PlotFlag;
|
||||||
|
import com.plotsquared.core.util.EventDispatcher;
|
||||||
|
import com.plotsquared.core.util.PlayerManager;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registry that contains {@link Placeholder placeholders}
|
||||||
|
*/
|
||||||
|
public final class PlaceholderRegistry {
|
||||||
|
|
||||||
|
private final Map<String, Placeholder> placeholders;
|
||||||
|
private final EventDispatcher eventDispatcher;
|
||||||
|
|
||||||
|
public PlaceholderRegistry(@NotNull final EventDispatcher eventDispatcher) {
|
||||||
|
this.placeholders = Maps.newHashMap();
|
||||||
|
this.eventDispatcher = eventDispatcher;
|
||||||
|
this.registerDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerDefault() {
|
||||||
|
final GlobalFlagContainer globalFlagContainer = GlobalFlagContainer.getInstance();
|
||||||
|
for (final PlotFlag<?, ?> flag : globalFlagContainer.getRecognizedPlotFlags()) {
|
||||||
|
this.registerPlaceholder(new PlotFlagPlaceholder(flag, true));
|
||||||
|
this.registerPlaceholder(new PlotFlagPlaceholder(flag, false));
|
||||||
|
}
|
||||||
|
GlobalFlagContainer.getInstance().subscribe((flag, type) -> {
|
||||||
|
this.registerPlaceholder(new PlotFlagPlaceholder(flag, true));
|
||||||
|
this.registerPlaceholder(new PlotFlagPlaceholder(flag, false));
|
||||||
|
});
|
||||||
|
this.createPlaceholder("currentplot_world", player -> player.getLocation().getWorldName());
|
||||||
|
this.createPlaceholder("has_plot", player -> player.getPlotCount() > 0 ? "true" : "false");
|
||||||
|
this.createPlaceholder("allowed_plot_count", player -> Integer.toString(player.getAllowedPlots()));
|
||||||
|
this.createPlaceholder("plot_count", player -> Integer.toString(player.getPlotCount()));
|
||||||
|
this.createPlaceholder("currentplot_alias", (player, plot) -> plot.getAlias());
|
||||||
|
this.createPlaceholder("currentplot_owner", (player, plot) -> {
|
||||||
|
final UUID plotOwner = plot.getOwnerAbs();
|
||||||
|
if (plotOwner == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return PlayerManager.getName(plotOwner, false);
|
||||||
|
} catch (final Exception ignored) {}
|
||||||
|
|
||||||
|
return "unknown";
|
||||||
|
});
|
||||||
|
this.createPlaceholder("currentplot_members", (player, plot) -> {
|
||||||
|
if (plot.getMembers() == null && plot.getTrusted() == null) {
|
||||||
|
return "0";
|
||||||
|
}
|
||||||
|
return String.valueOf(plot.getMembers().size() + plot.getTrusted().size());
|
||||||
|
});
|
||||||
|
this.createPlaceholder("currentplot_members_added", (player, plot) -> {
|
||||||
|
if (plot.getMembers() == null) {
|
||||||
|
return "0";
|
||||||
|
}
|
||||||
|
return String.valueOf(plot.getMembers().size());
|
||||||
|
});
|
||||||
|
this.createPlaceholder("currentplot_members_trusted", (player, plot) -> {
|
||||||
|
if (plot.getTrusted() == null) {
|
||||||
|
return "0";
|
||||||
|
}
|
||||||
|
return String.valueOf(plot.getTrusted().size());
|
||||||
|
});
|
||||||
|
this.createPlaceholder("currentplot_members_denied", (player, plot) -> {
|
||||||
|
if (plot.getDenied() == null) {
|
||||||
|
return "0";
|
||||||
|
}
|
||||||
|
return String.valueOf(plot.getDenied().size());
|
||||||
|
});
|
||||||
|
this.createPlaceholder("has_build_rights", (player, plot) ->
|
||||||
|
plot.isAdded(player.getUUID()) ? "true" : "false");
|
||||||
|
this.createPlaceholder("currentplot_x", (player, plot) -> Integer.toString(plot.getId().getX()));
|
||||||
|
this.createPlaceholder("currentplot_y", (player, plot) -> Integer.toString(plot.getId().getY()));
|
||||||
|
this.createPlaceholder("currentplot_xy", (player, plot) -> plot.getId().toString());
|
||||||
|
this.createPlaceholder("currentplot_rating", (player, plot) -> Double.toString(plot.getAverageRating()));
|
||||||
|
this.createPlaceholder("currentplot_biome", (player, plot) -> plot.getBiomeSynchronous().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a functional placeholder
|
||||||
|
*
|
||||||
|
* @param key Placeholder key
|
||||||
|
* @param placeholderFunction Placeholder generator. Cannot return null
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("ALL") public void createPlaceholder(@NotNull final String key,
|
||||||
|
@NotNull final Function<PlotPlayer<?>, String> placeholderFunction) {
|
||||||
|
this.registerPlaceholder(new Placeholder(key) {
|
||||||
|
@Override @NotNull public String getValue(@NotNull final PlotPlayer<?> player) {
|
||||||
|
return placeholderFunction.apply(player);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a functional placeholder
|
||||||
|
*
|
||||||
|
* @param key Placeholder key
|
||||||
|
* @param placeholderFunction Placeholder generator. Cannot return null
|
||||||
|
*/
|
||||||
|
public void createPlaceholder(@NotNull final String key,
|
||||||
|
@NotNull final BiFunction<PlotPlayer<?>, Plot, String> placeholderFunction) {
|
||||||
|
this.registerPlaceholder(new PlotSpecificPlaceholder(key) {
|
||||||
|
@Override @NotNull public String getValue(@NotNull final PlotPlayer<?> player, @NotNull final Plot plot) {
|
||||||
|
return placeholderFunction.apply(player, plot);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a placeholder
|
||||||
|
*
|
||||||
|
* @param placeholder Placeholder instance
|
||||||
|
*/
|
||||||
|
public void registerPlaceholder(@NotNull final Placeholder placeholder) {
|
||||||
|
final Placeholder previous = this.placeholders
|
||||||
|
.put(placeholder.getKey().toLowerCase(Locale.ENGLISH),
|
||||||
|
Preconditions.checkNotNull(placeholder, "Placeholder may not be null"));
|
||||||
|
if (previous == null) {
|
||||||
|
this.eventDispatcher.callGenericEvent(new PlaceholderAddedEvent(placeholder));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a placeholder instance from its key
|
||||||
|
*
|
||||||
|
* @param key Placeholder key
|
||||||
|
* @return Placeholder value
|
||||||
|
*/
|
||||||
|
@Nullable public Placeholder getPlaceholder(@NotNull final String key) {
|
||||||
|
return this.placeholders.get(
|
||||||
|
Preconditions.checkNotNull(key, "Key may not be null").toLowerCase(Locale.ENGLISH));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the placeholder value evaluated for a player, and catch and deal with any problems
|
||||||
|
* occurring while doing so
|
||||||
|
*
|
||||||
|
* @param key Placeholder key
|
||||||
|
* @param player Player to evaluate for
|
||||||
|
* @return Replacement value
|
||||||
|
*/
|
||||||
|
@NotNull public String getPlaceholderValue(@NotNull final String key,
|
||||||
|
@NotNull final PlotPlayer<?> player) {
|
||||||
|
final Placeholder placeholder = getPlaceholder(key);
|
||||||
|
if (placeholder == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
String placeholderValue = "";
|
||||||
|
try {
|
||||||
|
placeholderValue = placeholder.getValue(player);
|
||||||
|
// If a placeholder for some reason decides to be disobedient, we catch it here
|
||||||
|
if (placeholderValue == null) {
|
||||||
|
new RuntimeException(String
|
||||||
|
.format("Placeholder '%s' returned null for player '%s'", placeholder.getKey(),
|
||||||
|
player.getName())).printStackTrace();
|
||||||
|
}
|
||||||
|
} catch (final Exception exception) {
|
||||||
|
new RuntimeException(String
|
||||||
|
.format("Placeholder '%s' failed to evalulate for player '%s'",
|
||||||
|
placeholder.getKey(), player.getName()), exception).printStackTrace();
|
||||||
|
}
|
||||||
|
return placeholderValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all placeholders
|
||||||
|
*
|
||||||
|
* @return Unmodifiable collection of placeholders
|
||||||
|
*/
|
||||||
|
@NotNull public Collection<Placeholder> getPlaceholders() {
|
||||||
|
return Collections.unmodifiableCollection(this.placeholders.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event called when a new {@link Placeholder} has been added
|
||||||
|
*/
|
||||||
|
public static class PlaceholderAddedEvent {
|
||||||
|
|
||||||
|
private final Placeholder placeholder;
|
||||||
|
|
||||||
|
public PlaceholderAddedEvent(Placeholder placeholder) {
|
||||||
|
this.placeholder = placeholder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Placeholder getPlaceholder() {
|
||||||
|
return this.placeholder;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* _____ _ _ _____ _
|
||||||
|
* | __ \| | | | / ____| | |
|
||||||
|
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
||||||
|
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
||||||
|
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
||||||
|
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
||||||
|
* | |
|
||||||
|
* |_|
|
||||||
|
* PlotSquared plot management system for Minecraft
|
||||||
|
* Copyright (C) 2020 IntellectualSites
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.plotsquared.core.util.placeholders;
|
||||||
|
|
||||||
|
import com.plotsquared.core.player.PlotPlayer;
|
||||||
|
import com.plotsquared.core.plot.Plot;
|
||||||
|
import com.plotsquared.core.plot.flag.GlobalFlagContainer;
|
||||||
|
import com.plotsquared.core.plot.flag.PlotFlag;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public final class PlotFlagPlaceholder extends PlotSpecificPlaceholder {
|
||||||
|
|
||||||
|
private final PlotFlag<?, ?> flag;
|
||||||
|
private final boolean local;
|
||||||
|
|
||||||
|
public PlotFlagPlaceholder(@NotNull final PlotFlag<?, ?> flag, final boolean local) {
|
||||||
|
super(String.format("currentplot_%sflag_%s", local ? "local": "", flag.getName()));
|
||||||
|
this.flag = flag;
|
||||||
|
this.local = local;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override @NotNull public String getValue(@NotNull final PlotPlayer<?> player, @NotNull final Plot plot) {
|
||||||
|
return this.getFlagValue(plot, this.flag.getName(), !this.local);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the flag value from its name on the current plot.
|
||||||
|
* If the flag doesn't exist it returns an empty string.
|
||||||
|
* If the flag exists but it is not set on current plot and the parameter inherit is set to true,
|
||||||
|
* it returns the default value.
|
||||||
|
*
|
||||||
|
* @param plot Current plot where the player is
|
||||||
|
* @param flagName Name of flag to get from current plot
|
||||||
|
* @param inherit Define if it returns only the flag set on the current plot or also inherited flags
|
||||||
|
* @return The value of flag serialized in string
|
||||||
|
*/
|
||||||
|
@NotNull private String getFlagValue(@NotNull final Plot plot, @NotNull final String flagName, final boolean inherit) {
|
||||||
|
if (flagName.isEmpty()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
final PlotFlag<?, ?> flag = GlobalFlagContainer.getInstance().getFlagFromString(flagName);
|
||||||
|
if (flag == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
if (inherit) {
|
||||||
|
return plot.getFlag(flag).toString();
|
||||||
|
} else {
|
||||||
|
final PlotFlag<?, ?> plotFlag = plot.getFlagContainer().queryLocal(flag.getClass());
|
||||||
|
return (plotFlag != null) ? plotFlag.getValue().toString() : "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* _____ _ _ _____ _
|
||||||
|
* | __ \| | | | / ____| | |
|
||||||
|
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
||||||
|
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
||||||
|
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
||||||
|
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
||||||
|
* | |
|
||||||
|
* |_|
|
||||||
|
* PlotSquared plot management system for Minecraft
|
||||||
|
* Copyright (C) 2020 IntellectualSites
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.plotsquared.core.util.placeholders;
|
||||||
|
|
||||||
|
import com.plotsquared.core.player.PlotPlayer;
|
||||||
|
import com.plotsquared.core.plot.Plot;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link Placeholder placeholder} that requires a {@link com.plotsquared.core.plot.Plot plot}
|
||||||
|
*/
|
||||||
|
public abstract class PlotSpecificPlaceholder extends Placeholder {
|
||||||
|
|
||||||
|
public PlotSpecificPlaceholder(@NotNull final String key) {
|
||||||
|
super(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override @NotNull public final String getValue(@NotNull final PlotPlayer<?> player) {
|
||||||
|
final Plot plot = player.getCurrentPlot();
|
||||||
|
if (plot == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return this.getValue(player, plot);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of the placeholder for the {@link PlotPlayer player} in a specific {@link Plot plot}
|
||||||
|
*
|
||||||
|
* @param player Player that the placeholder is evaluated for
|
||||||
|
* @param plot Plot that the player is in
|
||||||
|
* @return Placeholder value, or {@code ""} if the placeholder does not apply
|
||||||
|
*/
|
||||||
|
@NotNull public abstract String getValue(@NotNull final PlotPlayer<?> player,
|
||||||
|
@NotNull final Plot plot);
|
||||||
|
|
||||||
|
}
|
@ -171,8 +171,10 @@ public class UUIDPipeline {
|
|||||||
} catch (InterruptedException | ExecutionException e) {
|
} catch (InterruptedException | ExecutionException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} catch (TimeoutException ignored) {
|
} catch (TimeoutException ignored) {
|
||||||
logger.warn("[P2] (UUID) Request for {} timed out", username);
|
|
||||||
// This is completely valid, we just don't care anymore
|
// This is completely valid, we just don't care anymore
|
||||||
|
if (Settings.DEBUG) {
|
||||||
|
logger.warn("[P2] (UUID) Request for {} timed out", username);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -194,8 +196,10 @@ public class UUIDPipeline {
|
|||||||
} catch (InterruptedException | ExecutionException e) {
|
} catch (InterruptedException | ExecutionException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} catch (TimeoutException ignored) {
|
} catch (TimeoutException ignored) {
|
||||||
logger.warn("[P2] (UUID) Request for {} timed out", uuid);
|
|
||||||
// This is completely valid, we just don't care anymore
|
// This is completely valid, we just don't care anymore
|
||||||
|
if (Settings.DEBUG) {
|
||||||
|
logger.warn("[P2] (UUID) Request for {} timed out", uuid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -206,8 +210,7 @@ public class UUIDPipeline {
|
|||||||
* @param username Username
|
* @param username Username
|
||||||
* @param uuid UUID consumer
|
* @param uuid UUID consumer
|
||||||
*/
|
*/
|
||||||
public void getSingle(@Nonnull final String username,
|
public void getSingle(@Nonnull final String username, @Nonnull final BiConsumer<UUID, Throwable> uuid) {
|
||||||
@Nonnull final BiConsumer<UUID, Throwable> uuid) {
|
|
||||||
this.getUUIDs(Collections.singletonList(username)).applyToEither(timeoutAfter(Settings.UUID.NON_BLOCKING_TIMEOUT), Function.identity())
|
this.getUUIDs(Collections.singletonList(username)).applyToEither(timeoutAfter(Settings.UUID.NON_BLOCKING_TIMEOUT), Function.identity())
|
||||||
.whenComplete((uuids, throwable) -> {
|
.whenComplete((uuids, throwable) -> {
|
||||||
if (throwable != null) {
|
if (throwable != null) {
|
||||||
@ -228,8 +231,7 @@ public class UUIDPipeline {
|
|||||||
* @param uuid UUID
|
* @param uuid UUID
|
||||||
* @param username Username consumer
|
* @param username Username consumer
|
||||||
*/
|
*/
|
||||||
public void getSingle(@Nonnull final UUID uuid,
|
public void getSingle(@Nonnull final UUID uuid, @Nonnull final BiConsumer<String, Throwable> username) {
|
||||||
@Nonnull final BiConsumer<String, Throwable> username) {
|
|
||||||
this.getNames(Collections.singletonList(uuid)).applyToEither(timeoutAfter(Settings.UUID.NON_BLOCKING_TIMEOUT), Function.identity())
|
this.getNames(Collections.singletonList(uuid)).applyToEither(timeoutAfter(Settings.UUID.NON_BLOCKING_TIMEOUT), Function.identity())
|
||||||
.whenComplete((uuids, throwable) -> {
|
.whenComplete((uuids, throwable) -> {
|
||||||
if (throwable != null) {
|
if (throwable != null) {
|
||||||
@ -254,8 +256,7 @@ public class UUIDPipeline {
|
|||||||
* @param timeout Timeout in milliseconds
|
* @param timeout Timeout in milliseconds
|
||||||
* @return Mappings
|
* @return Mappings
|
||||||
*/
|
*/
|
||||||
public CompletableFuture<List<UUIDMapping>> getNames(@Nonnull final Collection<UUID> requests,
|
public CompletableFuture<List<UUIDMapping>> getNames(@Nonnull final Collection<UUID> requests, final long timeout) {
|
||||||
final long timeout) {
|
|
||||||
return this.getNames(requests).applyToEither(timeoutAfter(timeout), Function.identity());
|
return this.getNames(requests).applyToEither(timeoutAfter(timeout), Function.identity());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,8 +270,7 @@ public class UUIDPipeline {
|
|||||||
* @param timeout Timeout in milliseconds
|
* @param timeout Timeout in milliseconds
|
||||||
* @return Mappings
|
* @return Mappings
|
||||||
*/
|
*/
|
||||||
public CompletableFuture<List<UUIDMapping>> getUUIDs(@Nonnull final Collection<String> requests,
|
public CompletableFuture<List<UUIDMapping>> getUUIDs(@Nonnull final Collection<String> requests, final long timeout) {
|
||||||
final long timeout) {
|
|
||||||
return this.getUUIDs(requests).applyToEither(timeoutAfter(timeout), Function.identity());
|
return this.getUUIDs(requests).applyToEither(timeoutAfter(timeout), Function.identity());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -349,8 +349,7 @@ public class UUIDPipeline {
|
|||||||
* @param requests Names
|
* @param requests Names
|
||||||
* @return Mappings
|
* @return Mappings
|
||||||
*/
|
*/
|
||||||
public CompletableFuture<List<UUIDMapping>> getUUIDs(
|
public CompletableFuture<List<UUIDMapping>> getUUIDs(@Nonnull final Collection<String> requests) {
|
||||||
@Nonnull final Collection<String> requests) {
|
|
||||||
if (requests.isEmpty()) {
|
if (requests.isEmpty()) {
|
||||||
return CompletableFuture.completedFuture(Collections.emptyList());
|
return CompletableFuture.completedFuture(Collections.emptyList());
|
||||||
}
|
}
|
||||||
|
@ -182,6 +182,8 @@
|
|||||||
"core.prefix": "<dark_gray>[</dark_gray><gold>P2</gold><dark_gray>] </dark_gray>",
|
"core.prefix": "<dark_gray>[</dark_gray><gold>P2</gold><dark_gray>] </dark_gray>",
|
||||||
"core.enabled": "<prefix><gold><value> is now enabled.</gold>",
|
"core.enabled": "<prefix><gold><value> is now enabled.</gold>",
|
||||||
|
|
||||||
|
"placeholder.hooked": "<prefix><gold>PlotSquared hooked into MVdWPlaceholderAPI</gold>",
|
||||||
|
|
||||||
"reload.reloaded_configs": "<prefix><gold>Translations and world settings have been reloaded successfully.</gold>",
|
"reload.reloaded_configs": "<prefix><gold>Translations and world settings have been reloaded successfully.</gold>",
|
||||||
"reload.reload_failed": "<prefix><red>Failed to reload file configurations.</red>",
|
"reload.reload_failed": "<prefix><red>Failed to reload file configurations.</red>",
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ subprojects { subproject ->
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile group: 'org.json', name: 'json', version: '20200518'
|
compile group: 'org.json', name: 'json', version: '20200518'
|
||||||
implementation("com.sk89q.worldedit:worldedit-core:7.0.0") {
|
implementation("com.sk89q.worldedit:worldedit-core:7.2.0-SNAPSHOT") {
|
||||||
exclude(module: "bukkit-classloader-check")
|
exclude(module: "bukkit-classloader-check")
|
||||||
exclude(module: "mockito-core")
|
exclude(module: "mockito-core")
|
||||||
exclude(module: "dummypermscompat")
|
exclude(module: "dummypermscompat")
|
||||||
@ -100,6 +100,7 @@ subprojects { subproject ->
|
|||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
|
mavenLocal()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
maven { url = "https://maven.enginehub.org/repo/" }
|
maven { url = "https://maven.enginehub.org/repo/" }
|
||||||
maven { url = "https://repo.maven.apache.org/maven2" }
|
maven { url = "https://repo.maven.apache.org/maven2" }
|
||||||
@ -110,6 +111,8 @@ subprojects { subproject ->
|
|||||||
dependencies {
|
dependencies {
|
||||||
include(dependency("org.json:json:20200518"))
|
include(dependency("org.json:json:20200518"))
|
||||||
include(dependency("net.kyori:text-api:3.0.2"))
|
include(dependency("net.kyori:text-api:3.0.2"))
|
||||||
|
include(dependency("javax.inject:javax.inject:1"))
|
||||||
|
include(dependency("aopalliance:aopalliance:1.0"))
|
||||||
}
|
}
|
||||||
relocate("io.papermc.lib", "com.plotsquared.bukkit.paperlib")
|
relocate("io.papermc.lib", "com.plotsquared.bukkit.paperlib")
|
||||||
relocate("org.json", "com.plotsquared.json") {
|
relocate("org.json", "com.plotsquared.json") {
|
||||||
|
Loading…
Reference in New Issue
Block a user