mirror of
https://github.com/IntellectualSites/PlotSquared.git
synced 2024-11-25 22:56:45 +01:00
Merge features/v5/internal-updates into api/v5/packages
This commit is contained in:
commit
edaf396894
@ -17,6 +17,7 @@ repositories {
|
||||
|
||||
dependencies {
|
||||
implementation(project(":Core"))
|
||||
compile("org.bstats:bstats-bukkit:1.7")
|
||||
compile(project(":Core"))
|
||||
compile("com.destroystokyo.paper:paper-api:1.15.2-R0.1-SNAPSHOT")
|
||||
//implementation 'com.onarandombox.multiversecore:Multiverse-Core:3.0.0-SNAPSHOT'
|
||||
@ -44,7 +45,7 @@ processResources {
|
||||
}
|
||||
|
||||
//noinspection GroovyAssignabilityCheck
|
||||
jar.archiveFileName = "PlotSquared-BukkitAPI-${project.parent.version}.jar"
|
||||
jar.archiveFileName = "PlotSquared-Bukkit-${project.parent.version}.jar"
|
||||
jar.destinationDirectory = file("../mvn/com/plotsquared/PlotSquared-Bukkit/" + project.parent.version)
|
||||
task createPom {
|
||||
doLast {
|
||||
@ -83,9 +84,11 @@ shadowJar {
|
||||
include(dependency(":Core"))
|
||||
include(dependency("io.papermc:paperlib:1.0.2"))
|
||||
include(dependency("net.kyori:text-adapter-bukkit:3.0.3"))
|
||||
include(dependency("org.bstats:bstats-bukkit:1.7"))
|
||||
}
|
||||
relocate('net.kyori.text', 'com.plotsquared.formatting.text')
|
||||
relocate("io.papermc.lib", "com.plotsquared.bukkit.paperlib")
|
||||
relocate("org.bstats", "com.plotsquared.metrics")
|
||||
archiveFileName = "${parent.name}-${project.name}-${parent.version}.jar"
|
||||
destinationDirectory = file "../target"
|
||||
}
|
||||
|
@ -6,10 +6,22 @@
|
||||
<artifactId>PlotSquared-Bukkit</artifactId>
|
||||
<version>latest</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.json</groupId>
|
||||
<artifactId>json</artifactId>
|
||||
<version>20190722</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bstats</groupId>
|
||||
<artifactId>bstats-bukkit</artifactId>
|
||||
<version>1.7</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.plotsquared</groupId>
|
||||
<artifactId>Core</artifactId>
|
||||
<version>latest</version>
|
||||
<version>unspecified</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -27,21 +27,23 @@ package com.plotsquared.bukkit;
|
||||
|
||||
import com.plotsquared.bukkit.entity.EntityWrapper;
|
||||
import com.plotsquared.bukkit.entity.ReplicatingEntityWrapper;
|
||||
import com.plotsquared.core.PlotSquared;
|
||||
import com.plotsquared.bukkit.util.BukkitUtil;
|
||||
import com.plotsquared.core.PlotSquared;
|
||||
import com.plotsquared.core.generator.AugmentedUtils;
|
||||
import com.plotsquared.core.listener.WEExtent;
|
||||
import com.plotsquared.core.location.Location;
|
||||
import com.plotsquared.core.location.PlotLoc;
|
||||
import com.plotsquared.core.plot.Plot;
|
||||
import com.plotsquared.core.plot.PlotArea;
|
||||
import com.plotsquared.core.location.PlotLoc;
|
||||
import com.plotsquared.core.util.task.RunnableVal;
|
||||
import com.plotsquared.core.util.ChunkManager;
|
||||
import com.plotsquared.core.util.task.TaskManager;
|
||||
import com.plotsquared.core.queue.GlobalBlockQueue;
|
||||
import com.plotsquared.core.queue.LocalBlockQueue;
|
||||
import com.plotsquared.core.queue.ScopedLocalBlockQueue;
|
||||
import com.plotsquared.core.util.ChunkManager;
|
||||
import com.plotsquared.core.util.RegionUtil;
|
||||
import com.plotsquared.core.util.entity.EntityCategories;
|
||||
import com.plotsquared.core.util.task.RunnableVal;
|
||||
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.BlockVector3;
|
||||
@ -54,8 +56,6 @@ import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.entity.Animals;
|
||||
import org.bukkit.entity.Creature;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@ -72,6 +72,12 @@ import java.util.concurrent.CompletableFuture;
|
||||
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_ENTITY;
|
||||
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;
|
||||
|
||||
public class BukkitChunkManager extends ChunkManager {
|
||||
|
||||
@ -514,135 +520,27 @@ public class BukkitChunkManager extends ChunkManager {
|
||||
}
|
||||
|
||||
private void count(int[] count, Entity entity) {
|
||||
switch (entity.getType()) {
|
||||
case PLAYER:
|
||||
// not valid
|
||||
final com.sk89q.worldedit.world.entity.EntityType entityType =
|
||||
BukkitAdapter.adapt(entity.getType());
|
||||
|
||||
if (EntityCategories.PLAYER.contains(entityType)) {
|
||||
return;
|
||||
case SMALL_FIREBALL:
|
||||
case FIREBALL:
|
||||
case DROPPED_ITEM:
|
||||
case EGG:
|
||||
case THROWN_EXP_BOTTLE:
|
||||
case SPLASH_POTION:
|
||||
case SNOWBALL:
|
||||
case ENDER_PEARL:
|
||||
case ARROW:
|
||||
case TRIDENT:
|
||||
case SHULKER_BULLET:
|
||||
case SPECTRAL_ARROW:
|
||||
case DRAGON_FIREBALL:
|
||||
case LLAMA_SPIT:
|
||||
// projectile
|
||||
case PRIMED_TNT:
|
||||
case FALLING_BLOCK:
|
||||
// Block entities
|
||||
case ENDER_CRYSTAL:
|
||||
case FISHING_HOOK:
|
||||
case ENDER_SIGNAL:
|
||||
case EXPERIENCE_ORB:
|
||||
case LEASH_HITCH:
|
||||
case FIREWORK:
|
||||
case LIGHTNING:
|
||||
case WITHER_SKULL:
|
||||
case UNKNOWN:
|
||||
case AREA_EFFECT_CLOUD:
|
||||
case EVOKER_FANGS:
|
||||
// non moving / unremovable
|
||||
break;
|
||||
case ITEM_FRAME:
|
||||
case PAINTING:
|
||||
case ARMOR_STAND:
|
||||
count[5]++;
|
||||
break;
|
||||
// misc
|
||||
case MINECART:
|
||||
case MINECART_CHEST:
|
||||
case MINECART_COMMAND:
|
||||
case MINECART_FURNACE:
|
||||
case MINECART_HOPPER:
|
||||
case MINECART_MOB_SPAWNER:
|
||||
case MINECART_TNT:
|
||||
case BOAT:
|
||||
count[4]++;
|
||||
break;
|
||||
case POLAR_BEAR:
|
||||
case RABBIT:
|
||||
case SHEEP:
|
||||
case MUSHROOM_COW:
|
||||
case OCELOT:
|
||||
case PIG:
|
||||
case HORSE:
|
||||
case SQUID:
|
||||
case VILLAGER:
|
||||
case IRON_GOLEM:
|
||||
case WOLF:
|
||||
case CHICKEN:
|
||||
case COW:
|
||||
case SNOWMAN:
|
||||
case BAT:
|
||||
case DONKEY:
|
||||
case LLAMA:
|
||||
case SKELETON_HORSE:
|
||||
case ZOMBIE_HORSE:
|
||||
case MULE:
|
||||
case DOLPHIN:
|
||||
case TURTLE:
|
||||
case COD:
|
||||
case PARROT:
|
||||
case SALMON:
|
||||
case PUFFERFISH:
|
||||
case TROPICAL_FISH:
|
||||
case CAT:
|
||||
case FOX:
|
||||
case PANDA:
|
||||
// animal
|
||||
count[3]++;
|
||||
count[1]++;
|
||||
break;
|
||||
case BLAZE:
|
||||
case CAVE_SPIDER:
|
||||
case CREEPER:
|
||||
case ENDERMAN:
|
||||
case ENDERMITE:
|
||||
case ENDER_DRAGON:
|
||||
case GHAST:
|
||||
case GIANT:
|
||||
case GUARDIAN:
|
||||
case MAGMA_CUBE:
|
||||
case PIG_ZOMBIE:
|
||||
case SILVERFISH:
|
||||
case SKELETON:
|
||||
case SLIME:
|
||||
case SPIDER:
|
||||
case WITCH:
|
||||
case WITHER:
|
||||
case ZOMBIE:
|
||||
case SHULKER:
|
||||
case ELDER_GUARDIAN:
|
||||
case STRAY:
|
||||
case HUSK:
|
||||
case EVOKER:
|
||||
case VEX:
|
||||
case WITHER_SKELETON:
|
||||
case ZOMBIE_VILLAGER:
|
||||
case VINDICATOR:
|
||||
// monster
|
||||
count[3]++;
|
||||
count[2]++;
|
||||
break;
|
||||
default:
|
||||
if (entity instanceof Creature) {
|
||||
count[3]++;
|
||||
if (entity instanceof Animals) {
|
||||
count[1]++;
|
||||
} else {
|
||||
count[2]++;
|
||||
} 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]++;
|
||||
}
|
||||
} else {
|
||||
count[4]++;
|
||||
}
|
||||
}
|
||||
count[0]++;
|
||||
count[CAP_ENTITY]++;
|
||||
}
|
||||
|
||||
|
||||
|
@ -41,7 +41,6 @@ import com.plotsquared.bukkit.schematic.BukkitSchematicHandler;
|
||||
import com.plotsquared.bukkit.util.BukkitSetupUtils;
|
||||
import com.plotsquared.bukkit.util.BukkitTaskManager;
|
||||
import com.plotsquared.bukkit.util.BukkitUtil;
|
||||
import com.plotsquared.bukkit.util.Metrics;
|
||||
import com.plotsquared.bukkit.util.SetGenCB;
|
||||
import com.plotsquared.bukkit.util.UpdateUtility;
|
||||
import com.plotsquared.bukkit.queue.BukkitLocalQueue;
|
||||
@ -64,6 +63,8 @@ import com.plotsquared.core.generator.IndependentPlotGenerator;
|
||||
import com.plotsquared.core.listener.PlotListener;
|
||||
import com.plotsquared.core.plot.Plot;
|
||||
import com.plotsquared.core.plot.PlotArea;
|
||||
import com.plotsquared.core.plot.PlotAreaTerrainType;
|
||||
import com.plotsquared.core.plot.PlotAreaType;
|
||||
import com.plotsquared.core.plot.PlotId;
|
||||
import com.plotsquared.core.player.PlotPlayer;
|
||||
import com.plotsquared.core.plot.SetupObject;
|
||||
@ -94,6 +95,7 @@ import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import org.bstats.bukkit.Metrics;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Chunk;
|
||||
@ -119,6 +121,7 @@ import java.lang.reflect.Method;
|
||||
import java.util.AbstractMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -690,14 +693,28 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain
|
||||
return new BukkitSetupUtils();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
// Metrics are controlled via bstats config
|
||||
@Override public void startMetrics() {
|
||||
if (this.metricsStarted) {
|
||||
return;
|
||||
}
|
||||
this.metricsStarted = true;
|
||||
Metrics metrics = new Metrics(this, BSTATS_ID);// bstats
|
||||
metrics.addCustomChart(new Metrics.DrilldownPie("area_types", () -> {
|
||||
final Map<String, Map<String, Integer>> map = new HashMap<>();
|
||||
for (final PlotAreaType plotAreaType : PlotAreaType.values()) {
|
||||
final Map<String, Integer> terrainTypes = new HashMap<>();
|
||||
for (final PlotAreaTerrainType plotAreaTerrainType : PlotAreaTerrainType.values()) {
|
||||
terrainTypes.put(plotAreaTerrainType.name().toLowerCase(), 0);
|
||||
}
|
||||
map.put(plotAreaType.name().toLowerCase(), terrainTypes);
|
||||
}
|
||||
for (final PlotArea plotArea : PlotSquared.get().getPlotAreas()) {
|
||||
final Map<String, Integer> terrainTypeMap = map.get(plotArea.getType().name().toLowerCase());
|
||||
terrainTypeMap.put(plotArea.getTerrain().name().toLowerCase(),
|
||||
terrainTypeMap.get(plotArea.getTerrain().name().toLowerCase()) + 1);
|
||||
}
|
||||
return map;
|
||||
}));
|
||||
}
|
||||
|
||||
@Override public ChunkManager initChunkManager() {
|
||||
|
@ -256,9 +256,9 @@ import java.util.UUID;
|
||||
MainUtil.sendMessage(player, "&7 - Updating plot objects");
|
||||
|
||||
for (Plot plot : PlotSquared.get().getPlots()) {
|
||||
UUID value = uCMap.get(plot.owner);
|
||||
UUID value = uCMap.get(plot.getOwnerAbs());
|
||||
if (value != null) {
|
||||
plot.owner = value;
|
||||
plot.setOwnerAbs(value);
|
||||
}
|
||||
plot.getTrusted().clear();
|
||||
plot.getMembers().clear();
|
||||
@ -275,9 +275,9 @@ import java.util.UUID;
|
||||
if (!result) {
|
||||
MainUtil.sendMessage(player, "&cConversion failed! Attempting recovery");
|
||||
for (Plot plot : PlotSquared.get().getPlots()) {
|
||||
UUID value = uCReverse.get(plot.owner);
|
||||
UUID value = uCReverse.get(plot.getOwnerAbs());
|
||||
if (value != null) {
|
||||
plot.owner = value;
|
||||
plot.setOwnerAbs(value);
|
||||
}
|
||||
}
|
||||
DBFunc.createPlotsAndData(new ArrayList<>(PlotSquared.get().getPlots()),
|
||||
|
@ -100,40 +100,39 @@ import com.plotsquared.core.util.MainUtil;
|
||||
import com.plotsquared.core.util.MathMan;
|
||||
import com.plotsquared.core.util.Permissions;
|
||||
import com.plotsquared.core.util.RegExUtil;
|
||||
import com.plotsquared.core.util.entity.EntityCategories;
|
||||
import com.plotsquared.core.util.task.TaskManager;
|
||||
import com.plotsquared.core.util.uuid.UUIDHandler;
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.FluidCollisionMode;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.entity.Ageable;
|
||||
import org.bukkit.entity.Animals;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.Arrow;
|
||||
import org.bukkit.entity.Creature;
|
||||
import org.bukkit.entity.EnderDragon;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.FallingBlock;
|
||||
import org.bukkit.entity.Fireball;
|
||||
import org.bukkit.entity.Golem;
|
||||
import org.bukkit.entity.Hanging;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.entity.ItemFrame;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Monster;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.entity.TNTPrimed;
|
||||
import org.bukkit.entity.Tameable;
|
||||
import org.bukkit.entity.ThrownPotion;
|
||||
import org.bukkit.entity.Vehicle;
|
||||
import org.bukkit.entity.Villager;
|
||||
import org.bukkit.entity.WaterMob;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
@ -156,12 +155,38 @@ import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.block.BlockRedstoneEvent;
|
||||
import org.bukkit.event.block.BlockSpreadEvent;
|
||||
import org.bukkit.event.block.EntityBlockFormEvent;
|
||||
import org.bukkit.event.entity.*;
|
||||
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.EntityPickupItemEvent;
|
||||
import org.bukkit.event.entity.ExplosionPrimeEvent;
|
||||
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.event.hanging.HangingBreakByEntityEvent;
|
||||
import org.bukkit.event.hanging.HangingPlaceEvent;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
||||
import org.bukkit.event.player.*;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
import org.bukkit.event.player.PlayerBucketEmptyEvent;
|
||||
import org.bukkit.event.player.PlayerBucketFillEvent;
|
||||
import org.bukkit.event.player.PlayerChangedWorldEvent;
|
||||
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
||||
import org.bukkit.event.player.PlayerDropItemEvent;
|
||||
import org.bukkit.event.player.PlayerEggThrowEvent;
|
||||
import org.bukkit.event.player.PlayerEvent;
|
||||
import org.bukkit.event.player.PlayerInteractAtEntityEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEntityEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.event.player.PlayerRespawnEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
import org.bukkit.event.vehicle.VehicleCreateEvent;
|
||||
import org.bukkit.event.vehicle.VehicleDestroyEvent;
|
||||
import org.bukkit.event.vehicle.VehicleEntityCollisionEvent;
|
||||
@ -244,147 +269,40 @@ public class PlayerEvents extends PlotListener implements Listener {
|
||||
.getFlagContainer().getFlagMap().isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
switch (entity.getType()) {
|
||||
case PLAYER:
|
||||
|
||||
final com.sk89q.worldedit.world.entity.EntityType entityType = BukkitAdapter.adapt(entity.getType());
|
||||
|
||||
if (EntityCategories.PLAYER.contains(entityType)) {
|
||||
return false;
|
||||
case ARROW:
|
||||
case DRAGON_FIREBALL:
|
||||
case DROPPED_ITEM:
|
||||
case EGG:
|
||||
case ENDER_PEARL:
|
||||
case FIREBALL:
|
||||
case LLAMA_SPIT:
|
||||
case SHULKER_BULLET:
|
||||
case SMALL_FIREBALL:
|
||||
case SNOWBALL:
|
||||
case SPECTRAL_ARROW:
|
||||
case SPLASH_POTION:
|
||||
case THROWN_EXP_BOTTLE:
|
||||
// projectile
|
||||
case FALLING_BLOCK:
|
||||
case PRIMED_TNT:
|
||||
// Block entities
|
||||
case AREA_EFFECT_CLOUD:
|
||||
case ENDER_CRYSTAL:
|
||||
case ENDER_SIGNAL:
|
||||
case EVOKER_FANGS:
|
||||
case EXPERIENCE_ORB:
|
||||
case FIREWORK:
|
||||
case FISHING_HOOK:
|
||||
case LEASH_HITCH:
|
||||
case LIGHTNING:
|
||||
case UNKNOWN:
|
||||
case WITHER_SKULL:
|
||||
// non moving / unmovable
|
||||
return EntityUtil.checkEntity(plot, EntityCapFlag.ENTITY_CAP_UNLIMITED);
|
||||
case ARMOR_STAND:
|
||||
case ITEM_FRAME:
|
||||
case PAINTING:
|
||||
return EntityUtil.checkEntity(plot, EntityCapFlag.ENTITY_CAP_UNLIMITED,
|
||||
MiscCapFlag.MISC_CAP_UNLIMITED);
|
||||
// misc
|
||||
case BOAT:
|
||||
case MINECART:
|
||||
case MINECART_CHEST:
|
||||
case MINECART_COMMAND:
|
||||
case MINECART_FURNACE:
|
||||
case MINECART_HOPPER:
|
||||
case MINECART_MOB_SPAWNER:
|
||||
case MINECART_TNT:
|
||||
return EntityUtil.checkEntity(plot, EntityCapFlag.ENTITY_CAP_UNLIMITED,
|
||||
VehicleCapFlag.VEHICLE_CAP_UNLIMITED);
|
||||
case BAT:
|
||||
case CHICKEN:
|
||||
case CAT:
|
||||
case COD:
|
||||
case COW:
|
||||
case DOLPHIN:
|
||||
case DONKEY:
|
||||
case FOX:
|
||||
case HORSE:
|
||||
case IRON_GOLEM:
|
||||
case LLAMA:
|
||||
case MULE:
|
||||
case MUSHROOM_COW:
|
||||
case OCELOT:
|
||||
case PANDA:
|
||||
case PARROT:
|
||||
case PIG:
|
||||
case POLAR_BEAR:
|
||||
case PUFFERFISH:
|
||||
case RABBIT:
|
||||
case SALMON:
|
||||
case SHEEP:
|
||||
case SKELETON_HORSE:
|
||||
case SNOWMAN:
|
||||
case SQUID:
|
||||
case TRADER_LLAMA:
|
||||
case TROPICAL_FISH:
|
||||
case TURTLE:
|
||||
case VILLAGER:
|
||||
case WOLF:
|
||||
case ZOMBIE_HORSE:
|
||||
// animal
|
||||
return EntityUtil.checkEntity(plot, EntityCapFlag.ENTITY_CAP_UNLIMITED,
|
||||
MobCapFlag.MOB_CAP_UNLIMITED, AnimalCapFlag.ANIMAL_CAP_UNLIMITED);
|
||||
case BLAZE:
|
||||
case CAVE_SPIDER:
|
||||
case CREEPER:
|
||||
case DROWNED:
|
||||
case ELDER_GUARDIAN:
|
||||
case ENDERMAN:
|
||||
case ENDERMITE:
|
||||
case ENDER_DRAGON:
|
||||
case EVOKER:
|
||||
case GHAST:
|
||||
case GIANT:
|
||||
case GUARDIAN:
|
||||
case HUSK:
|
||||
case ILLUSIONER:
|
||||
case MAGMA_CUBE:
|
||||
case PIG_ZOMBIE:
|
||||
case SHULKER:
|
||||
case SILVERFISH:
|
||||
case SKELETON:
|
||||
case SLIME:
|
||||
case SPIDER:
|
||||
case STRAY:
|
||||
case VEX:
|
||||
case VINDICATOR:
|
||||
case WITCH:
|
||||
case WITHER:
|
||||
case WITHER_SKELETON:
|
||||
case ZOMBIE:
|
||||
case ZOMBIE_VILLAGER:
|
||||
case PILLAGER:
|
||||
case PHANTOM:
|
||||
case RAVAGER:
|
||||
// monster
|
||||
return EntityUtil.checkEntity(plot, EntityCapFlag.ENTITY_CAP_UNLIMITED,
|
||||
MobCapFlag.MOB_CAP_UNLIMITED, HostileCapFlag.HOSTILE_CAP_UNLIMITED);
|
||||
default:
|
||||
if (entity instanceof LivingEntity) {
|
||||
if (entity instanceof Animals || entity instanceof WaterMob) {
|
||||
return EntityUtil.checkEntity(plot, EntityCapFlag.ENTITY_CAP_UNLIMITED,
|
||||
MobCapFlag.MOB_CAP_UNLIMITED, AnimalCapFlag.ANIMAL_CAP_UNLIMITED);
|
||||
} else if (entity instanceof Monster) {
|
||||
return EntityUtil.checkEntity(plot, EntityCapFlag.ENTITY_CAP_UNLIMITED,
|
||||
MobCapFlag.MOB_CAP_UNLIMITED, HostileCapFlag.HOSTILE_CAP_UNLIMITED);
|
||||
} else {
|
||||
return EntityUtil.checkEntity(plot, EntityCapFlag.ENTITY_CAP_UNLIMITED,
|
||||
MobCapFlag.MOB_CAP_UNLIMITED);
|
||||
}
|
||||
}
|
||||
if (entity instanceof Vehicle) {
|
||||
return EntityUtil.checkEntity(plot, EntityCapFlag.ENTITY_CAP_UNLIMITED,
|
||||
VehicleCapFlag.VEHICLE_CAP_UNLIMITED);
|
||||
}
|
||||
if (entity instanceof Hanging) {
|
||||
|
||||
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);
|
||||
}
|
||||
return EntityUtil.checkEntity(plot, EntityCapFlag.ENTITY_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);
|
||||
}
|
||||
|
||||
@EventHandler public void onVehicleEntityCollision(VehicleEntityCollisionEvent e) {
|
||||
@ -414,53 +332,6 @@ public class PlayerEvents extends PlotListener implements Listener {
|
||||
|
||||
@EventHandler public void onRedstoneEvent(BlockRedstoneEvent event) {
|
||||
Block block = event.getBlock();
|
||||
/* switch (block.getType()) {
|
||||
case OBSERVER:
|
||||
case REDSTONE:
|
||||
case REDSTONE_ORE:
|
||||
case REDSTONE_BLOCK:
|
||||
case REDSTONE_TORCH:
|
||||
case REDSTONE_WALL_TORCH:
|
||||
case REDSTONE_WIRE:
|
||||
case REDSTONE_LAMP:
|
||||
case PISTON_HEAD:
|
||||
case PISTON:
|
||||
case STICKY_PISTON:
|
||||
case MOVING_PISTON:
|
||||
case LEVER:
|
||||
case ACACIA_BUTTON:
|
||||
case BIRCH_BUTTON:
|
||||
case DARK_OAK_BUTTON:
|
||||
case JUNGLE_BUTTON:
|
||||
case OAK_BUTTON:
|
||||
case SPRUCE_BUTTON:
|
||||
case STONE_BUTTON:
|
||||
case STONE_PRESSURE_PLATE:
|
||||
case ACACIA_PRESSURE_PLATE:
|
||||
case BIRCH_PRESSURE_PLATE:
|
||||
case DARK_OAK_PRESSURE_PLATE:
|
||||
case HEAVY_WEIGHTED_PRESSURE_PLATE:
|
||||
case JUNGLE_PRESSURE_PLATE:
|
||||
case LIGHT_WEIGHTED_PRESSURE_PLATE:
|
||||
case OAK_PRESSURE_PLATE:
|
||||
case SPRUCE_PRESSURE_PLATE:
|
||||
case SPRUCE_DOOR:
|
||||
case BIRCH_DOOR:
|
||||
case JUNGLE_DOOR:
|
||||
case ACACIA_DOOR:
|
||||
case DARK_OAK_DOOR:
|
||||
case IRON_DOOR:
|
||||
case OAK_DOOR:
|
||||
case IRON_TRAPDOOR:
|
||||
case SPRUCE_FENCE_GATE:
|
||||
case BIRCH_FENCE_GATE:
|
||||
case JUNGLE_FENCE_GATE:
|
||||
case ACACIA_FENCE_GATE:
|
||||
case DARK_OAK_FENCE_GATE:
|
||||
case OAK_FENCE_GATE:
|
||||
case POWERED_RAIL:
|
||||
return;
|
||||
default:*/
|
||||
Location location = BukkitUtil.getLocation(block.getLocation());
|
||||
PlotArea area = location.getPlotArea();
|
||||
if (area == null) {
|
||||
@ -510,7 +381,6 @@ public class PlayerEvents extends PlotListener implements Listener {
|
||||
}
|
||||
event.setNewCurrent(0);
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
|
||||
@ -908,21 +778,15 @@ public class PlayerEvents extends PlotListener implements Listener {
|
||||
}
|
||||
}
|
||||
if (Settings.Enabled_Components.KILL_ROAD_VEHICLES) {
|
||||
switch (vehicle.getType()) {
|
||||
case BOAT:
|
||||
case ENDER_CRYSTAL:
|
||||
case MINECART:
|
||||
case MINECART_CHEST:
|
||||
case MINECART_COMMAND:
|
||||
case MINECART_FURNACE:
|
||||
case MINECART_HOPPER:
|
||||
case MINECART_MOB_SPAWNER:
|
||||
case MINECART_TNT: {
|
||||
final com.sk89q.worldedit.world.entity.EntityType entityType = BukkitAdapter.adapt(vehicle.getType());
|
||||
// Horses etc are vehicles, but they're also animals
|
||||
// so this filters out all living entities
|
||||
if (EntityCategories.VEHICLE.contains(entityType) && !EntityCategories.ANIMAL.contains(entityType)) {
|
||||
List<MetadataValue> meta = vehicle.getMetadata("plot");
|
||||
Plot toPlot = BukkitUtil.getLocation(to).getPlot();
|
||||
if (!meta.isEmpty()) {
|
||||
Plot origin = (Plot) meta.get(0).value();
|
||||
if (!origin.getBasePlot(false).equals(toPlot)) {
|
||||
if (origin != null && !origin.getBasePlot(false).equals(toPlot)) {
|
||||
vehicle.remove();
|
||||
}
|
||||
} else if (toPlot != null) {
|
||||
@ -932,7 +796,6 @@ public class PlayerEvents extends PlotListener implements Listener {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -2640,30 +2503,41 @@ public class PlayerEvents extends PlotListener implements Listener {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
} else if (!plot.isAdded(pp.getUUID())) {
|
||||
Entity entity = event.getRightClicked();
|
||||
if (entity instanceof Monster && plot.getFlag(HostileInteractFlag.class)) {
|
||||
final Entity entity = event.getRightClicked();
|
||||
final com.sk89q.worldedit.world.entity.EntityType entityType = BukkitAdapter.adapt(entity.getType());
|
||||
|
||||
if (EntityCategories.HOSTILE.contains(entityType) && plot.getFlag(HostileInteractFlag.class)) {
|
||||
return;
|
||||
}
|
||||
if ((entity instanceof Animals || entity instanceof Golem) && plot.getFlag(
|
||||
AnimalInteractFlag.class)) {
|
||||
|
||||
if (EntityCategories.ANIMAL.contains(entityType) && plot.getFlag(AnimalInteractFlag.class)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// This actually makes use of the interface, so we don't use the
|
||||
// category
|
||||
if (entity instanceof Tameable && ((Tameable) entity).isTamed() && plot
|
||||
.getFlag(TamedInteractFlag.class)) {
|
||||
return;
|
||||
}
|
||||
if (entity instanceof Vehicle && plot.getFlag(VehicleUseFlag.class)) {
|
||||
|
||||
if (EntityCategories.VEHICLE.contains(entityType) && plot.getFlag(VehicleUseFlag.class)) {
|
||||
return;
|
||||
}
|
||||
if (entity instanceof Player && plot.getFlag(PlayerInteractFlag.class)) {
|
||||
|
||||
if (EntityCategories.PLAYER.contains(entityType) && plot.getFlag(PlayerInteractFlag.class)) {
|
||||
return;
|
||||
}
|
||||
if (entity instanceof Villager && plot.getFlag(VillagerInteractFlag.class)) {
|
||||
|
||||
if (EntityCategories.VILLAGER.contains(entityType) && plot.getFlag(VillagerInteractFlag.class)) {
|
||||
return;
|
||||
}
|
||||
if (entity instanceof ItemFrame && plot.getFlag(MiscInteractFlag.class)) {
|
||||
|
||||
if ((EntityCategories.HANGING.contains(entityType) ||
|
||||
EntityCategories.OTHER.contains(entityType)) && plot.getFlag(MiscInteractFlag.class)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Permissions.hasPermission(pp, Captions.PERMISSION_ADMIN_INTERACT_OTHER)) {
|
||||
MainUtil.sendMessage(pp, Captions.NO_PERMISSION_EVENT,
|
||||
Captions.PERMISSION_ADMIN_INTERACT_OTHER);
|
||||
@ -2866,7 +2740,9 @@ public class PlayerEvents extends PlotListener implements Listener {
|
||||
}
|
||||
if (player != null) {
|
||||
PlotPlayer plotPlayer = BukkitUtil.getPlayer(player);
|
||||
if (victim instanceof Hanging) { // hanging
|
||||
final com.sk89q.worldedit.world.entity.EntityType 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)) {
|
||||
@ -2894,8 +2770,7 @@ public class PlayerEvents extends PlotListener implements Listener {
|
||||
"plots.admin.destroy." + stub);
|
||||
return false;
|
||||
}
|
||||
} else if (victim instanceof Monster
|
||||
|| victim instanceof EnderDragon) { // victim is monster
|
||||
} else if (EntityCategories.HOSTILE.contains(entityType)) {
|
||||
if (plot != null && (plot.getFlag(HostileAttackFlag.class) || plot
|
||||
.getFlag(PveFlag.class) || plot.isAdded(plotPlayer.getUUID()))) {
|
||||
return true;
|
||||
@ -2905,7 +2780,7 @@ public class PlayerEvents extends PlotListener implements Listener {
|
||||
"plots.admin.pve." + stub);
|
||||
return false;
|
||||
}
|
||||
} else if (victim instanceof Tameable) { // victim is tameable
|
||||
} else if (EntityCategories.TAMEABLE.contains(entityType)) { // victim is tameable
|
||||
if (plot != null && (plot.getFlag(TamedAttackFlag.class) || plot
|
||||
.getFlag(PveFlag.class) || plot.isAdded(plotPlayer.getUUID()))) {
|
||||
return true;
|
||||
@ -2915,7 +2790,7 @@ public class PlayerEvents extends PlotListener implements Listener {
|
||||
"plots.admin.pve." + stub);
|
||||
return false;
|
||||
}
|
||||
} else if (victim instanceof Player) {
|
||||
} else if (EntityCategories.PLAYER.contains(entityType)) {
|
||||
if (plot != null) {
|
||||
if (!plot.getFlag(PvpFlag.class) && !Permissions
|
||||
.hasPermission(plotPlayer, "plots.admin.pvp." + stub)) {
|
||||
@ -2931,7 +2806,7 @@ public class PlayerEvents extends PlotListener implements Listener {
|
||||
"plots.admin.pvp." + stub);
|
||||
return false;
|
||||
}
|
||||
} else if (victim instanceof Creature) { // victim is animal
|
||||
} else if (EntityCategories.ANIMAL.contains(entityType)) { // victim is animal
|
||||
if (plot != null && (plot.getFlag(AnimalAttackFlag.class) || plot
|
||||
.getFlag(PveFlag.class) || plot.isAdded(plotPlayer.getUUID()))) {
|
||||
return true;
|
||||
@ -2941,7 +2816,7 @@ public class PlayerEvents extends PlotListener implements Listener {
|
||||
"plots.admin.pve." + stub);
|
||||
return false;
|
||||
}
|
||||
} else if (victim instanceof Vehicle) { // Vehicles are managed in vehicle destroy event
|
||||
} else if (EntityCategories.VEHICLE.contains(entityType)) { // Vehicles are managed in vehicle destroy event
|
||||
return true;
|
||||
} else { // victim is something else
|
||||
if (plot != null && (plot.getFlag(PveFlag.class) || plot
|
||||
@ -3104,4 +2979,5 @@ public class PlayerEvents extends PlotListener implements Listener {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -58,13 +58,42 @@ import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.block.data.Directional;
|
||||
import org.bukkit.block.data.type.WallSign;
|
||||
import org.bukkit.entity.Ambient;
|
||||
import org.bukkit.entity.Animals;
|
||||
import org.bukkit.entity.AreaEffectCloud;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.Boss;
|
||||
import org.bukkit.entity.EnderCrystal;
|
||||
import org.bukkit.entity.EnderSignal;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.EvokerFangs;
|
||||
import org.bukkit.entity.ExperienceOrb;
|
||||
import org.bukkit.entity.Explosive;
|
||||
import org.bukkit.entity.FallingBlock;
|
||||
import org.bukkit.entity.Firework;
|
||||
import org.bukkit.entity.Ghast;
|
||||
import org.bukkit.entity.Hanging;
|
||||
import org.bukkit.entity.IronGolem;
|
||||
import org.bukkit.entity.Item;
|
||||
import org.bukkit.entity.LightningStrike;
|
||||
import org.bukkit.entity.Monster;
|
||||
import org.bukkit.entity.NPC;
|
||||
import org.bukkit.entity.Phantom;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.entity.Shulker;
|
||||
import org.bukkit.entity.Slime;
|
||||
import org.bukkit.entity.Snowman;
|
||||
import org.bukkit.entity.Tameable;
|
||||
import org.bukkit.entity.Vehicle;
|
||||
import org.bukkit.entity.WaterMob;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@ -72,7 +101,6 @@ import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.IntConsumer;
|
||||
|
||||
|
||||
@SuppressWarnings({"unused", "WeakerAccess"})
|
||||
public class BukkitUtil extends WorldUtil {
|
||||
|
||||
@ -543,6 +571,76 @@ public class BukkitUtil extends WorldUtil {
|
||||
Bukkit.getPlayer(player.getUUID()).setFoodLevel(foodLevel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<com.sk89q.worldedit.world.entity.EntityType> getTypesInCategory(final String category) {
|
||||
final Collection<Class<?>> allowedInterfaces = new HashSet<>();
|
||||
switch (category) {
|
||||
case "animal": {
|
||||
allowedInterfaces.add(IronGolem.class);
|
||||
allowedInterfaces.add(Snowman.class);
|
||||
allowedInterfaces.add(Animals.class);
|
||||
allowedInterfaces.add(WaterMob.class);
|
||||
allowedInterfaces.add(Ambient.class);
|
||||
} break;
|
||||
case "tameable": {
|
||||
allowedInterfaces.add(Tameable.class);
|
||||
} break;
|
||||
case "vehicle": {
|
||||
allowedInterfaces.add(Vehicle.class);
|
||||
} break;
|
||||
case "hostile": {
|
||||
allowedInterfaces.add(Shulker.class);
|
||||
allowedInterfaces.add(Monster.class);
|
||||
allowedInterfaces.add(Boss.class);
|
||||
allowedInterfaces.add(Slime.class);
|
||||
allowedInterfaces.add(Ghast.class);
|
||||
allowedInterfaces.add(Phantom.class);
|
||||
allowedInterfaces.add(EnderCrystal.class);
|
||||
} break;
|
||||
case "hanging": {
|
||||
allowedInterfaces.add(Hanging.class);
|
||||
} break;
|
||||
case "villager": {
|
||||
allowedInterfaces.add(NPC.class);
|
||||
} break;
|
||||
case "projectile": {
|
||||
allowedInterfaces.add(Projectile.class);
|
||||
} break;
|
||||
case "other": {
|
||||
allowedInterfaces.add(ArmorStand.class);
|
||||
allowedInterfaces.add(FallingBlock.class);
|
||||
allowedInterfaces.add(Item.class);
|
||||
allowedInterfaces.add(Explosive.class);
|
||||
allowedInterfaces.add(AreaEffectCloud.class);
|
||||
allowedInterfaces.add(EvokerFangs.class);
|
||||
allowedInterfaces.add(LightningStrike.class);
|
||||
allowedInterfaces.add(ExperienceOrb.class);
|
||||
allowedInterfaces.add(EnderSignal.class);
|
||||
allowedInterfaces.add(Firework.class);
|
||||
} break;
|
||||
case "player": {
|
||||
allowedInterfaces.add(Player.class);
|
||||
} break;
|
||||
default: {
|
||||
PlotSquared.log(Captions.PREFIX + "Unknown entity category requested: " + category);
|
||||
} break;
|
||||
}
|
||||
final Set<com.sk89q.worldedit.world.entity.EntityType> types = new HashSet<>();
|
||||
outer: for (final EntityType bukkitType : EntityType.values()) {
|
||||
final Class<? extends Entity> entityClass = bukkitType.getEntityClass();
|
||||
if (entityClass == null) {
|
||||
continue;
|
||||
}
|
||||
for (final Class<?> allowedInterface : allowedInterfaces) {
|
||||
if (allowedInterface.isAssignableFrom(entityClass)) {
|
||||
types.add(BukkitAdapter.adapt(bukkitType));
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
private static void ensureLoaded(final String world, final int x, final int z, final Consumer<Chunk> chunkConsumer) {
|
||||
PaperLib.getChunkAtAsync(getWorld(world), x >> 4, z >> 4, true).thenAccept(chunk ->
|
||||
ensureMainThread(chunkConsumer, chunk));
|
||||
|
@ -1,739 +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.util;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
import org.bukkit.plugin.ServicePriority;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.logging.Level;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
/**
|
||||
* bStats collects some data for plugin authors.
|
||||
* <p>
|
||||
* Check out https://bStats.org/ to learn more about bStats!
|
||||
*/
|
||||
@SuppressWarnings({"WeakerAccess", "unused"})
|
||||
public class Metrics {
|
||||
|
||||
static {
|
||||
// You can use the property to disable the check in your test environment
|
||||
if (System.getProperty("bstats.relocatecheck") == null || !System.getProperty("bstats.relocatecheck").equals("false")) {
|
||||
// Maven's Relocate is clever and changes strings, too. So we have to use this little "trick" ... :D
|
||||
final String defaultPackage = new String(
|
||||
new byte[]{'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's', '.', 'b', 'u', 'k', 'k', 'i', 't'});
|
||||
final String examplePackage = new String(new byte[]{'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e'});
|
||||
// We want to make sure nobody just copy & pastes the example and use the wrong package names
|
||||
|
||||
if (Metrics.class.getPackage().getName().equals(defaultPackage) || Metrics.class.getPackage().getName().equals(examplePackage)) {
|
||||
throw new IllegalStateException("bStats Metrics class has not been relocated correctly!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The version of this bStats class
|
||||
public static final int B_STATS_VERSION = 1;
|
||||
|
||||
// The url to which the data is sent
|
||||
private static final String URL = "https://bStats.org/submitData/bukkit";
|
||||
|
||||
// Is bStats enabled on this server?
|
||||
private boolean enabled;
|
||||
|
||||
// Should failed requests be logged?
|
||||
private static boolean logFailedRequests;
|
||||
|
||||
// Should the sent data be logged?
|
||||
private static boolean logSentData;
|
||||
|
||||
// Should the response text be logged?
|
||||
private static boolean logResponseStatusText;
|
||||
|
||||
// The uuid of the server
|
||||
private static String serverUUID;
|
||||
|
||||
// The plugin
|
||||
private final Plugin plugin;
|
||||
|
||||
// The plugin id
|
||||
private final int bstatsId;
|
||||
|
||||
// A list with all custom charts
|
||||
private final List<CustomChart> charts = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param plugin The plugin which stats should be submitted.
|
||||
* @param bstatsId The ID of the plugin. It can be found in the url when you open the plugin on bStats.
|
||||
*/
|
||||
public Metrics(Plugin plugin, int bstatsId) {
|
||||
if (plugin == null) {
|
||||
throw new IllegalArgumentException("Plugin cannot be null!");
|
||||
}
|
||||
this.plugin = plugin;
|
||||
this.bstatsId = bstatsId;
|
||||
|
||||
// Get the config file
|
||||
File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats");
|
||||
File configFile = new File(bStatsFolder, "config.yml");
|
||||
YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile);
|
||||
|
||||
// Check if the config file exists
|
||||
if (!config.isSet("serverUuid")) {
|
||||
|
||||
// Add default values
|
||||
config.addDefault("enabled", true);
|
||||
// Every server gets it's unique random id.
|
||||
config.addDefault("serverUuid", UUID.randomUUID().toString());
|
||||
// Should failed request be logged?
|
||||
config.addDefault("logFailedRequests", false);
|
||||
// Should the sent data be logged?
|
||||
config.addDefault("logSentData", false);
|
||||
// Should the response text be logged?
|
||||
config.addDefault("logResponseStatusText", false);
|
||||
|
||||
// Inform the server owners about bStats
|
||||
config.options().header(
|
||||
"bStats collects some data for plugin authors like how many servers are using their plugins.\n" +
|
||||
"To honor their work, you should not disable it.\n" +
|
||||
"This has nearly no effect on the server performance!\n" +
|
||||
"Check out https://bStats.org/ to learn more :)"
|
||||
).copyDefaults(true);
|
||||
try {
|
||||
config.save(configFile);
|
||||
} catch (IOException ignored) { }
|
||||
}
|
||||
|
||||
// Load the data
|
||||
enabled = config.getBoolean("enabled", true);
|
||||
serverUUID = config.getString("serverUuid");
|
||||
logFailedRequests = config.getBoolean("logFailedRequests", false);
|
||||
logSentData = config.getBoolean("logSentData", false);
|
||||
logResponseStatusText = config.getBoolean("logResponseStatusText", false);
|
||||
|
||||
if (enabled) {
|
||||
boolean found = false;
|
||||
// Search for all other bStats Metrics classes to see if we are the first one
|
||||
for (Class<?> service : Bukkit.getServicesManager().getKnownServices()) {
|
||||
try {
|
||||
service.getField("B_STATS_VERSION"); // Our identifier :)
|
||||
found = true; // We aren't the first
|
||||
break;
|
||||
} catch (NoSuchFieldException ignored) { }
|
||||
}
|
||||
// Register our service
|
||||
Bukkit.getServicesManager().register(Metrics.class, this, plugin, ServicePriority.Normal);
|
||||
if (!found) {
|
||||
// We are the first!
|
||||
startSubmitting();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if bStats is enabled.
|
||||
*
|
||||
* @return Whether bStats is enabled or not.
|
||||
*/
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a custom chart.
|
||||
*
|
||||
* @param chart The chart to add.
|
||||
*/
|
||||
public void addCustomChart(CustomChart chart) {
|
||||
if (chart == null) {
|
||||
throw new IllegalArgumentException("Chart cannot be null!");
|
||||
}
|
||||
charts.add(chart);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the Scheduler which submits our data every 30 minutes.
|
||||
*/
|
||||
private void startSubmitting() {
|
||||
final Timer timer = new Timer(true); // We use a timer cause the Bukkit scheduler is affected by server lags
|
||||
timer.scheduleAtFixedRate(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!plugin.isEnabled()) { // Plugin was disabled
|
||||
timer.cancel();
|
||||
return;
|
||||
}
|
||||
// Nevertheless we want our code to run in the Bukkit main thread, so we have to use the Bukkit scheduler
|
||||
// Don't be afraid! The connection to the bStats server is still async, only the stats collection is sync ;)
|
||||
Bukkit.getScheduler().runTask(plugin, () -> submitData());
|
||||
}
|
||||
}, 1000 * 60 * 5, 1000 * 60 * 30);
|
||||
// Submit the data every 30 minutes, first time after 5 minutes to give other plugins enough time to start
|
||||
// WARNING: Changing the frequency has no effect but your plugin WILL be blocked/deleted!
|
||||
// WARNING: Just don't do it!
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the plugin specific data.
|
||||
* This method is called using Reflection.
|
||||
*
|
||||
* @return The plugin specific data.
|
||||
*/
|
||||
public JSONObject getPluginData() {
|
||||
JSONObject data = new JSONObject();
|
||||
|
||||
String pluginName = plugin.getDescription().getName();
|
||||
String pluginVersion = plugin.getDescription().getVersion();
|
||||
|
||||
data.put("pluginName", pluginName); // Append the name of the plugin
|
||||
data.put("id", bstatsId); // Append the id of the plugin
|
||||
data.put("pluginVersion", pluginVersion); // Append the version of the plugin
|
||||
JSONArray customCharts = new JSONArray();
|
||||
for (CustomChart customChart : charts) {
|
||||
// Add the data of the custom charts
|
||||
JSONObject chart = customChart.getRequestJsonObject();
|
||||
if (chart == null) { // If the chart is null, we skip it
|
||||
continue;
|
||||
}
|
||||
customCharts.add(chart);
|
||||
}
|
||||
data.put("customCharts", customCharts);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the server specific data.
|
||||
*
|
||||
* @return The server specific data.
|
||||
*/
|
||||
private JSONObject getServerData() {
|
||||
// Minecraft specific data
|
||||
int playerAmount;
|
||||
try {
|
||||
// Around MC 1.8 the return type was changed to a collection from an array,
|
||||
// This fixes java.lang.NoSuchMethodError: org.bukkit.Bukkit.getOnlinePlayers()Ljava/util/Collection;
|
||||
Method onlinePlayersMethod = Class.forName("org.bukkit.Server").getMethod("getOnlinePlayers");
|
||||
playerAmount = onlinePlayersMethod.getReturnType().equals(Collection.class)
|
||||
? ((Collection<?>) onlinePlayersMethod.invoke(Bukkit.getServer())).size()
|
||||
: ((Player[]) onlinePlayersMethod.invoke(Bukkit.getServer())).length;
|
||||
} catch (Exception e) {
|
||||
playerAmount = Bukkit.getOnlinePlayers().size(); // Just use the new method if the Reflection failed
|
||||
}
|
||||
int onlineMode = Bukkit.getOnlineMode() ? 1 : 0;
|
||||
String bukkitVersion = Bukkit.getVersion();
|
||||
|
||||
// OS/Java specific data
|
||||
String javaVersion = System.getProperty("java.version");
|
||||
String osName = System.getProperty("os.name");
|
||||
String osArch = System.getProperty("os.arch");
|
||||
String osVersion = System.getProperty("os.version");
|
||||
int coreCount = Runtime.getRuntime().availableProcessors();
|
||||
|
||||
JSONObject data = new JSONObject();
|
||||
|
||||
data.put("serverUUID", serverUUID);
|
||||
|
||||
data.put("playerAmount", playerAmount);
|
||||
data.put("onlineMode", onlineMode);
|
||||
data.put("bukkitVersion", bukkitVersion);
|
||||
|
||||
data.put("javaVersion", javaVersion);
|
||||
data.put("osName", osName);
|
||||
data.put("osArch", osArch);
|
||||
data.put("osVersion", osVersion);
|
||||
data.put("coreCount", coreCount);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects the data and sends it afterwards.
|
||||
*/
|
||||
private void submitData() {
|
||||
final JSONObject data = getServerData();
|
||||
|
||||
JSONArray pluginData = new JSONArray();
|
||||
// Search for all other bStats Metrics classes to get their plugin data
|
||||
for (Class<?> service : Bukkit.getServicesManager().getKnownServices()) {
|
||||
try {
|
||||
service.getField("B_STATS_VERSION"); // Our identifier :)
|
||||
|
||||
for (RegisteredServiceProvider<?> provider : Bukkit.getServicesManager().getRegistrations(service)) {
|
||||
try {
|
||||
pluginData.add(provider.getService().getMethod("getPluginData").invoke(provider.getProvider()));
|
||||
} catch (NullPointerException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) { }
|
||||
}
|
||||
} catch (NoSuchFieldException ignored) { }
|
||||
}
|
||||
|
||||
data.put("plugins", pluginData);
|
||||
|
||||
// Create a new thread for the connection to the bStats server
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
// Send the data
|
||||
sendData(plugin, data);
|
||||
} catch (Exception e) {
|
||||
// Something went wrong! :(
|
||||
if (logFailedRequests) {
|
||||
plugin.getLogger().log(Level.WARNING, "Could not submit plugin stats of " + plugin.getName(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the data to the bStats server.
|
||||
*
|
||||
* @param plugin Any plugin. It's just used to get a logger instance.
|
||||
* @param data The data to send.
|
||||
* @throws Exception If the request failed.
|
||||
*/
|
||||
private static void sendData(Plugin plugin, JSONObject data) throws Exception {
|
||||
if (data == null) {
|
||||
throw new IllegalArgumentException("Data cannot be null!");
|
||||
}
|
||||
if (Bukkit.isPrimaryThread()) {
|
||||
throw new IllegalAccessException("This method must not be called from the main thread!");
|
||||
}
|
||||
if (logSentData) {
|
||||
plugin.getLogger().info("Sending data to bStats: " + data.toString());
|
||||
}
|
||||
HttpsURLConnection connection = (HttpsURLConnection) new URL(URL).openConnection();
|
||||
|
||||
// Compress the data to save bandwidth
|
||||
byte[] compressedData = compress(data.toString());
|
||||
|
||||
// Add headers
|
||||
connection.setRequestMethod("POST");
|
||||
connection.addRequestProperty("Accept", "application/json");
|
||||
connection.addRequestProperty("Connection", "close");
|
||||
connection.addRequestProperty("Content-Encoding", "gzip"); // We gzip our request
|
||||
connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length));
|
||||
connection.setRequestProperty("Content-Type", "application/json"); // We send our data in JSON format
|
||||
connection.setRequestProperty("User-Agent", "MC-Server/" + B_STATS_VERSION);
|
||||
|
||||
// Send data
|
||||
connection.setDoOutput(true);
|
||||
DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());
|
||||
outputStream.write(compressedData);
|
||||
outputStream.flush();
|
||||
outputStream.close();
|
||||
|
||||
InputStream inputStream = connection.getInputStream();
|
||||
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
String line;
|
||||
while ((line = bufferedReader.readLine()) != null) {
|
||||
builder.append(line);
|
||||
}
|
||||
bufferedReader.close();
|
||||
if (logResponseStatusText) {
|
||||
plugin.getLogger().info("Sent data to bStats and received response: " + builder.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gzips the given String.
|
||||
*
|
||||
* @param str The string to gzip.
|
||||
* @return The gzipped String.
|
||||
* @throws IOException If the compression failed.
|
||||
*/
|
||||
private static byte[] compress(final String str) throws IOException {
|
||||
if (str == null) {
|
||||
return null;
|
||||
}
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
GZIPOutputStream gzip = new GZIPOutputStream(outputStream);
|
||||
gzip.write(str.getBytes(StandardCharsets.UTF_8));
|
||||
gzip.close();
|
||||
return outputStream.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom chart.
|
||||
*/
|
||||
public static abstract class CustomChart {
|
||||
|
||||
// The id of the chart
|
||||
final String chartId;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
*/
|
||||
CustomChart(String chartId) {
|
||||
if (chartId == null || chartId.isEmpty()) {
|
||||
throw new IllegalArgumentException("ChartId cannot be null or empty!");
|
||||
}
|
||||
this.chartId = chartId;
|
||||
}
|
||||
|
||||
private JSONObject getRequestJsonObject() {
|
||||
JSONObject chart = new JSONObject();
|
||||
chart.put("chartId", chartId);
|
||||
try {
|
||||
JSONObject data = getChartData();
|
||||
if (data == null) {
|
||||
// If the data is null we don't send the chart.
|
||||
return null;
|
||||
}
|
||||
chart.put("data", data);
|
||||
} catch (Throwable t) {
|
||||
if (logFailedRequests) {
|
||||
Bukkit.getLogger().log(Level.WARNING, "Failed to get data for custom chart with id " + chartId, t);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return chart;
|
||||
}
|
||||
|
||||
protected abstract JSONObject getChartData() throws Exception;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom simple pie.
|
||||
*/
|
||||
public static class SimplePie extends CustomChart {
|
||||
|
||||
private final Callable<String> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public SimplePie(String chartId, Callable<String> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JSONObject getChartData() throws Exception {
|
||||
JSONObject data = new JSONObject();
|
||||
String value = callable.call();
|
||||
if (value == null || value.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.put("value", value);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom advanced pie.
|
||||
*/
|
||||
public static class AdvancedPie extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, Integer>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public AdvancedPie(String chartId, Callable<Map<String, Integer>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JSONObject getChartData() throws Exception {
|
||||
JSONObject data = new JSONObject();
|
||||
JSONObject values = new JSONObject();
|
||||
Map<String, Integer> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
boolean allSkipped = true;
|
||||
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
||||
if (entry.getValue() == 0) {
|
||||
continue; // Skip this invalid
|
||||
}
|
||||
allSkipped = false;
|
||||
values.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
if (allSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.put("values", values);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom drilldown pie.
|
||||
*/
|
||||
public static class DrilldownPie extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, Map<String, Integer>>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public DrilldownPie(String chartId, Callable<Map<String, Map<String, Integer>>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSONObject getChartData() throws Exception {
|
||||
JSONObject data = new JSONObject();
|
||||
JSONObject values = new JSONObject();
|
||||
Map<String, Map<String, Integer>> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
boolean reallyAllSkipped = true;
|
||||
for (Map.Entry<String, Map<String, Integer>> entryValues : map.entrySet()) {
|
||||
JSONObject value = new JSONObject();
|
||||
boolean allSkipped = true;
|
||||
for (Map.Entry<String, Integer> valueEntry : map.get(entryValues.getKey()).entrySet()) {
|
||||
value.put(valueEntry.getKey(), valueEntry.getValue());
|
||||
allSkipped = false;
|
||||
}
|
||||
if (!allSkipped) {
|
||||
reallyAllSkipped = false;
|
||||
values.put(entryValues.getKey(), value);
|
||||
}
|
||||
}
|
||||
if (reallyAllSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.put("values", values);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom single line chart.
|
||||
*/
|
||||
public static class SingleLineChart extends CustomChart {
|
||||
|
||||
private final Callable<Integer> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public SingleLineChart(String chartId, Callable<Integer> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JSONObject getChartData() throws Exception {
|
||||
JSONObject data = new JSONObject();
|
||||
int value = callable.call();
|
||||
if (value == 0) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.put("value", value);
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom multi line chart.
|
||||
*/
|
||||
public static class MultiLineChart extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, Integer>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public MultiLineChart(String chartId, Callable<Map<String, Integer>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JSONObject getChartData() throws Exception {
|
||||
JSONObject data = new JSONObject();
|
||||
JSONObject values = new JSONObject();
|
||||
Map<String, Integer> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
boolean allSkipped = true;
|
||||
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
||||
if (entry.getValue() == 0) {
|
||||
continue; // Skip this invalid
|
||||
}
|
||||
allSkipped = false;
|
||||
values.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
if (allSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.put("values", values);
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom simple bar chart.
|
||||
*/
|
||||
public static class SimpleBarChart extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, Integer>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public SimpleBarChart(String chartId, Callable<Map<String, Integer>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JSONObject getChartData() throws Exception {
|
||||
JSONObject data = new JSONObject();
|
||||
JSONObject values = new JSONObject();
|
||||
Map<String, Integer> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
||||
JSONArray categoryValues = new JSONArray();
|
||||
categoryValues.add(entry.getValue());
|
||||
values.put(entry.getKey(), categoryValues);
|
||||
}
|
||||
data.put("values", values);
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom advanced bar chart.
|
||||
*/
|
||||
public static class AdvancedBarChart extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, int[]>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public AdvancedBarChart(String chartId, Callable<Map<String, int[]>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JSONObject getChartData() throws Exception {
|
||||
JSONObject data = new JSONObject();
|
||||
JSONObject values = new JSONObject();
|
||||
Map<String, int[]> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
boolean allSkipped = true;
|
||||
for (Map.Entry<String, int[]> entry : map.entrySet()) {
|
||||
if (entry.getValue().length == 0) {
|
||||
continue; // Skip this invalid
|
||||
}
|
||||
allSkipped = false;
|
||||
JSONArray categoryValues = new JSONArray();
|
||||
for (int categoryValue : entry.getValue()) {
|
||||
categoryValues.add(categoryValue);
|
||||
}
|
||||
values.put(entry.getKey(), categoryValues);
|
||||
}
|
||||
if (allSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.put("values", values);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -25,29 +25,27 @@
|
||||
*/
|
||||
package com.plotsquared.bukkit.util.uuid;
|
||||
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.plotsquared.core.PlotSquared;
|
||||
import com.plotsquared.core.config.Captions;
|
||||
import com.plotsquared.core.config.Settings;
|
||||
import com.plotsquared.core.player.OfflinePlotPlayer;
|
||||
import com.plotsquared.core.util.task.RunnableVal;
|
||||
import com.plotsquared.core.util.StringWrapper;
|
||||
import com.plotsquared.core.plot.expiration.ExpireManager;
|
||||
import com.plotsquared.core.util.StringMan;
|
||||
import com.plotsquared.core.util.StringWrapper;
|
||||
import com.plotsquared.core.util.task.RunnableVal;
|
||||
import com.plotsquared.core.util.task.TaskManager;
|
||||
import com.plotsquared.core.util.uuid.UUIDHandler;
|
||||
import com.plotsquared.core.util.uuid.UUIDHandlerImplementation;
|
||||
import com.plotsquared.core.plot.expiration.ExpireManager;
|
||||
import com.plotsquared.core.util.uuid.UUIDWrapper;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.NBTInputStream;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.util.Map;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
@ -56,7 +54,9 @@ import java.nio.file.Files;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
public class FileUUIDHandler extends UUIDHandlerImplementation {
|
||||
|
||||
|
@ -75,6 +75,7 @@ shadowJar {
|
||||
include(dependency("net.kyori:text-serializer-plain:3.0.2"))
|
||||
}
|
||||
relocate('net.kyori.text', 'com.plotsquared.formatting.text')
|
||||
relocate("org.json", "com.plotsquared.json")
|
||||
}
|
||||
|
||||
shadowJar.doLast {
|
||||
|
@ -25,13 +25,6 @@
|
||||
*/
|
||||
package com.plotsquared.core;
|
||||
|
||||
import com.plotsquared.core.configuration.ConfigurationSection;
|
||||
import com.plotsquared.core.configuration.MemorySection;
|
||||
import com.plotsquared.core.configuration.file.YamlConfiguration;
|
||||
import com.plotsquared.core.configuration.serialization.ConfigurationSerialization;
|
||||
import com.plotsquared.core.location.Location;
|
||||
import com.plotsquared.core.player.ConsolePlayer;
|
||||
import com.plotsquared.core.player.PlotPlayer;
|
||||
import com.plotsquared.core.command.WE_Anywhere;
|
||||
import com.plotsquared.core.config.Caption;
|
||||
import com.plotsquared.core.config.CaptionUtility;
|
||||
@ -39,6 +32,10 @@ import com.plotsquared.core.config.Captions;
|
||||
import com.plotsquared.core.config.Configuration;
|
||||
import com.plotsquared.core.config.Settings;
|
||||
import com.plotsquared.core.config.Storage;
|
||||
import com.plotsquared.core.configuration.ConfigurationSection;
|
||||
import com.plotsquared.core.configuration.MemorySection;
|
||||
import com.plotsquared.core.configuration.file.YamlConfiguration;
|
||||
import com.plotsquared.core.configuration.serialization.ConfigurationSerialization;
|
||||
import com.plotsquared.core.database.DBFunc;
|
||||
import com.plotsquared.core.database.Database;
|
||||
import com.plotsquared.core.database.MySQL;
|
||||
@ -49,8 +46,9 @@ import com.plotsquared.core.generator.HybridPlotWorld;
|
||||
import com.plotsquared.core.generator.HybridUtils;
|
||||
import com.plotsquared.core.generator.IndependentPlotGenerator;
|
||||
import com.plotsquared.core.listener.WESubscriber;
|
||||
import com.plotsquared.core.plot.comment.CommentManager;
|
||||
import com.plotsquared.core.util.ChatManager;
|
||||
import com.plotsquared.core.location.Location;
|
||||
import com.plotsquared.core.player.ConsolePlayer;
|
||||
import com.plotsquared.core.player.PlotPlayer;
|
||||
import com.plotsquared.core.plot.BlockBucket;
|
||||
import com.plotsquared.core.plot.Plot;
|
||||
import com.plotsquared.core.plot.PlotArea;
|
||||
@ -59,29 +57,31 @@ import com.plotsquared.core.plot.PlotCluster;
|
||||
import com.plotsquared.core.plot.PlotFilter;
|
||||
import com.plotsquared.core.plot.PlotId;
|
||||
import com.plotsquared.core.plot.PlotManager;
|
||||
import com.plotsquared.core.util.StringWrapper;
|
||||
import com.plotsquared.core.util.ChunkManager;
|
||||
import com.plotsquared.core.util.EconHandler;
|
||||
import com.plotsquared.core.util.EventDispatcher;
|
||||
import com.plotsquared.core.util.LegacyConverter;
|
||||
import com.plotsquared.core.util.MathMan;
|
||||
import com.plotsquared.core.util.SchematicHandler;
|
||||
import com.plotsquared.core.util.StringMan;
|
||||
import com.plotsquared.core.util.logger.ILogger;
|
||||
import com.plotsquared.core.plot.comment.CommentManager;
|
||||
import com.plotsquared.core.plot.expiration.ExpireManager;
|
||||
import com.plotsquared.core.plot.expiration.ExpiryTask;
|
||||
import com.plotsquared.core.plot.world.DefaultPlotAreaManager;
|
||||
import com.plotsquared.core.plot.world.PlotAreaManager;
|
||||
import com.plotsquared.core.plot.world.SinglePlotArea;
|
||||
import com.plotsquared.core.plot.world.SinglePlotAreaManager;
|
||||
import com.plotsquared.core.queue.GlobalBlockQueue;
|
||||
import com.plotsquared.core.plot.expiration.ExpireManager;
|
||||
import com.plotsquared.core.plot.expiration.ExpiryTask;
|
||||
import com.plotsquared.core.util.ChatManager;
|
||||
import com.plotsquared.core.util.ChunkManager;
|
||||
import com.plotsquared.core.util.EconHandler;
|
||||
import com.plotsquared.core.util.EventDispatcher;
|
||||
import com.plotsquared.core.util.InventoryUtil;
|
||||
import com.plotsquared.core.util.LegacyConverter;
|
||||
import com.plotsquared.core.util.MainUtil;
|
||||
import com.plotsquared.core.util.MathMan;
|
||||
import com.plotsquared.core.util.ReflectionUtils;
|
||||
import com.plotsquared.core.util.SchematicHandler;
|
||||
import com.plotsquared.core.util.SetupUtils;
|
||||
import com.plotsquared.core.util.StringMan;
|
||||
import com.plotsquared.core.util.StringWrapper;
|
||||
import com.plotsquared.core.util.WorldUtil;
|
||||
import com.plotsquared.core.util.uuid.UUIDHandler;
|
||||
import com.plotsquared.core.util.logger.ILogger;
|
||||
import com.plotsquared.core.util.task.TaskManager;
|
||||
import com.plotsquared.core.util.uuid.UUIDHandler;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
@ -90,17 +90,38 @@ import lombok.NonNull;
|
||||
import lombok.Setter;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.*;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.sql.SQLException;
|
||||
import java.util.*;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.zip.ZipEntry;
|
||||
@ -399,8 +420,8 @@ import java.util.zip.ZipInputStream;
|
||||
UUIDHandler.add(new StringWrapper("*"), DBFunc.EVERYONE);
|
||||
forEachPlotRaw(plot -> {
|
||||
if (plot.hasOwner() && plot.temp != -1) {
|
||||
if (UUIDHandler.getName(plot.owner) == null) {
|
||||
UUIDHandler.implementation.unknown.add(plot.owner);
|
||||
if (UUIDHandler.getName(plot.getOwnerAbs()) == null) {
|
||||
UUIDHandler.implementation.unknown.add(plot.getOwnerAbs());
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -425,11 +446,11 @@ import java.util.zip.ZipInputStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if `version` is >= `version2`.
|
||||
* Check if `version` is >= `version2`.
|
||||
*
|
||||
* @param version First version
|
||||
* @param version2 Second version
|
||||
* @return true if `version` is >= `version2`
|
||||
* @return true if `version` is >= `version2`
|
||||
*/
|
||||
public boolean checkVersion(int[] version, int... version2) {
|
||||
return version[0] > version2[0] || version[0] == version2[0] && version[1] > version2[1]
|
||||
@ -788,7 +809,7 @@ import java.util.zip.ZipInputStream;
|
||||
} else {
|
||||
list = new ArrayList<>(input);
|
||||
}
|
||||
list.sort(Comparator.comparingLong(a -> ExpireManager.IMP.getTimestamp(a.owner)));
|
||||
list.sort(Comparator.comparingLong(a -> ExpireManager.IMP.getTimestamp(a.getOwnerAbs())));
|
||||
return list;
|
||||
}
|
||||
|
||||
@ -2055,7 +2076,7 @@ import java.util.zip.ZipInputStream;
|
||||
*
|
||||
* @param alias to search plots
|
||||
* @param worldname to filter alias to a specific world [optional] null means all worlds
|
||||
* @return Set<{ @ link Plot }> empty if nothing found
|
||||
* @return Set<{@link Plot }> empty if nothing found
|
||||
*/
|
||||
public Set<Plot> getPlotsByAlias(@Nullable final String alias,
|
||||
@NonNull final String worldname) {
|
||||
|
@ -162,7 +162,7 @@ public class Auto extends SubCommand {
|
||||
return;
|
||||
}
|
||||
whenDone.value = plot;
|
||||
plot.owner = player.getUUID();
|
||||
plot.setOwnerAbs(player.getUUID());
|
||||
DBFunc.createPlotSafe(plot, whenDone,
|
||||
() -> autoClaimFromDatabase(player, area, plot.getId(), whenDone));
|
||||
}
|
||||
|
@ -82,8 +82,8 @@ public class Buy extends Command {
|
||||
confirm.run(this, () -> {
|
||||
Captions.REMOVED_BALANCE.send(player, price);
|
||||
EconHandler.manager
|
||||
.depositMoney(UUIDHandler.getUUIDWrapper().getOfflinePlayer(plot.owner), price);
|
||||
PlotPlayer owner = UUIDHandler.getPlayer(plot.owner);
|
||||
.depositMoney(UUIDHandler.getUUIDWrapper().getOfflinePlayer(plot.getOwnerAbs()), price);
|
||||
PlotPlayer owner = UUIDHandler.getPlayer(plot.getOwnerAbs());
|
||||
if (owner != null) {
|
||||
Captions.PLOT_SOLD.send(owner, plot.getId(), player.getName(), price);
|
||||
}
|
||||
|
84
Core/src/main/java/com/plotsquared/core/command/Caps.java
Normal file
84
Core/src/main/java/com/plotsquared/core/command/Caps.java
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* _____ _ _ _____ _
|
||||
* | __ \| | | | / ____| | |
|
||||
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
||||
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
||||
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
||||
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
||||
* | |
|
||||
* |_|
|
||||
* 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.command;
|
||||
|
||||
import com.plotsquared.core.config.Captions;
|
||||
import com.plotsquared.core.player.PlotPlayer;
|
||||
import com.plotsquared.core.plot.Plot;
|
||||
import com.plotsquared.core.plot.flag.PlotFlag;
|
||||
import com.plotsquared.core.plot.flag.implementations.AnimalCapFlag;
|
||||
import com.plotsquared.core.plot.flag.implementations.EntityCapFlag;
|
||||
import com.plotsquared.core.plot.flag.implementations.HostileCapFlag;
|
||||
import com.plotsquared.core.plot.flag.implementations.MiscCapFlag;
|
||||
import com.plotsquared.core.plot.flag.implementations.MobCapFlag;
|
||||
import com.plotsquared.core.plot.flag.implementations.VehicleCapFlag;
|
||||
import com.plotsquared.core.util.Permissions;
|
||||
|
||||
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_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;
|
||||
|
||||
@CommandDeclaration(command = "caps",
|
||||
category = CommandCategory.INFO,
|
||||
description = "Show plot mob caps",
|
||||
usage = "/plot caps")
|
||||
public class Caps extends SubCommand {
|
||||
|
||||
@Override public boolean onCommand(final PlotPlayer player, final String[] args) {
|
||||
final Plot plot = player.getCurrentPlot();
|
||||
if (plot == null) {
|
||||
return Captions.NOT_IN_PLOT.send(player);
|
||||
}
|
||||
if (!plot.isAdded(player.getUUID()) && !Permissions
|
||||
.hasPermission(player, Captions.PERMISSION_ADMIN_CAPS_OTHER)) {
|
||||
return Captions.NO_PERMISSION.send(player, Captions.PERMISSION_ADMIN_CAPS_OTHER);
|
||||
}
|
||||
Captions.PLOT_CAPS_HEADER.send(player);
|
||||
final int[] countedEntities = plot.countEntities();
|
||||
sendFormatted(plot, player, MobCapFlag.class, countedEntities, "mobs", CAP_MOB);
|
||||
sendFormatted(plot, player, HostileCapFlag.class, countedEntities, "hostile", CAP_MONSTER);
|
||||
sendFormatted(plot, player, AnimalCapFlag.class, countedEntities, "animals", CAP_ANIMAL);
|
||||
sendFormatted(plot, player, VehicleCapFlag.class, countedEntities, "vehicle", CAP_VEHICLE);
|
||||
sendFormatted(plot, player, MiscCapFlag.class, countedEntities, "misc", CAP_MISC);
|
||||
sendFormatted(plot, player, EntityCapFlag.class, countedEntities, "entities", CAP_ENTITY);
|
||||
return true;
|
||||
}
|
||||
|
||||
private <T extends PlotFlag<Integer, T>> void sendFormatted(final Plot plot,
|
||||
final PlotPlayer player, final Class<T> capFlag, final int[] countedEntities,
|
||||
final String name, final int type) {
|
||||
final int current = countedEntities[type];
|
||||
final int max = plot.getFlag(capFlag);
|
||||
final String percentage = String.format("%.1f", 100 * ((float) current / max));
|
||||
player.sendMessage(Captions.PLOT_CAPS_FORMAT.getTranslated().replace("%cap%", name)
|
||||
.replace("%current%", Integer.toString(current))
|
||||
.replace("%limit%", Integer.toString(max)).replace("%percentage%", percentage));
|
||||
}
|
||||
|
||||
}
|
@ -128,7 +128,7 @@ public class Claim extends SubCommand {
|
||||
if (border != Integer.MAX_VALUE && plot.getDistanceFromOrigin() > border && !force) {
|
||||
return !sendMessage(player, Captions.BORDER);
|
||||
}
|
||||
plot.owner = player.getUUID();
|
||||
plot.setOwnerAbs(player.getUUID());
|
||||
final String finalSchematic = schematic;
|
||||
DBFunc.createPlotSafe(plot, () -> TaskManager.IMP.sync(new RunnableVal<Object>() {
|
||||
@Override public void run(Object value) {
|
||||
@ -136,7 +136,7 @@ public class Claim extends SubCommand {
|
||||
PlotSquared.get().getLogger().log(Captions.PREFIX.getTranslated() +
|
||||
String.format("Failed to claim plot %s", plot.getId().toCommaSeparatedString()));
|
||||
sendMessage(player, Captions.PLOT_NOT_CLAIMED);
|
||||
plot.owner = null;
|
||||
plot.setOwnerAbs(null);
|
||||
} else if (area.isAutoMerge()) {
|
||||
PlotMergeEvent event = PlotSquared.get().getEventDispatcher()
|
||||
.callMerge(plot, Direction.ALL, Integer.MAX_VALUE, player);
|
||||
@ -151,7 +151,7 @@ public class Claim extends SubCommand {
|
||||
PlotSquared.get().getLogger().log(Captions.PREFIX.getTranslated() +
|
||||
String.format("Failed to add plot %s to the database", plot.getId().toCommaSeparatedString()));
|
||||
sendMessage(player, Captions.PLOT_NOT_CLAIMED);
|
||||
plot.owner = null;
|
||||
plot.setOwnerAbs(null);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
@ -31,8 +31,12 @@ import com.plotsquared.core.player.PlotPlayer;
|
||||
import com.plotsquared.core.util.ChunkManager;
|
||||
import com.plotsquared.core.util.MainUtil;
|
||||
import com.plotsquared.core.util.StringMan;
|
||||
import com.plotsquared.core.util.entity.EntityCategories;
|
||||
import com.plotsquared.core.util.entity.EntityCategory;
|
||||
import com.plotsquared.core.util.task.TaskManager;
|
||||
import com.sk89q.worldedit.world.entity.EntityType;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.Map;
|
||||
|
||||
@CommandDeclaration(command = "debug",
|
||||
@ -59,6 +63,31 @@ public class Debug extends SubCommand {
|
||||
Thread.currentThread().getName()));
|
||||
return true;
|
||||
}
|
||||
if (args.length > 0 && "entitytypes".equalsIgnoreCase(args[0])) {
|
||||
EntityCategories.init();
|
||||
player.sendMessage(Captions.PREFIX.getTranslated() + "§cEntity Categories: ");
|
||||
EntityCategory.REGISTRY.forEach(category -> {
|
||||
final StringBuilder builder = new StringBuilder("§7- §6")
|
||||
.append(category.getId()).append("§7: §6");
|
||||
for (final EntityType entityType : category.getAll()) {
|
||||
builder.append(entityType.getId()).append(" ");
|
||||
}
|
||||
player.sendMessage(Captions.PREFIX.getTranslated() + builder.toString());
|
||||
});
|
||||
EntityType.REGISTRY.values().stream()
|
||||
.sorted(Comparator.comparing(EntityType::getId))
|
||||
.forEach(entityType -> {
|
||||
long categoryCount = EntityCategory.REGISTRY.values()
|
||||
.stream()
|
||||
.filter(category -> category.contains(entityType))
|
||||
.count();
|
||||
if (categoryCount > 0) {
|
||||
return;
|
||||
}
|
||||
player.sendMessage(Captions.PREFIX.getTranslated() + entityType.getName() + " is in " + categoryCount + " categories");
|
||||
});
|
||||
return true;
|
||||
}
|
||||
if ((args.length > 0) && args[0].equalsIgnoreCase("msg")) {
|
||||
StringBuilder msg = new StringBuilder();
|
||||
for (Captions caption : Captions.values()) {
|
||||
|
@ -60,6 +60,7 @@ public class MainCommand extends Command {
|
||||
public static MainCommand getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new MainCommand();
|
||||
new Caps();
|
||||
new Buy();
|
||||
new Save();
|
||||
new Load();
|
||||
|
@ -76,7 +76,7 @@ public class Owner extends SetCommand {
|
||||
uuid = null;
|
||||
}
|
||||
PlotChangeOwnerEvent event = PlotSquared.get().getEventDispatcher()
|
||||
.callOwnerChange(player, plot, plot.hasOwner() ? plot.owner : null, uuid,
|
||||
.callOwnerChange(player, plot, plot.hasOwner() ? plot.getOwnerAbs() : null, uuid,
|
||||
plot.hasOwner());
|
||||
if (event.getEventResult() == Result.DENY) {
|
||||
sendMessage(player, Captions.EVENT_DENIED, "Owner change");
|
||||
|
@ -144,7 +144,7 @@ public class Purge extends SubCommand {
|
||||
if (added != null && !plot.isAdded(added)) {
|
||||
continue;
|
||||
}
|
||||
if (unknown && UUIDHandler.getName(plot.owner) != null) {
|
||||
if (unknown && UUIDHandler.getName(plot.getOwnerAbs()) != null) {
|
||||
continue;
|
||||
}
|
||||
toDelete.addAll(plot.getConnectedPlots());
|
||||
@ -167,7 +167,7 @@ public class Purge extends SubCommand {
|
||||
if (added != null && !plot.isAdded(added)) {
|
||||
continue;
|
||||
}
|
||||
if (unknown && UUIDHandler.getName(plot.owner) != null) {
|
||||
if (unknown && UUIDHandler.getName(plot.getOwnerAbs()) != null) {
|
||||
continue;
|
||||
}
|
||||
toDelete.add(plot);
|
||||
|
@ -37,17 +37,18 @@ public interface Caption {
|
||||
return StringMan.replaceFromMap(getTranslated(), Captions.replacements);
|
||||
}
|
||||
|
||||
default void send(PlotPlayer caller, String... args) {
|
||||
send(caller, (Object[]) args);
|
||||
default boolean send(PlotPlayer caller, String... args) {
|
||||
return send(caller, (Object[]) args);
|
||||
}
|
||||
|
||||
default void send(PlotPlayer caller, Object... args) {
|
||||
default boolean send(PlotPlayer caller, Object... args) {
|
||||
String msg = CaptionUtility.format(caller, this, args);
|
||||
if (caller == null) {
|
||||
PlotSquared.log(msg);
|
||||
} else {
|
||||
caller.sendMessage(msg);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean usePrefix();
|
||||
|
@ -83,6 +83,7 @@ public enum Captions implements Caption {
|
||||
PERMISSION_COMMANDS_CHAT("plots.admin.command.chat", "static.permissions"),
|
||||
PERMISSION_MERGE_OTHER("plots.merge.other", "static.permissions"),
|
||||
PERMISSION_MERGE_KEEP_ROAD("plots.merge.keeproad", "static.permissions"),
|
||||
PERMISSION_ADMIN_CAPS_OTHER("plots.admin.caps.other", "static.permissions"),
|
||||
PERMISSION_ADMIN_DESTROY_UNOWNED("plots.admin.destroy.unowned", "static.permissions"),
|
||||
PERMISSION_ADMIN_DESTROY_GROUNDLEVEL("plots.admin.destroy.groundlevel", "static.permissions"),
|
||||
PERMISSION_ADMIN_DESTROY_OTHER("plots.admin.destroy.other", "static.permissions"),
|
||||
@ -749,6 +750,12 @@ public enum Captions implements Caption {
|
||||
EVENT_DENIED("$1%s $2Cancelled by external plugin.", "Events"),
|
||||
//</editor-fold>
|
||||
|
||||
//<editor-fold desc="Caps">
|
||||
PLOT_CAPS_HEADER("$3&m---------&r $1CAPS $3&m---------", false, "Info"),
|
||||
PLOT_CAPS_FORMAT("$2- Cap Type: $1%cap% $2| Status: $1%current%$2/$1%limit% $2($1%percentage%%$2)",
|
||||
false, "Info"),
|
||||
//</editor-fold>
|
||||
|
||||
/**
|
||||
* Legacy Configuration Conversion
|
||||
*/
|
||||
|
@ -54,7 +54,7 @@ public interface Configuration extends ConfigurationSection {
|
||||
* collection, then a new {@link MemoryConfiguration} will be created to
|
||||
* hold the new default values.</p>
|
||||
*
|
||||
* @param defaults A map of Path->Values to add to defaults.
|
||||
* @param defaults A map of Path->Values to add to defaults.
|
||||
* @throws IllegalArgumentException Thrown if defaults is null.
|
||||
*/
|
||||
void addDefaults(Map<String, Object> defaults);
|
||||
|
@ -170,7 +170,7 @@ public abstract class FileConfiguration extends MemoryConfiguration {
|
||||
* Compiles the header for this FileConfiguration and returns the
|
||||
* result.
|
||||
*
|
||||
* <p>This will use the header from {@link #options()} -> {@link
|
||||
* <p>This will use the header from {@link #options()} -> {@link
|
||||
* FileConfigurationOptions#header()}, respecting the rules of {@link
|
||||
* FileConfigurationOptions#copyHeader()} if set.
|
||||
*
|
||||
|
@ -743,7 +743,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
stmt.setInt(i * 5 + 1, plot.getId().x);
|
||||
stmt.setInt(i * 5 + 2, plot.getId().y);
|
||||
try {
|
||||
stmt.setString(i * 5 + 3, plot.owner.toString());
|
||||
stmt.setString(i * 5 + 3, plot.getOwnerAbs().toString());
|
||||
} catch (SQLException ignored) {
|
||||
stmt.setString(i * 5 + 3, everyone.toString());
|
||||
}
|
||||
@ -757,7 +757,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
stmt.setInt(i * 6 + 2, plot.getId().x);
|
||||
stmt.setInt(i * 6 + 3, plot.getId().y);
|
||||
try {
|
||||
stmt.setString(i * 6 + 4, plot.owner.toString());
|
||||
stmt.setString(i * 6 + 4, plot.getOwnerAbs().toString());
|
||||
} catch (SQLException ignored) {
|
||||
stmt.setString(i * 6 + 4, everyone.toString());
|
||||
}
|
||||
@ -768,7 +768,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
@Override public void setSQL(PreparedStatement stmt, Plot plot) throws SQLException {
|
||||
stmt.setInt(1, plot.getId().x);
|
||||
stmt.setInt(2, plot.getId().y);
|
||||
stmt.setString(3, plot.owner.toString());
|
||||
stmt.setString(3, plot.getOwnerAbs().toString());
|
||||
stmt.setString(4, plot.getArea().toString());
|
||||
stmt.setTimestamp(5, new Timestamp(plot.getTimestamp()));
|
||||
|
||||
@ -1007,7 +1007,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
@Override public void set(PreparedStatement statement) throws SQLException {
|
||||
statement.setInt(1, plot.getId().x);
|
||||
statement.setInt(2, plot.getId().y);
|
||||
statement.setString(3, plot.owner.toString());
|
||||
statement.setString(3, plot.getOwnerAbs().toString());
|
||||
statement.setString(4, plot.getArea().toString());
|
||||
statement.setTimestamp(5, new Timestamp(plot.getTimestamp()));
|
||||
statement.setString(6, plot.getArea().toString());
|
||||
@ -1076,7 +1076,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
@Override public void set(PreparedStatement statement) throws SQLException {
|
||||
statement.setInt(1, plot.getId().x);
|
||||
statement.setInt(2, plot.getId().y);
|
||||
statement.setString(3, plot.owner.toString());
|
||||
statement.setString(3, plot.getOwnerAbs().toString());
|
||||
statement.setString(4, plot.getArea().toString());
|
||||
statement.setTimestamp(5, new Timestamp(plot.getTimestamp()));
|
||||
}
|
||||
@ -1381,7 +1381,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
@Override public void delete(final Plot plot) {
|
||||
PlotSquared.debug(
|
||||
"Deleting plot... Id: " + plot.getId() + " World: " + plot.getWorldName() + " Owner: "
|
||||
+ plot.owner + " Index: " + plot.temp);
|
||||
+ plot.getOwnerAbs() + " Index: " + plot.temp);
|
||||
deleteSettings(plot);
|
||||
deleteDenied(plot);
|
||||
deleteHelpers(plot);
|
||||
@ -1409,7 +1409,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
@Override public void createPlotSettings(final int id, Plot plot) {
|
||||
PlotSquared.debug(
|
||||
"Creating plot... Id: " + plot.getId() + " World: " + plot.getWorldName() + " Owner: "
|
||||
+ plot.owner + " Index: " + id);
|
||||
+ plot.getOwnerAbs() + " Index: " + id);
|
||||
addPlotTask(plot, new UniqueStatement("createPlotSettings") {
|
||||
@Override public void set(PreparedStatement statement) throws SQLException {
|
||||
statement.setInt(1, id);
|
||||
@ -1675,13 +1675,26 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
//
|
||||
try (final PreparedStatement preparedStatement =
|
||||
this.connection.prepareStatement("INSERT INTO `" + SQLManager.this.prefix + "plot_flags`(`plot_id`, `flag`, `value`) VALUES(?, ?, ?)")) {
|
||||
|
||||
long timeStarted = System.currentTimeMillis();
|
||||
int flagsProcessed = 0;
|
||||
int plotsProcessed = 0;
|
||||
|
||||
int totalFlags = 0;
|
||||
for (final Map<String, String> flags : flagMap.values()) {
|
||||
totalFlags += flags.size();
|
||||
}
|
||||
|
||||
for (final Map.Entry<Integer, Map<String, String>> plotFlagEntry : flagMap.entrySet()) {
|
||||
for (final Map.Entry<String, String> flagEntry : plotFlagEntry.getValue().entrySet()) {
|
||||
preparedStatement.setInt(1, plotFlagEntry.getKey());
|
||||
preparedStatement.setString(2, flagEntry.getKey());
|
||||
preparedStatement.setString(3, flagEntry.getValue());
|
||||
preparedStatement.addBatch();
|
||||
flagsProcessed += 1;
|
||||
}
|
||||
plotsProcessed += 1;
|
||||
|
||||
try {
|
||||
preparedStatement.executeBatch();
|
||||
} catch (final Exception e) {
|
||||
@ -1689,6 +1702,12 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
e.printStackTrace();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (System.currentTimeMillis() - timeStarted >= 1000L || plotsProcessed >= flagMap.size()) {
|
||||
timeStarted = System.currentTimeMillis();
|
||||
PlotSquared.log(Captions.PREFIX.getTranslated() + "... Flag conversion in progress. " + String.format("%.1f", ((float) flagsProcessed / totalFlags) * 100) + "% Done");
|
||||
}
|
||||
|
||||
PlotSquared.debug(Captions.PREFIX.getTranslated() + "- Finished converting flags for plot with entry ID: " + plotFlagEntry.getKey());
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
@ -3027,10 +3046,10 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
continue;
|
||||
}
|
||||
// owner
|
||||
if (!plot.owner.equals(dataPlot.owner)) {
|
||||
if (!plot.getOwnerAbs().equals(dataPlot.getOwnerAbs())) {
|
||||
PlotSquared
|
||||
.debug("&8 - &7Setting owner: " + plot + " -> " + MainUtil.getName(plot.owner));
|
||||
setOwner(plot, plot.owner);
|
||||
.debug("&8 - &7Setting owner: " + plot + " -> " + MainUtil.getName(plot.getOwnerAbs()));
|
||||
setOwner(plot, plot.getOwnerAbs());
|
||||
}
|
||||
// trusted
|
||||
if (!plot.getTrusted().equals(dataPlot.getTrusted())) {
|
||||
|
@ -31,16 +31,13 @@ import com.plotsquared.core.plot.PlotArea;
|
||||
import com.plotsquared.core.plot.PlotAreaTerrainType;
|
||||
import com.plotsquared.core.plot.PlotAreaType;
|
||||
import com.plotsquared.core.plot.PlotManager;
|
||||
import com.plotsquared.core.queue.DelegateLocalBlockQueue;
|
||||
import com.plotsquared.core.queue.AreaBoundDelegateLocalBlockQueue;
|
||||
import com.plotsquared.core.queue.GlobalBlockQueue;
|
||||
import com.plotsquared.core.queue.LocalBlockQueue;
|
||||
import com.plotsquared.core.queue.LocationOffsetDelegateLocalBlockQueue;
|
||||
import com.plotsquared.core.queue.ScopedLocalBlockQueue;
|
||||
import com.plotsquared.core.util.RegionUtil;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
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 com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@ -63,19 +60,27 @@ public class AugmentedUtils {
|
||||
if (!enabled) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// The coordinates of the block on the
|
||||
// least positive corner of the chunk
|
||||
final int blockX = chunkX << 4;
|
||||
final int blockZ = chunkZ << 4;
|
||||
// Create a region that contains the
|
||||
// entire chunk
|
||||
CuboidRegion region = RegionUtil.createRegion(blockX, blockX + 15, blockZ, blockZ + 15);
|
||||
// Query for plot areas in the chunk
|
||||
Set<PlotArea> areas = PlotSquared.get().getPlotAreas(world, region);
|
||||
if (areas.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
boolean toReturn = false;
|
||||
boolean generationResult = false;
|
||||
for (final PlotArea area : areas) {
|
||||
// A normal plot world may not contain any clusters
|
||||
// and so there's no reason to continue searching
|
||||
if (area.getType() == PlotAreaType.NORMAL) {
|
||||
return false;
|
||||
}
|
||||
// This means that full vanilla generation is used
|
||||
// so we do not interfere
|
||||
if (area.getTerrain() == PlotAreaTerrainType.ALL) {
|
||||
continue;
|
||||
}
|
||||
@ -87,50 +92,38 @@ public class AugmentedUtils {
|
||||
}
|
||||
LocalBlockQueue primaryMask;
|
||||
// coordinates
|
||||
int bxx;
|
||||
int bzz;
|
||||
int txx;
|
||||
int tzz;
|
||||
// gen
|
||||
int relativeBottomX;
|
||||
int relativeBottomZ;
|
||||
int relativeTopX;
|
||||
int relativeTopZ;
|
||||
// Generation
|
||||
if (area.getType() == PlotAreaType.PARTIAL) {
|
||||
bxx = Math.max(0, area.getRegion().getMinimumPoint().getX() - blockX);
|
||||
bzz = Math.max(0, area.getRegion().getMinimumPoint().getZ() - blockZ);
|
||||
txx = Math.min(15, area.getRegion().getMaximumPoint().getX() - blockX);
|
||||
tzz = Math.min(15, area.getRegion().getMaximumPoint().getZ() - blockZ);
|
||||
primaryMask = new DelegateLocalBlockQueue(queue) {
|
||||
@Override public boolean setBlock(int x, int y, int z, BlockState id) {
|
||||
if (area.contains(x, z)) {
|
||||
return super.setBlock(x, y, z, id);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
relativeBottomX = Math.max(0, area.getRegion().getMinimumPoint().getX() - blockX);
|
||||
relativeBottomZ = Math.max(0, area.getRegion().getMinimumPoint().getZ() - blockZ);
|
||||
relativeTopX = Math.min(15, area.getRegion().getMaximumPoint().getX() - blockX);
|
||||
relativeTopZ = Math.min(15, area.getRegion().getMaximumPoint().getZ() - blockZ);
|
||||
|
||||
@Override public boolean setBiome(int x, int z, BiomeType biome) {
|
||||
if (area.contains(x, z)) {
|
||||
return super.setBiome(x, z, biome);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
primaryMask = new AreaBoundDelegateLocalBlockQueue(area, queue);
|
||||
} else {
|
||||
bxx = bzz = 0;
|
||||
txx = tzz = 15;
|
||||
relativeBottomX = relativeBottomZ = 0;
|
||||
relativeTopX = relativeTopZ = 15;
|
||||
primaryMask = queue;
|
||||
}
|
||||
|
||||
LocalBlockQueue secondaryMask;
|
||||
BlockState air = BlockTypes.AIR.getDefaultState();
|
||||
if (area.getTerrain() == PlotAreaTerrainType.ROAD) {
|
||||
PlotManager manager = area.getPlotManager();
|
||||
final boolean[][] canPlace = new boolean[16][16];
|
||||
boolean has = false;
|
||||
for (int x = bxx; x <= txx; x++) {
|
||||
for (int z = bzz; z <= tzz; z++) {
|
||||
int rx = x + blockX;
|
||||
int rz = z + blockZ;
|
||||
boolean can = manager.getPlotId(rx, 0, rz) == null;
|
||||
for (int x = relativeBottomX; x <= relativeTopX; x++) {
|
||||
for (int z = relativeBottomZ; z <= relativeTopZ; z++) {
|
||||
int worldX = x + blockX;
|
||||
int worldZ = z + blockZ;
|
||||
boolean can = manager.getPlotId(worldX, 0, worldZ) == null;
|
||||
if (can) {
|
||||
for (int y = 1; y < 128; y++) {
|
||||
queue.setBlock(rx, y, rz, air);
|
||||
queue.setBlock(worldX, y, worldZ, air);
|
||||
}
|
||||
canPlace[x][z] = true;
|
||||
has = true;
|
||||
@ -140,47 +133,19 @@ public class AugmentedUtils {
|
||||
if (!has) {
|
||||
continue;
|
||||
}
|
||||
toReturn = true;
|
||||
secondaryMask = new DelegateLocalBlockQueue(primaryMask) {
|
||||
@Override public boolean setBlock(int x, int y, int z, 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 {
|
||||
if (canPlace[x - blockX][z - blockZ]) {
|
||||
return super.setBlock(x, y, z, id);
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
PlotSquared.debug(String.format("Failed to set block at: %d;%d;%d (to = %s) with offset %d;%d."
|
||||
+ " Translated to: %d;%d", x, y, z, id, blockX, blockZ, x - blockX, z - blockZ));
|
||||
throw e;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override public boolean setBlock(int x, int y, int z, Pattern pattern) {
|
||||
final BlockVector3 blockVector3 = BlockVector3.at(x + blockX, y, z + blockZ);
|
||||
return this.setBlock(x, y, z, pattern.apply(blockVector3));
|
||||
}
|
||||
|
||||
@Override public boolean setBiome(int x, int y, BiomeType biome) {
|
||||
return super.setBiome(x, y, biome);
|
||||
}
|
||||
};
|
||||
generationResult = true;
|
||||
secondaryMask = new LocationOffsetDelegateLocalBlockQueue(canPlace, blockX,
|
||||
blockZ, primaryMask);
|
||||
} else {
|
||||
secondaryMask = primaryMask;
|
||||
for (int x = bxx; x <= txx; x++) {
|
||||
for (int z = bzz; z <= tzz; z++) {
|
||||
for (int x = relativeBottomX; x <= relativeTopX; x++) {
|
||||
for (int z = relativeBottomZ; z <= relativeTopZ; z++) {
|
||||
for (int y = 1; y < 128; y++) {
|
||||
queue.setBlock(blockX + x, y, blockZ + z, air);
|
||||
}
|
||||
}
|
||||
}
|
||||
toReturn = true;
|
||||
generationResult = true;
|
||||
}
|
||||
primaryMask.setChunkObject(chunkObject);
|
||||
primaryMask.setForceSync(true);
|
||||
@ -196,6 +161,7 @@ public class AugmentedUtils {
|
||||
queue.setForceSync(true);
|
||||
queue.flush();
|
||||
}
|
||||
return toReturn;
|
||||
return generationResult;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -70,11 +70,11 @@ public class HybridGen extends IndependentPlotGenerator {
|
||||
Preconditions.checkNotNull(result, "result cannot be null");
|
||||
Preconditions.checkNotNull(settings, "settings cannot be null");
|
||||
|
||||
HybridPlotWorld hpw = (HybridPlotWorld) settings;
|
||||
HybridPlotWorld hybridPlotWorld = (HybridPlotWorld) settings;
|
||||
// Biome
|
||||
result.fillBiome(hpw.getPlotBiome());
|
||||
result.fillBiome(hybridPlotWorld.getPlotBiome());
|
||||
// Bedrock
|
||||
if (hpw.PLOT_BEDROCK) {
|
||||
if (hybridPlotWorld.PLOT_BEDROCK) {
|
||||
for (short x = 0; x < 16; x++) {
|
||||
for (short z = 0; z < 16; z++) {
|
||||
result.setBlock(x, 0, z, BlockTypes.BEDROCK.getDefaultState());
|
||||
@ -83,110 +83,122 @@ public class HybridGen extends IndependentPlotGenerator {
|
||||
}
|
||||
// Coords
|
||||
Location min = result.getMin();
|
||||
int bx = (min.getX()) - hpw.ROAD_OFFSET_X;
|
||||
int bz = (min.getZ()) - hpw.ROAD_OFFSET_Z;
|
||||
short rbx;
|
||||
int bx = (min.getX()) - hybridPlotWorld.ROAD_OFFSET_X;
|
||||
int bz = (min.getZ()) - hybridPlotWorld.ROAD_OFFSET_Z;
|
||||
// The relative X-coordinate (within the plot) of the minimum X coordinate
|
||||
// contained in the scoped queue
|
||||
short relativeOffsetX;
|
||||
if (bx < 0) {
|
||||
rbx = (short) (hpw.SIZE + (bx % hpw.SIZE));
|
||||
relativeOffsetX = (short) (hybridPlotWorld.SIZE + (bx % hybridPlotWorld.SIZE));
|
||||
} else {
|
||||
rbx = (short) (bx % hpw.SIZE);
|
||||
relativeOffsetX = (short) (bx % hybridPlotWorld.SIZE);
|
||||
}
|
||||
short rbz;
|
||||
// The relative Z-coordinate (within the plot) of the minimum Z coordinate
|
||||
// contained in the scoped queue
|
||||
short relativeOffsetZ;
|
||||
if (bz < 0) {
|
||||
rbz = (short) (hpw.SIZE + (bz % hpw.SIZE));
|
||||
relativeOffsetZ = (short) (hybridPlotWorld.SIZE + (bz % hybridPlotWorld.SIZE));
|
||||
} else {
|
||||
rbz = (short) (bz % hpw.SIZE);
|
||||
relativeOffsetZ = (short) (bz % hybridPlotWorld.SIZE);
|
||||
}
|
||||
short[] rx = new short[16];
|
||||
boolean[] gx = new boolean[16];
|
||||
boolean[] wx = new boolean[16];
|
||||
// The X-coordinate of a given X coordinate, relative to the
|
||||
// plot (Counting from the corner with the least positive
|
||||
// coordinates)
|
||||
short[] relativeX = new short[16];
|
||||
boolean[] insideRoadX = new boolean[16];
|
||||
boolean[] insideWallX = new boolean[16];
|
||||
for (short i = 0; i < 16; i++) {
|
||||
short v = (short) (rbx + i);
|
||||
if (v >= hpw.SIZE) {
|
||||
v -= hpw.SIZE;
|
||||
short v = (short) (relativeOffsetX + i);
|
||||
if (v >= hybridPlotWorld.SIZE) {
|
||||
v -= hybridPlotWorld.SIZE;
|
||||
}
|
||||
rx[i] = v;
|
||||
if (hpw.ROAD_WIDTH != 0) {
|
||||
gx[i] = v < hpw.PATH_WIDTH_LOWER || v > hpw.PATH_WIDTH_UPPER;
|
||||
wx[i] = v == hpw.PATH_WIDTH_LOWER || v == hpw.PATH_WIDTH_UPPER;
|
||||
relativeX[i] = v;
|
||||
if (hybridPlotWorld.ROAD_WIDTH != 0) {
|
||||
insideRoadX[i] = v < hybridPlotWorld.PATH_WIDTH_LOWER || v > hybridPlotWorld.PATH_WIDTH_UPPER;
|
||||
insideWallX[i] = v == hybridPlotWorld.PATH_WIDTH_LOWER || v == hybridPlotWorld.PATH_WIDTH_UPPER;
|
||||
}
|
||||
}
|
||||
short[] rz = new short[16];
|
||||
boolean[] gz = new boolean[16];
|
||||
boolean[] wz = new boolean[16];
|
||||
// The Z-coordinate of a given Z coordinate, relative to the
|
||||
// plot (Counting from the corner with the least positive
|
||||
// coordinates)
|
||||
short[] relativeZ = new short[16];
|
||||
// Whether or not the given Z coordinate belongs to the road
|
||||
boolean[] insideRoadZ = new boolean[16];
|
||||
// Whether or not the given Z coordinate belongs to the wall
|
||||
boolean[] insideWallZ = new boolean[16];
|
||||
for (short i = 0; i < 16; i++) {
|
||||
short v = (short) (rbz + i);
|
||||
if (v >= hpw.SIZE) {
|
||||
v -= hpw.SIZE;
|
||||
short v = (short) (relativeOffsetZ + i);
|
||||
if (v >= hybridPlotWorld.SIZE) {
|
||||
v -= hybridPlotWorld.SIZE;
|
||||
}
|
||||
rz[i] = v;
|
||||
if (hpw.ROAD_WIDTH != 0) {
|
||||
gz[i] = v < hpw.PATH_WIDTH_LOWER || v > hpw.PATH_WIDTH_UPPER;
|
||||
wz[i] = v == hpw.PATH_WIDTH_LOWER || v == hpw.PATH_WIDTH_UPPER;
|
||||
relativeZ[i] = v;
|
||||
if (hybridPlotWorld.ROAD_WIDTH != 0) {
|
||||
insideRoadZ[i] = v < hybridPlotWorld.PATH_WIDTH_LOWER || v > hybridPlotWorld.PATH_WIDTH_UPPER;
|
||||
insideWallZ[i] = v == hybridPlotWorld.PATH_WIDTH_LOWER || v == hybridPlotWorld.PATH_WIDTH_UPPER;
|
||||
}
|
||||
}
|
||||
// generation
|
||||
for (short x = 0; x < 16; x++) {
|
||||
if (gx[x]) {
|
||||
if (insideRoadX[x]) {
|
||||
for (short z = 0; z < 16; z++) {
|
||||
// Road
|
||||
for (int y = 1; y <= hpw.ROAD_HEIGHT; y++) {
|
||||
result.setBlock(x, y, z, hpw.ROAD_BLOCK.toPattern());
|
||||
for (int y = 1; y <= hybridPlotWorld.ROAD_HEIGHT; y++) {
|
||||
result.setBlock(x, y, z, hybridPlotWorld.ROAD_BLOCK.toPattern());
|
||||
}
|
||||
if (hpw.ROAD_SCHEMATIC_ENABLED) {
|
||||
placeSchem(hpw, result, rx[x], rz[z], x, z, true);
|
||||
if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) {
|
||||
placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, true);
|
||||
}
|
||||
}
|
||||
} else if (wx[x]) {
|
||||
} else if (insideWallX[x]) {
|
||||
for (short z = 0; z < 16; z++) {
|
||||
if (gz[z]) {
|
||||
if (insideRoadZ[z]) {
|
||||
// road
|
||||
for (int y = 1; y <= hpw.ROAD_HEIGHT; y++) {
|
||||
result.setBlock(x, y, z, hpw.ROAD_BLOCK.toPattern());
|
||||
for (int y = 1; y <= hybridPlotWorld.ROAD_HEIGHT; y++) {
|
||||
result.setBlock(x, y, z, hybridPlotWorld.ROAD_BLOCK.toPattern());
|
||||
}
|
||||
if (hpw.ROAD_SCHEMATIC_ENABLED) {
|
||||
placeSchem(hpw, result, rx[x], rz[z], x, z, true);
|
||||
if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) {
|
||||
placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, true);
|
||||
}
|
||||
} else {
|
||||
// wall
|
||||
for (int y = 1; y <= hpw.WALL_HEIGHT; y++) {
|
||||
result.setBlock(x, y, z, hpw.WALL_FILLING.toPattern());
|
||||
for (int y = 1; y <= hybridPlotWorld.WALL_HEIGHT; y++) {
|
||||
result.setBlock(x, y, z, hybridPlotWorld.WALL_FILLING.toPattern());
|
||||
}
|
||||
if (!hpw.ROAD_SCHEMATIC_ENABLED) {
|
||||
result.setBlock(x, hpw.WALL_HEIGHT + 1, z, hpw.WALL_BLOCK.toPattern());
|
||||
if (!hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) {
|
||||
result.setBlock(x, hybridPlotWorld.WALL_HEIGHT + 1, z, hybridPlotWorld.WALL_BLOCK.toPattern());
|
||||
} else {
|
||||
placeSchem(hpw, result, rx[x], rz[z], x, z, true);
|
||||
placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (short z = 0; z < 16; z++) {
|
||||
if (gz[z]) {
|
||||
if (insideRoadZ[z]) {
|
||||
// road
|
||||
for (int y = 1; y <= hpw.ROAD_HEIGHT; y++) {
|
||||
result.setBlock(x, y, z, hpw.ROAD_BLOCK.toPattern());
|
||||
for (int y = 1; y <= hybridPlotWorld.ROAD_HEIGHT; y++) {
|
||||
result.setBlock(x, y, z, hybridPlotWorld.ROAD_BLOCK.toPattern());
|
||||
}
|
||||
if (hpw.ROAD_SCHEMATIC_ENABLED) {
|
||||
placeSchem(hpw, result, rx[x], rz[z], x, z, true);
|
||||
if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) {
|
||||
placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, true);
|
||||
}
|
||||
} else if (wz[z]) {
|
||||
} else if (insideWallZ[z]) {
|
||||
// wall
|
||||
for (int y = 1; y <= hpw.WALL_HEIGHT; y++) {
|
||||
result.setBlock(x, y, z, hpw.WALL_FILLING.toPattern());
|
||||
for (int y = 1; y <= hybridPlotWorld.WALL_HEIGHT; y++) {
|
||||
result.setBlock(x, y, z, hybridPlotWorld.WALL_FILLING.toPattern());
|
||||
}
|
||||
if (!hpw.ROAD_SCHEMATIC_ENABLED) {
|
||||
result.setBlock(x, hpw.WALL_HEIGHT + 1, z, hpw.WALL_BLOCK.toPattern());
|
||||
if (!hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) {
|
||||
result.setBlock(x, hybridPlotWorld.WALL_HEIGHT + 1, z, hybridPlotWorld.WALL_BLOCK.toPattern());
|
||||
} else {
|
||||
placeSchem(hpw, result, rx[x], rz[z], x, z, true);
|
||||
placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, true);
|
||||
}
|
||||
} else {
|
||||
// plot
|
||||
for (int y = 1; y < hpw.PLOT_HEIGHT; y++) {
|
||||
result.setBlock(x, y, z, hpw.MAIN_BLOCK.toPattern());
|
||||
for (int y = 1; y < hybridPlotWorld.PLOT_HEIGHT; y++) {
|
||||
result.setBlock(x, y, z, hybridPlotWorld.MAIN_BLOCK.toPattern());
|
||||
}
|
||||
result.setBlock(x, hpw.PLOT_HEIGHT, z, hpw.TOP_BLOCK.toPattern());
|
||||
if (hpw.PLOT_SCHEMATIC) {
|
||||
placeSchem(hpw, result, rx[x], rz[z], x, z, false);
|
||||
result.setBlock(x, hybridPlotWorld.PLOT_HEIGHT, z, hybridPlotWorld.TOP_BLOCK.toPattern());
|
||||
if (hybridPlotWorld.PLOT_SCHEMATIC) {
|
||||
placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -194,68 +206,6 @@ public class HybridGen extends IndependentPlotGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
/* @Override public boolean populateChunk(ScopedLocalBlockQueue result, PlotArea settings) {
|
||||
HybridPlotWorld hpw = (HybridPlotWorld) settings;
|
||||
if (hpw.G_SCH_STATE != null) {
|
||||
Location min = result.getMin();
|
||||
int cx = min.getX() >> 4;
|
||||
int cz = min.getZ() >> 4;
|
||||
int p1x = cx << 4;
|
||||
int p1z = cz << 4;
|
||||
int bx = p1x - hpw.ROAD_OFFSET_X;
|
||||
int bz = p1z - hpw.ROAD_OFFSET_Z;
|
||||
short rbx;
|
||||
if (bx < 0) {
|
||||
rbx = (short) (hpw.SIZE + (bx % hpw.SIZE));
|
||||
} else {
|
||||
rbx = (short) (bx % hpw.SIZE);
|
||||
}
|
||||
short rbz;
|
||||
if (bz < 0) {
|
||||
rbz = (short) (hpw.SIZE + (bz % hpw.SIZE));
|
||||
} else {
|
||||
rbz = (short) (bz % hpw.SIZE);
|
||||
}
|
||||
short[] rx = new short[16];
|
||||
for (short i = 0; i < 16; i++) {
|
||||
short v = (short) (rbx + i);
|
||||
if (v >= hpw.SIZE) {
|
||||
v -= hpw.SIZE;
|
||||
}
|
||||
rx[i] = v;
|
||||
}
|
||||
short[] rz = new short[16];
|
||||
for (short i = 0; i < 16; i++) {
|
||||
short v = (short) (rbz + i);
|
||||
if (v >= hpw.SIZE) {
|
||||
v -= hpw.SIZE;
|
||||
}
|
||||
rz[i] = v;
|
||||
}
|
||||
LocalBlockQueue queue = null;
|
||||
for (short x = 0; x < 16; x++) {
|
||||
for (short z = 0; z < 16; z++) {
|
||||
int pair = MathMan.pair(rx[x], rz[z]);
|
||||
HashMap<Integer, CompoundTag> map = hpw.G_SCH_STATE.get(pair);
|
||||
if (map != null) {
|
||||
for (Entry<Integer, CompoundTag> entry : map.entrySet()) {
|
||||
if (queue == null) {
|
||||
queue = GlobalBlockQueue.IMP.getNewQueue(hpw.worldname, false);
|
||||
}
|
||||
CompoundTag tag = entry.getValue();
|
||||
SchematicHandler.manager
|
||||
.restoreTile(queue, tag, p1x + x, entry.getKey(), p1z + z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (queue != null) {
|
||||
queue.flush();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}*/
|
||||
|
||||
@Override public PlotArea getNewPlotArea(String world, String id, PlotId min, PlotId max) {
|
||||
return new HybridPlotWorld(world, id, this, min, max);
|
||||
}
|
||||
|
@ -25,23 +25,22 @@
|
||||
*/
|
||||
package com.plotsquared.core.generator;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.plotsquared.core.PlotSquared;
|
||||
import com.plotsquared.core.command.Template;
|
||||
import com.plotsquared.core.config.Settings;
|
||||
import com.plotsquared.core.util.FileBytes;
|
||||
import com.plotsquared.core.location.Location;
|
||||
import com.plotsquared.core.plot.Plot;
|
||||
import com.plotsquared.core.plot.PlotAreaTerrainType;
|
||||
import com.plotsquared.core.plot.PlotAreaType;
|
||||
import com.plotsquared.core.plot.PlotId;
|
||||
import com.plotsquared.core.util.task.RunnableVal;
|
||||
import com.plotsquared.core.util.ChunkManager;
|
||||
import com.plotsquared.core.util.MainUtil;
|
||||
import com.plotsquared.core.util.MathMan;
|
||||
import com.plotsquared.core.queue.GlobalBlockQueue;
|
||||
import com.plotsquared.core.queue.LocalBlockQueue;
|
||||
import com.plotsquared.core.util.BlockUtil;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.plotsquared.core.util.ChunkManager;
|
||||
import com.plotsquared.core.util.FileBytes;
|
||||
import com.plotsquared.core.util.MainUtil;
|
||||
import com.plotsquared.core.util.MathMan;
|
||||
import com.plotsquared.core.util.task.RunnableVal;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
@ -209,13 +208,15 @@ public class HybridPlotManager extends ClassicPlotManager {
|
||||
// The component blocks
|
||||
final Pattern plotfloor = hybridPlotWorld.TOP_BLOCK.toPattern();
|
||||
final Pattern filling = hybridPlotWorld.MAIN_BLOCK.toPattern();
|
||||
|
||||
final BlockState bedrock;
|
||||
final BlockState air = BlockTypes.AIR.getDefaultState();
|
||||
if (hybridPlotWorld.PLOT_BEDROCK) {
|
||||
bedrock = BlockUtil.get((short) 7, (byte) 0);
|
||||
bedrock = BlockTypes.BEDROCK.getDefaultState();
|
||||
} else {
|
||||
bedrock = BlockUtil.get((short) 0, (byte) 0);
|
||||
bedrock = air;
|
||||
}
|
||||
final BlockState air = BlockUtil.get((short) 0, (byte) 0);
|
||||
|
||||
final BiomeType biome = hybridPlotWorld.getPlotBiome();
|
||||
final LocalBlockQueue queue = hybridPlotWorld.getQueue(false);
|
||||
ChunkManager.chunkTask(pos1, pos2, new RunnableVal<int[]>() {
|
||||
|
@ -245,7 +245,7 @@ public abstract class PlotPlayer implements CommandCaller, OfflinePlotPlayer {
|
||||
* Get the number of plots this player owns.
|
||||
*
|
||||
* @return number of plots within the scope (globally, or in the player's current world as defined in the settings.yml)
|
||||
* @see #getPlotCount(String);
|
||||
* @see #getPlotCount(String)
|
||||
* @see #getPlots()
|
||||
*/
|
||||
public int getPlotCount() {
|
||||
|
@ -103,6 +103,8 @@ import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.plotsquared.core.command.SubCommand.sendMessage;
|
||||
import static com.plotsquared.core.util.entity.EntityCategories.*;
|
||||
|
||||
|
||||
/**
|
||||
* The plot class<br>
|
||||
@ -120,16 +122,10 @@ public class Plot {
|
||||
private static Set<CuboidRegion> regions_cache;
|
||||
|
||||
@NotNull private final PlotId id;
|
||||
|
||||
/**
|
||||
* plot owner
|
||||
* (Merged plots can have multiple owners)
|
||||
* Direct access is Deprecated: use getOwners()
|
||||
*
|
||||
* @deprecated
|
||||
* Plot flag container
|
||||
*/
|
||||
@Deprecated public UUID owner;
|
||||
|
||||
@Getter private final FlagContainer flagContainer = new FlagContainer(null);
|
||||
/**
|
||||
* Has the plot changed since the last save cycle?
|
||||
*/
|
||||
@ -143,55 +139,50 @@ public class Plot {
|
||||
* @deprecated magical
|
||||
*/
|
||||
@Deprecated public int temp;
|
||||
|
||||
/**
|
||||
* plot owner
|
||||
* (Merged plots can have multiple owners)
|
||||
* Direct access is Deprecated: use getOwners()
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
private UUID owner;
|
||||
/**
|
||||
* Plot creation timestamp (not accurate if the plot was created before this was implemented)<br>
|
||||
* - Milliseconds since the epoch<br>
|
||||
*/
|
||||
private long timestamp;
|
||||
|
||||
/**
|
||||
* List of trusted (with plot permissions).
|
||||
*/
|
||||
private HashSet<UUID> trusted;
|
||||
|
||||
/**
|
||||
* List of members users (with plot permissions).
|
||||
*/
|
||||
private HashSet<UUID> members;
|
||||
|
||||
/**
|
||||
* List of denied players.
|
||||
*/
|
||||
private HashSet<UUID> denied;
|
||||
|
||||
/**
|
||||
* External settings class.
|
||||
* - Please favor the methods over direct access to this class<br>
|
||||
* - The methods are more likely to be left unchanged from version changes<br>
|
||||
*/
|
||||
private PlotSettings settings;
|
||||
|
||||
private PlotArea area;
|
||||
|
||||
/**
|
||||
* Session only plot metadata (session is until the server stops)<br>
|
||||
* <br>
|
||||
* For persistent metadata use the flag system
|
||||
*/
|
||||
private ConcurrentHashMap<String, Object> meta;
|
||||
|
||||
/**
|
||||
* The cached origin plot.
|
||||
* - The origin plot is used for plot grouping and relational data
|
||||
*/
|
||||
private Plot origin;
|
||||
|
||||
/**
|
||||
* Plot flag container
|
||||
*/
|
||||
@Getter private final FlagContainer flagContainer = new FlagContainer(null);
|
||||
|
||||
/**
|
||||
* Constructor for a new plot.
|
||||
* (Only changes after plot.create() will be properly set in the database)
|
||||
@ -316,6 +307,34 @@ public class Plot {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the owner of this exact plot, as it is
|
||||
* stored in the database.
|
||||
* <p>
|
||||
* If the plot is a mega-plot, then the method returns
|
||||
* the owner of this particular subplot.
|
||||
* <p>
|
||||
* Unlike {@link #getOwner()} this method does not
|
||||
* consider factors such as {@link com.github.intellectualsites.plotsquared.plot.flags.implementations.ServerPlotFlag}
|
||||
* that could alter the de facto owner of the plot.
|
||||
*
|
||||
* @return The plot owner of this particular (sub-)plot
|
||||
* as stored in the database, if one exists. Else, null.
|
||||
*/
|
||||
@Nullable public UUID getOwnerAbs() {
|
||||
return this.owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the owner of this exact sub-plot. This does
|
||||
* not update the database.
|
||||
*
|
||||
* @param owner The new owner of this particular sub-plot.
|
||||
*/
|
||||
public void setOwnerAbs(@Nullable final UUID owner) {
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
public String getWorldName() {
|
||||
return area.getWorldName();
|
||||
}
|
||||
@ -396,7 +415,7 @@ public class Plot {
|
||||
* @return false if there is no owner
|
||||
*/
|
||||
public boolean hasOwner() {
|
||||
return this.owner != null;
|
||||
return this.getOwnerAbs() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -416,22 +435,25 @@ public class Plot {
|
||||
return connected.stream().anyMatch(current -> uuid.equals(current.getOwner()));
|
||||
}
|
||||
|
||||
public boolean isOwnerAbs(UUID uuid) {
|
||||
public boolean isOwnerAbs(@Nullable final UUID uuid) {
|
||||
if (uuid == null) {
|
||||
return false;
|
||||
}
|
||||
return uuid.equals(this.getOwner());
|
||||
}
|
||||
|
||||
/**
|
||||
* plot owner
|
||||
* Get the plot owner of this particular sub-plot.
|
||||
* (Merged plots can have multiple owners)
|
||||
* Direct access is Deprecated: use getOwners()
|
||||
* Direct access is discouraged: use getOwners()
|
||||
*
|
||||
* @deprecated
|
||||
* @see #getOwnerAbs() getOwnerAbs() to get the owner as stored in the database
|
||||
*/
|
||||
@Deprecated public UUID getOwner() {
|
||||
public UUID getOwner() {
|
||||
if (MainUtil.isServerOwned(this)) {
|
||||
return DBFunc.SERVER;
|
||||
}
|
||||
return this.owner;
|
||||
return this.getOwnerAbs();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -441,20 +463,20 @@ public class Plot {
|
||||
*/
|
||||
public void setOwner(UUID owner) {
|
||||
if (!hasOwner()) {
|
||||
this.owner = owner;
|
||||
this.setOwnerAbs(owner);
|
||||
create();
|
||||
return;
|
||||
}
|
||||
if (!isMerged()) {
|
||||
if (!this.owner.equals(owner)) {
|
||||
this.owner = owner;
|
||||
if (!owner.equals(this.getOwnerAbs())) {
|
||||
this.setOwnerAbs(owner);
|
||||
DBFunc.setOwner(this, owner);
|
||||
}
|
||||
return;
|
||||
}
|
||||
for (Plot current : getConnectedPlots()) {
|
||||
if (!owner.equals(current.owner)) {
|
||||
current.owner = owner;
|
||||
if (!owner.equals(current.getOwnerAbs())) {
|
||||
current.setOwnerAbs(owner);
|
||||
DBFunc.setOwner(current, owner);
|
||||
}
|
||||
}
|
||||
@ -497,7 +519,7 @@ public class Plot {
|
||||
* @return true if the player is added/trusted or is the owner
|
||||
*/
|
||||
public boolean isAdded(UUID uuid) {
|
||||
if (this.owner == null || getDenied().contains(uuid)) {
|
||||
if (!this.hasOwner() || getDenied().contains(uuid)) {
|
||||
return false;
|
||||
}
|
||||
if (isOwner(uuid)) {
|
||||
@ -862,20 +884,20 @@ public class Plot {
|
||||
*/
|
||||
public boolean setOwner(UUID owner, PlotPlayer initiator) {
|
||||
if (!hasOwner()) {
|
||||
this.owner = owner;
|
||||
this.setOwnerAbs(owner);
|
||||
create();
|
||||
return true;
|
||||
}
|
||||
if (!isMerged()) {
|
||||
if (!this.owner.equals(owner)) {
|
||||
this.owner = owner;
|
||||
if (!owner.equals(this.getOwnerAbs())) {
|
||||
this.setOwnerAbs(owner);
|
||||
DBFunc.setOwner(this, owner);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
for (Plot current : getConnectedPlots()) {
|
||||
if (!owner.equals(current.owner)) {
|
||||
current.owner = owner;
|
||||
for (final Plot current : getConnectedPlots()) {
|
||||
if (!owner.equals(current.getOwnerAbs())) {
|
||||
current.setOwnerAbs(owner);
|
||||
DBFunc.setOwner(current, owner);
|
||||
}
|
||||
}
|
||||
@ -886,7 +908,7 @@ public class Plot {
|
||||
* Clear a plot.
|
||||
*
|
||||
* @param whenDone A runnable to execute when clearing finishes, or null
|
||||
* @see this#clear(boolean, boolean, Runnable)
|
||||
* @see #clear(boolean, boolean, Runnable)
|
||||
* @see #deletePlot(Runnable) to clear and delete a plot
|
||||
*/
|
||||
public void clear(Runnable whenDone) {
|
||||
@ -921,7 +943,7 @@ public class Plot {
|
||||
TaskManager.runTask(whenDone);
|
||||
};
|
||||
for (Plot current : plots) {
|
||||
if (isDelete || current.owner == null) {
|
||||
if (isDelete || !current.hasOwner()) {
|
||||
manager.unClaimPlot(current, null);
|
||||
} else {
|
||||
manager.claimPlot(current);
|
||||
@ -1053,7 +1075,7 @@ public class Plot {
|
||||
if (createSign) {
|
||||
GlobalBlockQueue.IMP.addEmptyTask(() -> {
|
||||
for (Plot current : plots) {
|
||||
current.setSign(MainUtil.getName(current.owner));
|
||||
current.setSign(MainUtil.getName(current.getOwnerAbs()));
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -1084,11 +1106,13 @@ public class Plot {
|
||||
"%plr%", name),
|
||||
Captions.OWNER_SIGN_LINE_4.formatted().replaceAll("%id%", id).replaceAll(
|
||||
"%plr%", name)};
|
||||
WorldUtil.IMP.setSign(this.getWorldName(), location.getX(), location.getY(), location.getZ(), lines);
|
||||
WorldUtil.IMP
|
||||
.setSign(this.getWorldName(), location.getX(), location.getY(), location.getZ(),
|
||||
lines);
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isLoaded() {
|
||||
public boolean isLoaded() {
|
||||
return WorldUtil.IMP.isWorld(getWorldName());
|
||||
}
|
||||
|
||||
@ -1261,12 +1285,12 @@ public class Plot {
|
||||
int[] count = new int[6];
|
||||
for (Plot current : this.getConnectedPlots()) {
|
||||
int[] result = ChunkManager.manager.countEntities(current);
|
||||
count[0] += result[0];
|
||||
count[1] += result[1];
|
||||
count[2] += result[2];
|
||||
count[3] += result[3];
|
||||
count[4] += result[4];
|
||||
count[5] += result[5];
|
||||
count[CAP_ENTITY] += result[CAP_ENTITY];
|
||||
count[CAP_ANIMAL] += result[CAP_ANIMAL];
|
||||
count[CAP_MONSTER] += result[CAP_MONSTER];
|
||||
count[CAP_MOB] += result[CAP_MOB];
|
||||
count[CAP_VEHICLE] += result[CAP_VEHICLE];
|
||||
count[CAP_MISC] += result[CAP_MISC];
|
||||
}
|
||||
return count;
|
||||
}
|
||||
@ -1321,7 +1345,7 @@ public class Plot {
|
||||
* @return false if the Plot has no owner, otherwise true.
|
||||
*/
|
||||
public boolean unclaim() {
|
||||
if (this.owner == null) {
|
||||
if (!this.hasOwner()) {
|
||||
return false;
|
||||
}
|
||||
for (Plot current : getConnectedPlots()) {
|
||||
@ -1331,7 +1355,7 @@ public class Plot {
|
||||
}
|
||||
getArea().removePlot(getId());
|
||||
DBFunc.delete(current);
|
||||
current.owner = null;
|
||||
current.setOwnerAbs(null);
|
||||
current.settings = null;
|
||||
for (PlotPlayer pp : players) {
|
||||
PlotListener.plotEntry(pp, current);
|
||||
@ -1344,7 +1368,7 @@ public class Plot {
|
||||
* Unlink a plot and remove the roads
|
||||
*
|
||||
* @return true if plot was linked
|
||||
* @see this#unlinkPlot(boolean, boolean)
|
||||
* @see #unlinkPlot(boolean, boolean)
|
||||
*/
|
||||
public boolean unlink() {
|
||||
return this.unlinkPlot(true, true);
|
||||
@ -1374,8 +1398,7 @@ public class Plot {
|
||||
/**
|
||||
* @deprecated May cause synchronous chunk loads
|
||||
*/
|
||||
@Deprecated
|
||||
public Location getCenterSynchronous() {
|
||||
@Deprecated public Location getCenterSynchronous() {
|
||||
Location[] corners = getCorners();
|
||||
Location top = corners[0];
|
||||
Location bot = corners[1];
|
||||
@ -1385,7 +1408,8 @@ public class Plot {
|
||||
if (!isLoaded()) {
|
||||
return location;
|
||||
}
|
||||
int y = WorldUtil.IMP.getHighestBlockSynchronous(getWorldName(), location.getX(), location.getZ());
|
||||
int y = WorldUtil.IMP
|
||||
.getHighestBlockSynchronous(getWorldName(), location.getX(), location.getZ());
|
||||
if (area.allowSigns()) {
|
||||
y = Math.max(y, getManager().getSignLoc(this).getY());
|
||||
}
|
||||
@ -1396,8 +1420,7 @@ public class Plot {
|
||||
/**
|
||||
* @deprecated May cause synchronous chunk loads
|
||||
*/
|
||||
@Deprecated
|
||||
public Location getSideSynchronous() {
|
||||
@Deprecated public Location getSideSynchronous() {
|
||||
CuboidRegion largest = getLargestRegion();
|
||||
int x = (largest.getMaximumPoint().getX() >> 1) - (largest.getMinimumPoint().getX() >> 1)
|
||||
+ largest.getMinimumPoint().getX();
|
||||
@ -1436,8 +1459,7 @@ public class Plot {
|
||||
/**
|
||||
* @deprecated May cause synchronous chunk loading
|
||||
*/
|
||||
@Deprecated
|
||||
public Location getHomeSynchronous() {
|
||||
@Deprecated public Location getHomeSynchronous() {
|
||||
BlockLoc home = this.getPosition();
|
||||
if (home == null || home.getX() == 0 && home.getZ() == 0) {
|
||||
return this.getDefaultHomeSynchronous(true);
|
||||
@ -1451,8 +1473,8 @@ public class Plot {
|
||||
}
|
||||
if (!WorldUtil.IMP.getBlockSynchronous(location).getBlockType().getMaterial().isAir()) {
|
||||
location.setY(Math.max(1 + WorldUtil.IMP
|
||||
.getHighestBlockSynchronous(this.getWorldName(), location.getX(), location.getZ()),
|
||||
bottom.getY()));
|
||||
.getHighestBlockSynchronous(this.getWorldName(), location.getX(),
|
||||
location.getZ()), bottom.getY()));
|
||||
}
|
||||
return location;
|
||||
}
|
||||
@ -1477,9 +1499,9 @@ public class Plot {
|
||||
WorldUtil.IMP.getBlock(location, block -> {
|
||||
if (!block.getBlockType().getMaterial().isAir()) {
|
||||
WorldUtil.IMP
|
||||
.getHighestBlock(this.getWorldName(), location.getX(), location.getZ(), y -> {
|
||||
location.setY(Math.max(1 + y,
|
||||
bottom.getY()));
|
||||
.getHighestBlock(this.getWorldName(), location.getX(), location.getZ(),
|
||||
y -> {
|
||||
location.setY(Math.max(1 + y, bottom.getY()));
|
||||
result.accept(location);
|
||||
});
|
||||
} else {
|
||||
@ -1510,8 +1532,6 @@ public class Plot {
|
||||
/**
|
||||
* Gets the default home location for a plot<br>
|
||||
* - Ignores any home location set for that specific plot
|
||||
*
|
||||
* @return Location
|
||||
*/
|
||||
public void getDefaultHome(Consumer<Location> result) {
|
||||
getDefaultHome(false, result);
|
||||
@ -1520,8 +1540,7 @@ public class Plot {
|
||||
/**
|
||||
* @deprecated May cause synchronous chunk loads
|
||||
*/
|
||||
@Deprecated
|
||||
public Location getDefaultHomeSynchronous(final boolean member) {
|
||||
@Deprecated public Location getDefaultHomeSynchronous(final boolean member) {
|
||||
Plot plot = this.getBasePlot(false);
|
||||
PlotLoc loc = member ? area.getDefaultHome() : area.getNonmemberHome();
|
||||
if (loc != null) {
|
||||
@ -1541,7 +1560,9 @@ public class Plot {
|
||||
z = bot.getZ() + loc.getZ();
|
||||
}
|
||||
int y = loc.getY() < 1 ?
|
||||
(isLoaded() ? WorldUtil.IMP.getHighestBlockSynchronous(plot.getWorldName(), x, z) + 1 : 63) :
|
||||
(isLoaded() ?
|
||||
WorldUtil.IMP.getHighestBlockSynchronous(plot.getWorldName(), x, z) + 1 :
|
||||
63) :
|
||||
loc.getY();
|
||||
return new Location(plot.getWorldName(), x, y, z);
|
||||
}
|
||||
@ -1570,8 +1591,8 @@ public class Plot {
|
||||
}
|
||||
if (loc.getY() < 1) {
|
||||
if (isLoaded()) {
|
||||
WorldUtil.IMP.getHighestBlock(plot.getWorldName(), x, z, y ->
|
||||
result.accept(new Location(plot.getWorldName(), x, y + 1, z)));
|
||||
WorldUtil.IMP.getHighestBlock(plot.getWorldName(), x, z,
|
||||
y -> result.accept(new Location(plot.getWorldName(), x, y + 1, z)));
|
||||
} else {
|
||||
result.accept(new Location(plot.getWorldName(), x, 63, z));
|
||||
}
|
||||
@ -1707,11 +1728,11 @@ public class Plot {
|
||||
* Sets the plot sign if plot signs are enabled.
|
||||
*/
|
||||
public void setSign() {
|
||||
if (this.owner == null) {
|
||||
if (!this.hasOwner()) {
|
||||
this.setSign("unknown");
|
||||
return;
|
||||
}
|
||||
String name = UUIDHandler.getName(this.owner);
|
||||
String name = UUIDHandler.getName(this.getOwnerAbs());
|
||||
if (name == null) {
|
||||
this.setSign("unknown");
|
||||
} else {
|
||||
@ -1733,8 +1754,8 @@ public class Plot {
|
||||
|
||||
public boolean claim(final PlotPlayer player, boolean teleport, String schematic) {
|
||||
if (!canClaim(player)) {
|
||||
PlotSquared.debug(Captions.PREFIX.getTranslated() +
|
||||
String.format("Player %s attempted to claim plot %s, but was not allowed",
|
||||
PlotSquared.debug(Captions.PREFIX.getTranslated() + String
|
||||
.format("Player %s attempted to claim plot %s, but was not allowed",
|
||||
player.getName(), this.getId().toCommaSeparatedString()));
|
||||
return false;
|
||||
}
|
||||
@ -1746,8 +1767,8 @@ public class Plot {
|
||||
|
||||
if (updateDB) {
|
||||
if (!create(player.getUUID(), true)) {
|
||||
PlotSquared.debug(Captions.PREFIX.getTranslated() +
|
||||
String.format("Player %s attempted to claim plot %s, but the database failed to update",
|
||||
PlotSquared.debug(Captions.PREFIX.getTranslated() + String.format(
|
||||
"Player %s attempted to claim plot %s, but the database failed to update",
|
||||
player.getName(), this.getId().toCommaSeparatedString()));
|
||||
return false;
|
||||
}
|
||||
@ -1757,7 +1778,8 @@ public class Plot {
|
||||
setSign(player.getName());
|
||||
MainUtil.sendMessage(player, Captions.CLAIMED);
|
||||
if (teleport && Settings.Teleport.ON_CLAIM) {
|
||||
teleportPlayer(player, TeleportCause.COMMAND, result -> {});
|
||||
teleportPlayer(player, TeleportCause.COMMAND, result -> {
|
||||
});
|
||||
}
|
||||
PlotArea plotworld = getArea();
|
||||
if (plotworld.isSchematicOnClaim()) {
|
||||
@ -1801,7 +1823,7 @@ public class Plot {
|
||||
* @return true if plot was created successfully
|
||||
*/
|
||||
public boolean create(@NotNull UUID uuid, final boolean notify) {
|
||||
this.owner = uuid;
|
||||
this.setOwnerAbs(uuid);
|
||||
Plot existing = this.area.getOwnedPlotAbs(this.id);
|
||||
if (existing != null) {
|
||||
throw new IllegalStateException("Plot already exists!");
|
||||
@ -1834,8 +1856,8 @@ public class Plot {
|
||||
});
|
||||
return true;
|
||||
}
|
||||
PlotSquared.get().getLogger().log(Captions.PREFIX.getTranslated() +
|
||||
String.format("Failed to add plot %s to plot area %s", this.getId().toCommaSeparatedString(),
|
||||
PlotSquared.get().getLogger().log(Captions.PREFIX.getTranslated() + String
|
||||
.format("Failed to add plot %s to plot area %s", this.getId().toCommaSeparatedString(),
|
||||
this.area.toString()));
|
||||
return false;
|
||||
}
|
||||
@ -1854,21 +1876,19 @@ public class Plot {
|
||||
|
||||
/**
|
||||
* Retrieve the biome of the plot.
|
||||
*
|
||||
* @return the name of the biome
|
||||
*/
|
||||
public void getBiome(Consumer<BiomeType> result) {
|
||||
this.getCenter(location ->
|
||||
WorldUtil.IMP.getBiome(location.getWorld(), location.getX(), location.getZ(), result));
|
||||
this.getCenter(location -> WorldUtil.IMP
|
||||
.getBiome(location.getWorld(), location.getX(), location.getZ(), result));
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated May cause synchronous chunk loads
|
||||
*/
|
||||
@Deprecated
|
||||
public BiomeType getBiomeSynchronous() {
|
||||
@Deprecated public BiomeType getBiomeSynchronous() {
|
||||
final Location location = this.getCenterSynchronous();
|
||||
return WorldUtil.IMP.getBiomeSynchronous(location.getWorld(), location.getX(), location.getZ());
|
||||
return WorldUtil.IMP
|
||||
.getBiomeSynchronous(location.getWorld(), location.getX(), location.getZ());
|
||||
}
|
||||
|
||||
//TODO Better documentation needed.
|
||||
@ -1900,7 +1920,7 @@ public class Plot {
|
||||
* @return Future containing the result
|
||||
*/
|
||||
public CompletableFuture<Boolean> swapData(Plot plot) {
|
||||
if (this.owner == null) {
|
||||
if (!this.hasOwner()) {
|
||||
if (plot != null && plot.hasOwner()) {
|
||||
plot.moveData(this, null);
|
||||
return CompletableFuture.completedFuture(true);
|
||||
@ -1935,7 +1955,7 @@ public class Plot {
|
||||
* @return
|
||||
*/
|
||||
public boolean moveData(Plot plot, Runnable whenDone) {
|
||||
if (this.owner == null) {
|
||||
if (!this.hasOwner()) {
|
||||
PlotSquared.debug(plot + " is unowned (single)");
|
||||
TaskManager.runTask(whenDone);
|
||||
return false;
|
||||
@ -2016,14 +2036,16 @@ public class Plot {
|
||||
* - Used when a plot is merged<br>
|
||||
*/
|
||||
public void removeRoadEast() {
|
||||
if (this.area.getType() != PlotAreaType.NORMAL && this.area.getTerrain() == PlotAreaTerrainType.ROAD) {
|
||||
if (this.area.getType() != PlotAreaType.NORMAL
|
||||
&& this.area.getTerrain() == PlotAreaTerrainType.ROAD) {
|
||||
Plot other = this.getRelative(Direction.EAST);
|
||||
Location bot = other.getBottomAbs();
|
||||
Location top = this.getTopAbs();
|
||||
Location pos1 = new Location(this.getWorldName(), top.getX(), 0, bot.getZ());
|
||||
Location pos2 = new Location(this.getWorldName(), bot.getX(), MAX_HEIGHT, top.getZ());
|
||||
ChunkManager.manager.regenerateRegion(pos1, pos2, true, null);
|
||||
} else if (this.area.getTerrain() != PlotAreaTerrainType.ALL) { // no road generated => no road to remove
|
||||
} else if (this.area.getTerrain()
|
||||
!= PlotAreaTerrainType.ALL) { // no road generated => no road to remove
|
||||
this.area.getPlotManager().removeRoadEast(this);
|
||||
}
|
||||
}
|
||||
@ -2054,8 +2076,7 @@ public class Plot {
|
||||
* @param whenDone A task to run when finished, or null
|
||||
* @return boolean if swap was successful
|
||||
* @see ChunkManager#swap(Location, Location, Location, Location, Runnable) to swap terrain
|
||||
* @see this#swapData(Plot) to swap plot settings
|
||||
* @see this#swapData(Plot)
|
||||
* @see #swapData(Plot) to swap plot settings
|
||||
*/
|
||||
public CompletableFuture<Boolean> swap(Plot destination, Runnable whenDone) {
|
||||
return this.move(destination, whenDone, true);
|
||||
@ -2175,8 +2196,6 @@ public class Plot {
|
||||
|
||||
/**
|
||||
* Export the plot as a schematic to the configured output directory.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public void export(final RunnableVal<Boolean> whenDone) {
|
||||
SchematicHandler.manager.getCompoundTag(this, new RunnableVal<CompoundTag>() {
|
||||
@ -2189,7 +2208,7 @@ public class Plot {
|
||||
} else {
|
||||
TaskManager.runTaskAsync(() -> {
|
||||
String name = Plot.this.id + "," + Plot.this.area + ',' + MainUtil
|
||||
.getName(Plot.this.owner);
|
||||
.getName(Plot.this.getOwnerAbs());
|
||||
boolean result = SchematicHandler.manager.save(value,
|
||||
Settings.Paths.SCHEMATICS + File.separator + name + ".schem");
|
||||
if (whenDone != null) {
|
||||
@ -2396,7 +2415,7 @@ public class Plot {
|
||||
*/
|
||||
public UUID guessOwner() {
|
||||
if (this.hasOwner()) {
|
||||
return this.owner;
|
||||
return this.getOwnerAbs();
|
||||
}
|
||||
if (!this.area.allowSigns() || !Settings.Enabled_Components.GUESS_PLOT_OWNER) {
|
||||
return null;
|
||||
@ -2430,7 +2449,7 @@ public class Plot {
|
||||
}
|
||||
UUID owner = UUIDHandler.getUUID(name, null);
|
||||
if (owner != null) {
|
||||
this.owner = owner;
|
||||
this.setOwnerAbs(owner);
|
||||
break;
|
||||
}
|
||||
if (lines[i - 1].length() == 15) {
|
||||
@ -2438,19 +2457,19 @@ public class Plot {
|
||||
for (Entry<StringWrapper, UUID> entry : map.entrySet()) {
|
||||
String key = entry.getKey().value;
|
||||
if (key.length() > name.length() && key.startsWith(name)) {
|
||||
this.owner = entry.getValue();
|
||||
this.setOwnerAbs(entry.getValue());
|
||||
break loop;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.owner = UUID.nameUUIDFromBytes(
|
||||
("OfflinePlayer:" + name).getBytes(StandardCharsets.UTF_8));
|
||||
this.setOwnerAbs(UUID.nameUUIDFromBytes(
|
||||
("OfflinePlayer:" + name).getBytes(StandardCharsets.UTF_8)));
|
||||
break;
|
||||
}
|
||||
if (this.hasOwner()) {
|
||||
this.create();
|
||||
}
|
||||
return this.owner;
|
||||
return this.getOwnerAbs();
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
return null;
|
||||
}
|
||||
@ -2461,14 +2480,16 @@ public class Plot {
|
||||
* - Used when a plot is merged<br>
|
||||
*/
|
||||
public void removeRoadSouth() {
|
||||
if (this.area.getType() != PlotAreaType.NORMAL && this.area.getTerrain() == PlotAreaTerrainType.ROAD) {
|
||||
if (this.area.getType() != PlotAreaType.NORMAL
|
||||
&& this.area.getTerrain() == PlotAreaTerrainType.ROAD) {
|
||||
Plot other = this.getRelative(Direction.SOUTH);
|
||||
Location bot = other.getBottomAbs();
|
||||
Location top = this.getTopAbs();
|
||||
Location pos1 = new Location(this.getWorldName(), bot.getX(), 0, top.getZ());
|
||||
Location pos2 = new Location(this.getWorldName(), top.getX(), MAX_HEIGHT, bot.getZ());
|
||||
ChunkManager.manager.regenerateRegion(pos1, pos2, true, null);
|
||||
} else if (this.area.getTerrain() != PlotAreaTerrainType.ALL) { // no road generated => no road to remove
|
||||
} else if (this.area.getTerrain()
|
||||
!= PlotAreaTerrainType.ALL) { // no road generated => no road to remove
|
||||
this.getManager().removeRoadSouth(this);
|
||||
}
|
||||
}
|
||||
@ -2484,7 +2505,7 @@ public class Plot {
|
||||
*/
|
||||
public boolean autoMerge(Direction dir, int max, UUID uuid, boolean removeRoads) {
|
||||
//Ignore merging if there is no owner for the plot
|
||||
if (this.owner == null) {
|
||||
if (!this.hasOwner()) {
|
||||
return false;
|
||||
}
|
||||
Set<Plot> connected = this.getConnectedPlots();
|
||||
@ -2637,14 +2658,16 @@ public class Plot {
|
||||
* Remove the SE road (only effects terrain)
|
||||
*/
|
||||
public void removeRoadSouthEast() {
|
||||
if (this.area.getType() != PlotAreaType.NORMAL && this.area.getTerrain() == PlotAreaTerrainType.ROAD) {
|
||||
if (this.area.getType() != PlotAreaType.NORMAL
|
||||
&& this.area.getTerrain() == PlotAreaTerrainType.ROAD) {
|
||||
Plot other = this.getRelative(1, 1);
|
||||
Location pos1 = this.getTopAbs().add(1, 0, 1);
|
||||
Location pos2 = other.getBottomAbs().subtract(1, 0, 1);
|
||||
pos1.setY(0);
|
||||
pos2.setY(MAX_HEIGHT);
|
||||
ChunkManager.manager.regenerateRegion(pos1, pos2, true, null);
|
||||
} else if (this.area.getTerrain() != PlotAreaTerrainType.ALL) { // no road generated => no road to remove
|
||||
} else if (this.area.getTerrain()
|
||||
!= PlotAreaTerrainType.ALL) { // no road generated => no road to remove
|
||||
this.area.getPlotManager().removeRoadSouthEast(this);
|
||||
}
|
||||
}
|
||||
@ -2719,7 +2742,7 @@ public class Plot {
|
||||
if (!tmp.getMerged(Direction.SOUTH)) {
|
||||
// invalid merge
|
||||
PlotSquared.debug("Fixing invalid merge: " + this);
|
||||
if (tmp.isOwnerAbs(this.owner)) {
|
||||
if (tmp.isOwnerAbs(this.getOwnerAbs())) {
|
||||
tmp.getSettings().setMerged(Direction.SOUTH, true);
|
||||
DBFunc.setMerged(tmp, tmp.getSettings().getMerged());
|
||||
} else {
|
||||
@ -2732,10 +2755,11 @@ public class Plot {
|
||||
}
|
||||
if (this.getMerged(Direction.EAST)) {
|
||||
tmp = this.area.getPlotAbs(this.id.getRelative(Direction.EAST));
|
||||
assert tmp != null;
|
||||
if (!tmp.getMerged(Direction.WEST)) {
|
||||
// invalid merge
|
||||
PlotSquared.debug("Fixing invalid merge: " + this);
|
||||
if (tmp.isOwnerAbs(this.owner)) {
|
||||
if (tmp.isOwnerAbs(this.getOwnerAbs())) {
|
||||
tmp.getSettings().setMerged(Direction.WEST, true);
|
||||
DBFunc.setMerged(tmp, tmp.getSettings().getMerged());
|
||||
} else {
|
||||
@ -2748,10 +2772,11 @@ public class Plot {
|
||||
}
|
||||
if (this.getMerged(Direction.SOUTH)) {
|
||||
tmp = this.area.getPlotAbs(this.id.getRelative(Direction.SOUTH));
|
||||
assert tmp != null;
|
||||
if (!tmp.getMerged(Direction.NORTH)) {
|
||||
// invalid merge
|
||||
PlotSquared.debug("Fixing invalid merge: " + this);
|
||||
if (tmp.isOwnerAbs(this.owner)) {
|
||||
if (tmp.isOwnerAbs(this.getOwnerAbs())) {
|
||||
tmp.getSettings().setMerged(Direction.NORTH, true);
|
||||
DBFunc.setMerged(tmp, tmp.getSettings().getMerged());
|
||||
} else {
|
||||
@ -2767,7 +2792,7 @@ public class Plot {
|
||||
if (!tmp.getMerged(Direction.EAST)) {
|
||||
// invalid merge
|
||||
PlotSquared.debug("Fixing invalid merge: " + this);
|
||||
if (tmp.isOwnerAbs(this.owner)) {
|
||||
if (tmp.isOwnerAbs(this.getOwnerAbs())) {
|
||||
tmp.getSettings().setMerged(Direction.EAST, true);
|
||||
DBFunc.setMerged(tmp, tmp.getSettings().getMerged());
|
||||
} else {
|
||||
@ -2780,11 +2805,11 @@ public class Plot {
|
||||
}
|
||||
Plot current;
|
||||
while ((current = frontier.poll()) != null) {
|
||||
if (current.owner == null || current.settings == null) {
|
||||
if (!current.hasOwner() || current.settings == null) {
|
||||
// Invalid plot
|
||||
// merged onto unclaimed plot
|
||||
PlotSquared
|
||||
.debug("Ignoring invalid merged plot: " + current + " | " + current.owner);
|
||||
PlotSquared.debug(
|
||||
"Ignoring invalid merged plot: " + current + " | " + current.getOwnerAbs());
|
||||
continue;
|
||||
}
|
||||
tmpSet.add(current);
|
||||
@ -3026,7 +3051,7 @@ public class Plot {
|
||||
* Teleport a player to a plot and send them the teleport message.
|
||||
*
|
||||
* @param player the player
|
||||
* @return if the teleport succeeded
|
||||
* @param result Called with the result of the teleportation
|
||||
*/
|
||||
public void teleportPlayer(final PlotPlayer player, Consumer<Boolean> result) {
|
||||
teleportPlayer(player, TeleportCause.PLUGIN, result);
|
||||
@ -3037,25 +3062,29 @@ public class Plot {
|
||||
*
|
||||
* @param player the player
|
||||
* @param cause the cause of the teleport
|
||||
* @return if the teleport succeeded
|
||||
* @param resultConsumer Called with the result of the teleportation
|
||||
*/
|
||||
public void teleportPlayer(final PlotPlayer player, TeleportCause cause, Consumer<Boolean> resultConsumer) {
|
||||
public void teleportPlayer(final PlotPlayer player, TeleportCause cause,
|
||||
Consumer<Boolean> resultConsumer) {
|
||||
Plot plot = this.getBasePlot(false);
|
||||
Result result =
|
||||
PlotSquared.get().getEventDispatcher().callTeleport(player, player.getLocation(), plot).getEventResult();
|
||||
PlotSquared.get().getEventDispatcher().callTeleport(player, player.getLocation(), plot)
|
||||
.getEventResult();
|
||||
if (result == Result.DENY) {
|
||||
sendMessage(player, Captions.EVENT_DENIED, "Teleport");
|
||||
resultConsumer.accept(false);
|
||||
return;
|
||||
}
|
||||
final Consumer<Location> locationConsumer = location -> {
|
||||
if (Settings.Teleport.DELAY == 0 || Permissions.hasPermission(player, "plots.teleport.delay.bypass")) {
|
||||
if (Settings.Teleport.DELAY == 0 || Permissions
|
||||
.hasPermission(player, "plots.teleport.delay.bypass")) {
|
||||
MainUtil.sendMessage(player, Captions.TELEPORTED_TO_PLOT);
|
||||
player.teleport(location, cause);
|
||||
resultConsumer.accept(true);
|
||||
return;
|
||||
}
|
||||
MainUtil.sendMessage(player, Captions.TELEPORT_IN_SECONDS, Settings.Teleport.DELAY + "");
|
||||
MainUtil
|
||||
.sendMessage(player, Captions.TELEPORT_IN_SECONDS, Settings.Teleport.DELAY + "");
|
||||
final String name = player.getName();
|
||||
TaskManager.TELEPORT_QUEUE.add(name);
|
||||
TaskManager.runTaskLater(() -> {
|
||||
@ -3084,14 +3113,14 @@ public class Plot {
|
||||
* @return true if the owner of the Plot is online
|
||||
*/
|
||||
public boolean isOnline() {
|
||||
if (this.owner == null) {
|
||||
if (!this.hasOwner()) {
|
||||
return false;
|
||||
}
|
||||
if (!isMerged()) {
|
||||
return UUIDHandler.getPlayer(this.owner) != null;
|
||||
return UUIDHandler.getPlayer(this.getOwnerAbs()) != null;
|
||||
}
|
||||
for (Plot current : getConnectedPlots()) {
|
||||
if (current.hasOwner() && UUIDHandler.getPlayer(current.owner) != null) {
|
||||
for (final Plot current : getConnectedPlots()) {
|
||||
if (current.hasOwner() && UUIDHandler.getPlayer(current.getOwnerAbs()) != null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -3108,7 +3137,8 @@ public class Plot {
|
||||
* @return
|
||||
*/
|
||||
public boolean setComponent(String component, Pattern blocks) {
|
||||
PlotComponentSetEvent event = PlotSquared.get().getEventDispatcher().callComponentSet(this, component, blocks);
|
||||
PlotComponentSetEvent event =
|
||||
PlotSquared.get().getEventDispatcher().callComponentSet(this, component, blocks);
|
||||
component = event.getComponent();
|
||||
blocks = event.getPattern();
|
||||
return this.getManager().setComponent(this.getId(), component, blocks);
|
||||
@ -3206,14 +3236,15 @@ public class Plot {
|
||||
* @param allowSwap whether to swap plots
|
||||
* @return success
|
||||
*/
|
||||
public CompletableFuture<Boolean> move(final Plot destination, final Runnable whenDone, boolean allowSwap) {
|
||||
public CompletableFuture<Boolean> move(final Plot destination, final Runnable whenDone,
|
||||
boolean allowSwap) {
|
||||
final PlotId offset = new PlotId(destination.getId().x - this.getId().x,
|
||||
destination.getId().y - this.getId().y);
|
||||
Location db = destination.getBottomAbs();
|
||||
Location ob = this.getBottomAbs();
|
||||
final int offsetX = db.getX() - ob.getX();
|
||||
final int offsetZ = db.getZ() - ob.getZ();
|
||||
if (this.owner == null) {
|
||||
if (!this.hasOwner()) {
|
||||
TaskManager.runTaskLater(whenDone, 1);
|
||||
return CompletableFuture.completedFuture(false);
|
||||
}
|
||||
@ -3287,7 +3318,8 @@ public class Plot {
|
||||
@Override public void run() {
|
||||
if (regions.isEmpty()) {
|
||||
Plot plot = destination.getRelative(0, 0);
|
||||
Plot originPlot = originArea.getPlotAbs(new PlotId(plot.id.x - offset.x, plot.id.y - offset.y));
|
||||
Plot originPlot = originArea
|
||||
.getPlotAbs(new PlotId(plot.id.x - offset.x, plot.id.y - offset.y));
|
||||
final Runnable clearDone = () -> {
|
||||
for (final Plot current : plot.getConnectedPlots()) {
|
||||
getManager().claimPlot(current);
|
||||
@ -3331,7 +3363,7 @@ public class Plot {
|
||||
Location ob = this.getBottomAbs();
|
||||
final int offsetX = db.getX() - ob.getX();
|
||||
final int offsetZ = db.getZ() - ob.getZ();
|
||||
if (this.owner == null) {
|
||||
if (!this.hasOwner()) {
|
||||
TaskManager.runTaskLater(whenDone, 1);
|
||||
return false;
|
||||
}
|
||||
|
@ -25,33 +25,35 @@
|
||||
*/
|
||||
package com.plotsquared.core.plot;
|
||||
|
||||
import com.plotsquared.core.location.Direction;
|
||||
import com.plotsquared.core.location.Location;
|
||||
import com.plotsquared.core.configuration.ConfigurationSection;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.plotsquared.core.PlotSquared;
|
||||
import com.plotsquared.core.location.PlotLoc;
|
||||
import com.plotsquared.core.player.PlotPlayer;
|
||||
import com.plotsquared.core.collection.QuadMap;
|
||||
import com.plotsquared.core.config.CaptionUtility;
|
||||
import com.plotsquared.core.config.Captions;
|
||||
import com.plotsquared.core.config.Configuration;
|
||||
import com.plotsquared.core.config.ConfigurationNode;
|
||||
import com.plotsquared.core.config.Settings;
|
||||
import com.plotsquared.core.configuration.ConfigurationSection;
|
||||
import com.plotsquared.core.generator.GridPlotWorld;
|
||||
import com.plotsquared.core.generator.IndependentPlotGenerator;
|
||||
import com.plotsquared.core.location.Direction;
|
||||
import com.plotsquared.core.location.Location;
|
||||
import com.plotsquared.core.location.PlotLoc;
|
||||
import com.plotsquared.core.player.PlotPlayer;
|
||||
import com.plotsquared.core.plot.flag.FlagContainer;
|
||||
import com.plotsquared.core.plot.flag.FlagParseException;
|
||||
import com.plotsquared.core.plot.flag.GlobalFlagContainer;
|
||||
import com.plotsquared.core.plot.flag.PlotFlag;
|
||||
import com.plotsquared.core.plot.flag.implementations.DoneFlag;
|
||||
import com.plotsquared.core.generator.GridPlotWorld;
|
||||
import com.plotsquared.core.generator.IndependentPlotGenerator;
|
||||
import com.plotsquared.core.queue.GlobalBlockQueue;
|
||||
import com.plotsquared.core.queue.LocalBlockQueue;
|
||||
import com.plotsquared.core.util.EconHandler;
|
||||
import com.plotsquared.core.util.Expression;
|
||||
import com.plotsquared.core.util.MainUtil;
|
||||
import com.plotsquared.core.util.MathMan;
|
||||
import com.plotsquared.core.util.StringMan;
|
||||
import com.plotsquared.core.collection.QuadMap;
|
||||
import com.plotsquared.core.queue.GlobalBlockQueue;
|
||||
import com.plotsquared.core.queue.LocalBlockQueue;
|
||||
import com.plotsquared.core.util.RegionUtil;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.plotsquared.core.util.StringMan;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
@ -340,13 +342,23 @@ public abstract class PlotArea {
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
this.getFlagContainer().addAll(parseFlags(flags));
|
||||
} catch (FlagParseException e) {
|
||||
e.printStackTrace();
|
||||
PlotSquared.debug("&cInvalid default flags for " + this.getWorldName() + ": " + StringMan
|
||||
.join(flags, ","));
|
||||
|
||||
StringBuilder flagBuilder = new StringBuilder();
|
||||
Collection<PlotFlag<?, ?>> flagCollection = this.getFlagContainer().getFlagMap().values();
|
||||
if (flagCollection.isEmpty()) {
|
||||
flagBuilder.append(Captions.NONE.getTranslated());
|
||||
} else {
|
||||
String prefix = " ";
|
||||
for (final PlotFlag<?, ?> flag : flagCollection) {
|
||||
Object value = flag.toString();
|
||||
flagBuilder.append(prefix).append(CaptionUtility.format(null, Captions.PLOT_FLAG_LIST.getTranslated(),
|
||||
flag.getName(), CaptionUtility.formatRaw(null, value.toString(), "")));
|
||||
prefix = ", ";
|
||||
}
|
||||
}
|
||||
|
||||
PlotSquared.log(Captions.PREFIX + "&3 - default flags: &7" + flagBuilder.toString());
|
||||
this.spawnEggs = config.getBoolean("event.spawn.egg");
|
||||
this.spawnCustom = config.getBoolean("event.spawn.custom");
|
||||
this.spawnBreeding = config.getBoolean("event.spawn.breeding");
|
||||
@ -527,13 +539,13 @@ public abstract class PlotArea {
|
||||
|| this.region.contains(location.getBlockVector3()));
|
||||
}
|
||||
|
||||
@NotNull Set<Plot> getPlotsAbs(final UUID uuid) {
|
||||
@NotNull public Set<Plot> getPlotsAbs(final UUID uuid) {
|
||||
if (uuid == null) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
final HashSet<Plot> myPlots = new HashSet<>();
|
||||
forEachPlotAbs(value -> {
|
||||
if (uuid.equals(value.owner)) {
|
||||
if (uuid.equals(value.getOwnerAbs())) {
|
||||
myPlots.add(value);
|
||||
}
|
||||
});
|
||||
@ -1022,7 +1034,7 @@ public abstract class PlotArea {
|
||||
this.terrain = terrain;
|
||||
}
|
||||
|
||||
private static Collection<PlotFlag<?, ?>> parseFlags(List<String> flagStrings) throws FlagParseException {
|
||||
private static Collection<PlotFlag<?, ?>> parseFlags(List<String> flagStrings) {
|
||||
final Collection<PlotFlag<?, ?>> flags = new ArrayList<>();
|
||||
for (final String key : flagStrings) {
|
||||
final String[] split;
|
||||
@ -1033,7 +1045,14 @@ public abstract class PlotArea {
|
||||
}
|
||||
final PlotFlag<?, ?> flagInstance = GlobalFlagContainer.getInstance().getFlagFromString(split[0]);
|
||||
if (flagInstance != null) {
|
||||
try {
|
||||
flags.add(flagInstance.parse(split[1]));
|
||||
} catch (final FlagParseException e) {
|
||||
PlotSquared.log(Captions.PREFIX.getTranslated() +
|
||||
String.format("§cFailed to parse default flag with key §6'%s'§c and value: §6'%s'§c."
|
||||
+ " Reason: %s. This flag will not be added as a default flag.",
|
||||
e.getFlag().getName(), e.getValue(), e.getErrorMessage()));
|
||||
}
|
||||
}
|
||||
}
|
||||
return flags;
|
||||
|
@ -30,7 +30,7 @@ import java.util.UUID;
|
||||
|
||||
public class PlotHandler {
|
||||
public static boolean sameOwners(final Plot plot1, final Plot plot2) {
|
||||
if (plot1.owner == null || plot2.owner == null) {
|
||||
if (plot1.getOwnerAbs() == null || plot2.getOwnerAbs() == null) {
|
||||
return false;
|
||||
}
|
||||
final Set<UUID> owners = plot1.getOwners();
|
||||
|
@ -25,8 +25,8 @@
|
||||
*/
|
||||
package com.plotsquared.core.plot.flag;
|
||||
|
||||
import com.plotsquared.core.config.Caption;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.plotsquared.core.config.Caption;
|
||||
import com.plotsquared.core.config.Captions;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
@ -48,7 +48,7 @@ public abstract class BlockTypeListFlag<F extends ListFlag<BlockTypeWrapper, F>>
|
||||
|
||||
@Override public F parse(@NotNull String input) throws FlagParseException {
|
||||
final List<BlockTypeWrapper> parsedBlocks = new ArrayList<>();
|
||||
final String[] split = input.split(",(?![^\\(\\[]*[\\]\\)])");
|
||||
final String[] split = input.replaceAll("\\s+", "").split(",(?![^\\(\\[]*[\\]\\)])");
|
||||
if (split.length == 0) {
|
||||
return this.flagOf(parsedBlocks);
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ public class SinglePlot extends Plot {
|
||||
getCenter(result);
|
||||
}
|
||||
|
||||
@Override protected boolean isLoaded() {
|
||||
@Override public boolean isLoaded() {
|
||||
getArea().loadWorld(getId());
|
||||
return super.isLoaded();
|
||||
}
|
||||
|
@ -197,7 +197,7 @@ public class SinglePlotArea extends GridPlotWorld {
|
||||
PlotSettings s = p.getSettings();
|
||||
|
||||
final FlagContainer oldContainer = p.getFlagContainer();
|
||||
p = new SinglePlot(p.getId(), p.owner, p.getTrusted(), p.getMembers(), p.getDenied(),
|
||||
p = new SinglePlot(p.getId(), p.getOwnerAbs(), p.getTrusted(), p.getMembers(), p.getDenied(),
|
||||
s.getAlias(), s.getPosition(), null, this, s.getMerged(), p.getTimestamp(), p.temp);
|
||||
p.getFlagContainer().addAll(oldContainer);
|
||||
|
||||
|
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* _____ _ _ _____ _
|
||||
* | __ \| | | | / ____| | |
|
||||
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
||||
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
||||
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
||||
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
||||
* | |
|
||||
* |_|
|
||||
* 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.plot.PlotArea;
|
||||
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 lombok.Getter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Objects;
|
||||
|
||||
public class AreaBoundDelegateLocalBlockQueue extends DelegateLocalBlockQueue {
|
||||
|
||||
@Getter private final PlotArea area;
|
||||
|
||||
public AreaBoundDelegateLocalBlockQueue(@NotNull final PlotArea area,
|
||||
@Nullable final LocalBlockQueue parent) {
|
||||
super(parent);
|
||||
this.area = Objects.requireNonNull(area);
|
||||
}
|
||||
|
||||
@Override public boolean setBlock(int x, int y, int z, BlockState id) {
|
||||
if (area.contains(x, z)) {
|
||||
return super.setBlock(x, y, z, id);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override public boolean setBlock(int x, int y, int z, BaseBlock id) {
|
||||
if (area.contains(x, z)) {
|
||||
return super.setBlock(x, y, z, id);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override public boolean setBlock(int x, int y, int z, Pattern pattern) {
|
||||
if (area.contains(x, z)) {
|
||||
return super.setBlock(x, y, z, pattern);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override public boolean setBiome(int x, int z, BiomeType biome) {
|
||||
if (area.contains(x, z)) {
|
||||
return super.setBiome(x, z, biome);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
@ -25,11 +25,11 @@
|
||||
*/
|
||||
package com.plotsquared.core.queue;
|
||||
|
||||
import com.plotsquared.core.util.task.RunnableVal;
|
||||
import com.plotsquared.core.util.MainUtil;
|
||||
import com.plotsquared.core.util.MathMan;
|
||||
import com.plotsquared.core.util.task.TaskManager;
|
||||
import com.plotsquared.core.util.PatternUtil;
|
||||
import com.plotsquared.core.util.task.RunnableVal;
|
||||
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;
|
||||
|
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* _____ _ _ _____ _
|
||||
* | __ \| | | | / ____| | |
|
||||
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
||||
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
||||
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
||||
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
||||
* | |
|
||||
* |_|
|
||||
* 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.PlotSquared;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class LocationOffsetDelegateLocalBlockQueue extends DelegateLocalBlockQueue {
|
||||
|
||||
private final boolean[][] canPlace;
|
||||
private final int blockX;
|
||||
private final int blockZ;
|
||||
|
||||
public LocationOffsetDelegateLocalBlockQueue(final boolean[][] canPlace,
|
||||
final int blockX, final int blockZ,
|
||||
@Nullable LocalBlockQueue parent) {
|
||||
super(parent);
|
||||
this.canPlace = canPlace;
|
||||
this.blockX = blockX;
|
||||
this.blockZ = blockZ;
|
||||
}
|
||||
|
||||
@Override public boolean setBlock(int x, int y, int z, 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 {
|
||||
if (canPlace[x - blockX][z - blockZ]) {
|
||||
return super.setBlock(x, y, z, id);
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
PlotSquared.debug(String.format("Failed to set block at: %d;%d;%d (to = %s) with offset %d;%d."
|
||||
+ " Translated to: %d;%d", x, y, z, id, blockX, blockZ, x - blockX, z - blockZ));
|
||||
throw e;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override public boolean setBlock(int x, int y, int z, Pattern pattern) {
|
||||
final BlockVector3 blockVector3 = BlockVector3.at(x + blockX, y, z + blockZ);
|
||||
return this.setBlock(x, y, z, pattern.apply(blockVector3));
|
||||
}
|
||||
|
||||
@Override public boolean setBiome(int x, int y, BiomeType biome) {
|
||||
return super.setBiome(x, y, biome);
|
||||
}
|
||||
|
||||
}
|
@ -32,6 +32,13 @@ import com.plotsquared.core.plot.Plot;
|
||||
import lombok.NonNull;
|
||||
import lombok.experimental.UtilityClass;
|
||||
|
||||
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_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;
|
||||
|
||||
/**
|
||||
* Entity related general utility methods
|
||||
*/
|
||||
@ -41,23 +48,23 @@ import lombok.experimental.UtilityClass;
|
||||
int i;
|
||||
switch (flagName) {
|
||||
case "mob-cap":
|
||||
i = 3;
|
||||
i = CAP_MOB;
|
||||
break;
|
||||
case "hostile-cap":
|
||||
i = 2;
|
||||
i = CAP_MONSTER;
|
||||
break;
|
||||
case "animal-cap":
|
||||
i = 1;
|
||||
i = CAP_ANIMAL;
|
||||
break;
|
||||
case "vehicle-cap":
|
||||
i = 4;
|
||||
i = CAP_VEHICLE;
|
||||
break;
|
||||
case "misc-cap":
|
||||
i = 5;
|
||||
i = CAP_MISC;
|
||||
break;
|
||||
case "entity-cap":
|
||||
default:
|
||||
i = 0;
|
||||
i = CAP_ENTITY;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ import com.sk89q.worldedit.math.BlockVector2;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.entity.EntityType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
@ -82,7 +83,7 @@ public abstract class WorldUtil {
|
||||
|
||||
public abstract boolean isBlockSolid(BlockState block);
|
||||
|
||||
public abstract StringComparison.ComparisonResult getClosestBlock(String name);
|
||||
public abstract StringComparison<BlockState>.ComparisonResult getClosestBlock(String name);
|
||||
|
||||
public abstract void getBiome(String world, int x, int z, Consumer<BiomeType> result);
|
||||
|
||||
@ -215,4 +216,7 @@ public abstract class WorldUtil {
|
||||
public abstract int getFoodLevel(PlotPlayer player);
|
||||
|
||||
public abstract void setFoodLevel(PlotPlayer player, int foodLevel);
|
||||
|
||||
public abstract Set<EntityType> getTypesInCategory(final String category);
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* _____ _ _ _____ _
|
||||
* | __ \| | | | / ____| | |
|
||||
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
||||
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
||||
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
||||
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
||||
* | |
|
||||
* |_|
|
||||
* 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.entity;
|
||||
|
||||
/**
|
||||
* A collection of {@link EntityCategory entity categories}
|
||||
*/
|
||||
public class EntityCategories {
|
||||
|
||||
public static final int CAP_ENTITY = 0;
|
||||
public static final int CAP_ANIMAL = 1;
|
||||
public static final int CAP_MONSTER = 2;
|
||||
public static final int CAP_MOB = 3;
|
||||
public static final int CAP_VEHICLE = 4;
|
||||
public static final int CAP_MISC = 5;
|
||||
|
||||
public static final EntityCategory ANIMAL = register("animal");
|
||||
public static final EntityCategory TAMEABLE = register("tameable");
|
||||
public static final EntityCategory VEHICLE = register("vehicle");
|
||||
public static final EntityCategory HOSTILE = register("hostile");
|
||||
public static final EntityCategory HANGING = register("hanging");
|
||||
public static final EntityCategory VILLAGER = register("villager");
|
||||
public static final EntityCategory PROJECTILE = register("projectile");
|
||||
public static final EntityCategory OTHER = register("other");
|
||||
public static final EntityCategory PLAYER = register("player");
|
||||
|
||||
public static EntityCategory register(final String id) {
|
||||
final EntityCategory entityCategory = new EntityCategory(id);
|
||||
EntityCategory.REGISTRY.register(entityCategory.getId(), entityCategory);
|
||||
return entityCategory;
|
||||
}
|
||||
|
||||
public static void init() {}
|
||||
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* _____ _ _ _____ _
|
||||
* | __ \| | | | / ____| | |
|
||||
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
||||
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
||||
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
||||
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
||||
* | |
|
||||
* |_|
|
||||
* 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.entity;
|
||||
|
||||
import com.plotsquared.core.util.WorldUtil;
|
||||
import com.sk89q.worldedit.registry.Category;
|
||||
import com.sk89q.worldedit.registry.Keyed;
|
||||
import com.sk89q.worldedit.registry.NamespacedRegistry;
|
||||
import com.sk89q.worldedit.world.entity.EntityType;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Categories to which an {@link com.sk89q.worldedit.entity.Entity} may belong
|
||||
*/
|
||||
public class EntityCategory extends Category<EntityType> implements Keyed {
|
||||
|
||||
public static final NamespacedRegistry<EntityCategory> REGISTRY = new NamespacedRegistry<>("entity type");
|
||||
|
||||
private final String key;
|
||||
|
||||
protected EntityCategory(final String id) {
|
||||
super("plotsquared:" + id);
|
||||
this.key = id;
|
||||
}
|
||||
|
||||
@Override protected Set<EntityType> load() {
|
||||
return WorldUtil.IMP.getTypesInCategory(this.key);
|
||||
}
|
||||
|
||||
}
|
@ -85,7 +85,7 @@ public class UUIDHandler {
|
||||
final HashSet<UUID> uuids = new HashSet<>();
|
||||
PlotSquared.get().forEachPlotRaw(plot -> {
|
||||
if (plot.hasOwner()) {
|
||||
uuids.add(plot.owner);
|
||||
uuids.add(plot.getOwnerAbs());
|
||||
uuids.addAll(plot.getTrusted());
|
||||
uuids.addAll(plot.getMembers());
|
||||
uuids.addAll(plot.getDenied());
|
||||
@ -131,8 +131,8 @@ public class UUIDHandler {
|
||||
return implementation.getName(uuid);
|
||||
}
|
||||
|
||||
public static PlotPlayer getPlayer(UUID uuid) {
|
||||
if (implementation == null) {
|
||||
@Nullable public static PlotPlayer getPlayer(@Nullable final UUID uuid) {
|
||||
if (implementation == null || uuid == null) {
|
||||
return null;
|
||||
}
|
||||
return check(implementation.getPlayer(uuid));
|
||||
|
@ -156,8 +156,8 @@ public abstract class UUIDHandlerImplementation {
|
||||
UUIDHandlerImplementation.this.unknown.remove(offline);
|
||||
Set<Plot> plots = PlotSquared.get().getPlotsAbs(offline);
|
||||
if (!plots.isEmpty()) {
|
||||
for (Plot plot : plots) {
|
||||
plot.owner = uuid;
|
||||
for (final Plot plot : plots) {
|
||||
plot.setOwnerAbs(uuid);
|
||||
}
|
||||
DBFunc.replaceUUID(offline, uuid);
|
||||
PlotSquared.debug("&cDetected invalid UUID stored for: " + name.value);
|
||||
@ -178,8 +178,8 @@ public abstract class UUIDHandlerImplementation {
|
||||
UUIDHandlerImplementation.this.unknown.remove(offlineUpper);
|
||||
Set<Plot> plots = PlotSquared.get().getPlotsAbs(offlineUpper);
|
||||
if (!plots.isEmpty()) {
|
||||
for (Plot plot : plots) {
|
||||
plot.owner = uuid;
|
||||
for (final Plot plot : plots) {
|
||||
plot.setOwnerAbs(uuid);
|
||||
}
|
||||
replace(offlineUpper, uuid, name.value);
|
||||
}
|
||||
@ -192,8 +192,8 @@ public abstract class UUIDHandlerImplementation {
|
||||
if (!existing.equals(uuid)) {
|
||||
Set<Plot> plots = PlotSquared.get().getPlots(existing);
|
||||
if (!plots.isEmpty()) {
|
||||
for (Plot plot : plots) {
|
||||
plot.owner = uuid;
|
||||
for (final Plot plot : plots) {
|
||||
plot.setOwnerAbs(uuid);
|
||||
}
|
||||
replace(existing, uuid, name.value);
|
||||
}
|
||||
|
@ -78,12 +78,13 @@ subprojects {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile group: 'org.json', name: 'json', version: '20190722'
|
||||
|
||||
implementation("com.sk89q.worldedit:worldedit-core:7.0.0") {
|
||||
exclude(module: "bukkit-classloader-check")
|
||||
exclude(module: "mockito-core")
|
||||
exclude(module: "dummypermscompat")
|
||||
}
|
||||
compile group: 'org.json', name: 'json', version: '20190722'
|
||||
|
||||
implementation("net.kyori:text-api:3.0.2")
|
||||
implementation("net.kyori:text-serializer-gson:3.0.2")
|
||||
@ -118,6 +119,7 @@ subprojects {
|
||||
|
||||
shadowJar {
|
||||
dependencies {
|
||||
include(dependency("org.json:json:20190722"))
|
||||
include(dependency("net.kyori:text-api:3.0.2"))
|
||||
}
|
||||
relocate("io.papermc.lib", "com.plotsquared.bukkit.paperlib")
|
||||
|
Loading…
Reference in New Issue
Block a user