Merge branch 'v6' into feature/v6/pipeline-queue

# Conflicts:
#	Bukkit/src/main/java/com/plotsquared/bukkit/BukkitPlatform.java
#	Bukkit/src/main/java/com/plotsquared/bukkit/inject/BukkitModule.java
#	Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitUtil.java
#	Core/src/main/java/com/plotsquared/core/queue/BasicLocalBlockQueue.java
This commit is contained in:
dordsor21 2020-07-24 12:21:40 +01:00
commit e53c53bb4a
No known key found for this signature in database
GPG Key ID: 1E53E88969FFCF0B
60 changed files with 2043 additions and 1044 deletions

View File

@ -106,6 +106,8 @@ shadowJar {
include(dependency("javax.annotation:javax-annotation-api")) include(dependency("javax.annotation:javax-annotation-api"))
include(dependency('org.apache.logging.log4j:log4j-slf4j-impl')) include(dependency('org.apache.logging.log4j:log4j-slf4j-impl'))
include(dependency('org.slf4j:slf4j-api')) include(dependency('org.slf4j:slf4j-api'))
include(dependency('javax.inject:javax.inject:1'))
include(dependency('aopalliance:aopalliance:1.0'))
} }
relocate('net.kyori.text', 'com.plotsquared.formatting.text') relocate('net.kyori.text', 'com.plotsquared.formatting.text')

View File

@ -34,6 +34,7 @@ import com.google.inject.TypeLiteral;
import com.plotsquared.bukkit.generator.BukkitPlotGenerator; import com.plotsquared.bukkit.generator.BukkitPlotGenerator;
import com.plotsquared.bukkit.inject.BackupModule; import com.plotsquared.bukkit.inject.BackupModule;
import com.plotsquared.bukkit.inject.BukkitModule; import com.plotsquared.bukkit.inject.BukkitModule;
import com.plotsquared.bukkit.inject.PermissionModule;
import com.plotsquared.bukkit.inject.WorldManagerModule; import com.plotsquared.bukkit.inject.WorldManagerModule;
import com.plotsquared.bukkit.listener.ChunkListener; import com.plotsquared.bukkit.listener.ChunkListener;
import com.plotsquared.bukkit.listener.EntitySpawnListener; import com.plotsquared.bukkit.listener.EntitySpawnListener;
@ -103,7 +104,6 @@ import com.plotsquared.core.util.ConsoleColors;
import com.plotsquared.core.util.EconHandler; import com.plotsquared.core.util.EconHandler;
import com.plotsquared.core.util.EventDispatcher; import com.plotsquared.core.util.EventDispatcher;
import com.plotsquared.core.util.FileUtils; import com.plotsquared.core.util.FileUtils;
import com.plotsquared.core.util.PermHandler;
import com.plotsquared.core.util.PlatformWorldManager; import com.plotsquared.core.util.PlatformWorldManager;
import com.plotsquared.core.util.PlayerManager; import com.plotsquared.core.util.PlayerManager;
import com.plotsquared.core.util.PremiumVerification; import com.plotsquared.core.util.PremiumVerification;
@ -123,7 +123,6 @@ import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.command.PluginCommand; import org.bukkit.command.PluginCommand;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
@ -184,7 +183,6 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
private boolean methodUnloadSetup = false; private boolean methodUnloadSetup = false;
private boolean metricsStarted; private boolean metricsStarted;
private EconHandler econ; private EconHandler econ;
private PermHandler perm;
@Getter private Injector injector; @Getter private Injector injector;
@ -249,9 +247,11 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
// We create the injector after PlotSquared has been initialized, so that we have access // We create the injector after PlotSquared has been initialized, so that we have access
// to generated instances and settings // to generated instances and settings
this.injector = Guice this.injector = Guice.createInjector(Stage.PRODUCTION, new PermissionModule(),
.createInjector(Stage.PRODUCTION, new WorldManagerModule(), new PlotSquaredModule(), new WorldManagerModule(),
new BukkitModule(this), new BackupModule()); new PlotSquaredModule(),
new BukkitModule(this),
new BackupModule());
this.injector.injectMembers(this); this.injector.injectMembers(this);
if (PremiumVerification.isPremium() && Settings.Enabled_Components.UPDATE_NOTIFICATIONS) { if (PremiumVerification.isPremium() && Settings.Enabled_Components.UPDATE_NOTIFICATIONS) {
@ -344,10 +344,7 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
// Economy // Economy
if (Settings.Enabled_Components.ECONOMY) { if (Settings.Enabled_Components.ECONOMY) {
TaskManager.runTask(() -> { TaskManager.runTask(() -> {
final PermHandler permHandler = getInjector().getInstance(PermHandler.class); this.getPermissionHandler().initialize();
if (permHandler != null) {
permHandler.init();
}
final EconHandler econHandler = getInjector().getInstance(EconHandler.class); final EconHandler econHandler = getInjector().getInstance(EconHandler.class);
if (econHandler != null) { if (econHandler != null) {
econHandler.init(); econHandler.init();
@ -589,7 +586,8 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
} }
final Plot plot = area.getOwnedPlot(id); final Plot plot = area.getOwnedPlot(id);
if (plot != null) { if (plot != null) {
if (!plot.getFlag(ServerPlotFlag.class) || PlotPlayer.wrap(plot.getOwner()) == null) { if (!plot.getFlag(ServerPlotFlag.class) || PlotSquared.platform().getPlayerManager()
.getPlayerIfExists(plot.getOwner()) == null) {
if (world.getKeepSpawnInMemory()) { if (world.getKeepSpawnInMemory()) {
world.setKeepSpawnInMemory(false); world.setKeepSpawnInMemory(false);
return; return;
@ -1104,39 +1102,6 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
} }
} }
/**
* Attempt to retrieve a {@link PlotPlayer} from a player identifier.
* This method accepts:
* - {@link Player} objects,
* - {@link OfflinePlayer} objects,
* - {@link String} usernames for online players, and
* - {@link UUID} UUIDs for online players
* <p>
* In the case of offline players, a fake {@link Player} instance will be created.
* This is a rather expensive operation, and should be avoided if possible.
*
* @param player The player to convert to a PlotPlayer
* @return The plot player instance that corresponds to the identifier, or null
* if no such player object could be created
*/
@Override @Nullable public PlotPlayer<Player> wrapPlayer(final Object player) {
if (player instanceof Player) {
return BukkitUtil.adapt((Player) player);
}
if (player instanceof OfflinePlayer) {
return BukkitUtil.adapt((OfflinePlayer) player);
}
if (player instanceof String) {
return (PlotPlayer<Player>) PlotSquared.platform().getPlayerManager()
.getPlayerIfExists((String) player);
}
if (player instanceof UUID) {
return (PlotPlayer<Player>) PlotSquared.platform().getPlayerManager()
.getPlayerIfExists((UUID) player);
}
return null;
}
@Override public String getNMSPackage() { @Override public String getNMSPackage() {
final String name = Bukkit.getServer().getClass().getPackage().getName(); final String name = Bukkit.getServer().getClass().getPackage().getName();
return name.substring(name.lastIndexOf('.') + 1); return name.substring(name.lastIndexOf('.') + 1);
@ -1173,8 +1138,9 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
return getInjector().getInstance(Key.get(new TypeLiteral<PlatformWorldManager<World>>() {})); return getInjector().getInstance(Key.get(new TypeLiteral<PlatformWorldManager<World>>() {}));
} }
@Override @Nonnull public PlayerManager<? extends PlotPlayer<Player>, ? extends Player> getPlayerManager() { @Override @Nonnull @SuppressWarnings("ALL")
return getInjector().getInstance(Key.get(new TypeLiteral<PlayerManager<BukkitPlayer, Player>>() {})); public PlayerManager<? extends PlotPlayer<Player>, ? extends Player> getPlayerManager() {
return (PlayerManager<BukkitPlayer, Player>) getInjector().getInstance(PlayerManager.class);
} }
} }

View File

@ -26,8 +26,9 @@
package com.plotsquared.bukkit.inject; package com.plotsquared.bukkit.inject;
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import com.google.inject.Singleton;
import com.google.inject.assistedinject.FactoryModuleBuilder; import com.google.inject.assistedinject.FactoryModuleBuilder;
import com.google.inject.util.Providers;
import com.plotsquared.bukkit.BukkitPlatform; import com.plotsquared.bukkit.BukkitPlatform;
import com.plotsquared.bukkit.player.BukkitPlayerManager; import com.plotsquared.bukkit.player.BukkitPlayerManager;
import com.plotsquared.bukkit.queue.BukkitChunkCoordinator; import com.plotsquared.bukkit.queue.BukkitChunkCoordinator;
@ -36,7 +37,6 @@ import com.plotsquared.bukkit.schematic.BukkitSchematicHandler;
import com.plotsquared.bukkit.util.BukkitChunkManager; import com.plotsquared.bukkit.util.BukkitChunkManager;
import com.plotsquared.bukkit.util.BukkitEconHandler; import com.plotsquared.bukkit.util.BukkitEconHandler;
import com.plotsquared.bukkit.util.BukkitInventoryUtil; import com.plotsquared.bukkit.util.BukkitInventoryUtil;
import com.plotsquared.bukkit.util.BukkitPermHandler;
import com.plotsquared.bukkit.util.BukkitRegionManager; import com.plotsquared.bukkit.util.BukkitRegionManager;
import com.plotsquared.bukkit.util.BukkitSetupUtils; import com.plotsquared.bukkit.util.BukkitSetupUtils;
import com.plotsquared.bukkit.util.BukkitUtil; import com.plotsquared.bukkit.util.BukkitUtil;
@ -58,7 +58,6 @@ import com.plotsquared.core.queue.QueueProvider;
import com.plotsquared.core.util.ChunkManager; import com.plotsquared.core.util.ChunkManager;
import com.plotsquared.core.util.EconHandler; import com.plotsquared.core.util.EconHandler;
import com.plotsquared.core.util.InventoryUtil; import com.plotsquared.core.util.InventoryUtil;
import com.plotsquared.core.util.PermHandler;
import com.plotsquared.core.util.PlayerManager; import com.plotsquared.core.util.PlayerManager;
import com.plotsquared.core.util.RegionManager; import com.plotsquared.core.util.RegionManager;
import com.plotsquared.core.util.SchematicHandler; import com.plotsquared.core.util.SchematicHandler;
@ -72,6 +71,7 @@ import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@RequiredArgsConstructor @RequiredArgsConstructor
public class BukkitModule extends AbstractModule { public class BukkitModule extends AbstractModule {
@ -98,7 +98,6 @@ public class BukkitModule extends AbstractModule {
bind(ChunkManager.class).to(BukkitChunkManager.class); bind(ChunkManager.class).to(BukkitChunkManager.class);
bind(RegionManager.class).to(BukkitRegionManager.class); bind(RegionManager.class).to(BukkitRegionManager.class);
bind(SchematicHandler.class).to(BukkitSchematicHandler.class); bind(SchematicHandler.class).to(BukkitSchematicHandler.class);
this.setupVault();
if (Settings.Enabled_Components.WORLDS) { if (Settings.Enabled_Components.WORLDS) {
bind(PlotAreaManager.class).to(SinglePlotAreaManager.class); bind(PlotAreaManager.class).to(SinglePlotAreaManager.class);
} else { } else {
@ -111,26 +110,14 @@ public class BukkitModule extends AbstractModule {
install(new FactoryModuleBuilder().build(ChunkCoordinatorBuilderFactory.class)); install(new FactoryModuleBuilder().build(ChunkCoordinatorBuilderFactory.class));
} }
private void setupVault() { @Provides @Singleton @Nullable EconHandler provideEconHandler() {
if (Bukkit.getPluginManager().isPluginEnabled("Vault")) { if (Bukkit.getPluginManager().isPluginEnabled("Vault")) {
BukkitPermHandler bukkitPermHandler = null;
try { try {
bukkitPermHandler = new BukkitPermHandler(); return new BukkitEconHandler();
bind(PermHandler.class).toInstance(bukkitPermHandler);
} catch (final Exception ignored) { } catch (final Exception ignored) {
bind(PermHandler.class).toProvider(Providers.of(null));
} }
try {
final BukkitEconHandler bukkitEconHandler =
new BukkitEconHandler(bukkitPermHandler);
bind(EconHandler.class).toInstance(bukkitEconHandler);
} catch (final Exception ignored) {
bind(EconHandler.class).toProvider(Providers.of(null));
}
} else {
bind(PermHandler.class).toProvider(Providers.of(null));
bind(EconHandler.class).toProvider(Providers.of(null));
} }
return null;
} }
} }

View File

@ -23,38 +23,26 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package com.plotsquared.bukkit.util; package com.plotsquared.bukkit.inject;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import com.google.inject.Singleton; import com.google.inject.Singleton;
import com.plotsquared.core.util.PermHandler; import com.plotsquared.bukkit.permissions.BukkitPermissionHandler;
import net.milkbowl.vault.permission.Permission; import com.plotsquared.bukkit.permissions.VaultPermissionHandler;
import com.plotsquared.core.permissions.PermissionHandler;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.plugin.RegisteredServiceProvider;
@Singleton public class BukkitPermHandler extends PermHandler { public class PermissionModule extends AbstractModule {
private Permission perms; @Provides @Singleton PermissionHandler providePermissionHandler() {
try {
@Override if (Bukkit.getPluginManager().isPluginEnabled("Vault")) {
public boolean init() { return new VaultPermissionHandler();
if (this.perms == null) {
setupPermissions();
} }
return this.perms != null; } catch (final Exception ignored) {
}
return new BukkitPermissionHandler();
} }
private void setupPermissions() {
if (Bukkit.getServer().getPluginManager().getPlugin("Vault") == null) {
return;
}
RegisteredServiceProvider<Permission> permissionProvider =
Bukkit.getServer().getServicesManager().getRegistration(Permission.class);
if (permissionProvider != null) {
this.perms = permissionProvider.getProvider();
}
}
@Override public boolean hasPermission(String world, String player, String perm) {
return this.perms.playerHas(world, Bukkit.getOfflinePlayer(player), perm);
}
} }

View File

@ -38,6 +38,8 @@ import com.plotsquared.core.database.DBFunc;
import com.plotsquared.core.listener.PlayerBlockEventType; import com.plotsquared.core.listener.PlayerBlockEventType;
import com.plotsquared.core.listener.PlotListener; import com.plotsquared.core.listener.PlotListener;
import com.plotsquared.core.location.Location; import com.plotsquared.core.location.Location;
import com.plotsquared.core.player.MetaDataAccess;
import com.plotsquared.core.player.PlayerMetaDataKeys;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea; import com.plotsquared.core.plot.PlotArea;
@ -216,8 +218,8 @@ import org.bukkit.plugin.Plugin;
import org.bukkit.projectiles.BlockProjectileSource; import org.bukkit.projectiles.BlockProjectileSource;
import org.bukkit.projectiles.ProjectileSource; import org.bukkit.projectiles.ProjectileSource;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import javax.annotation.Nonnull;
import javax.annotation.Nonnull;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
@ -731,7 +733,9 @@ import java.util.regex.Pattern;
public void onTeleport(PlayerTeleportEvent event) { public void onTeleport(PlayerTeleportEvent event) {
Player player = event.getPlayer(); Player player = event.getPlayer();
BukkitPlayer pp = BukkitUtil.adapt(player); BukkitPlayer pp = BukkitUtil.adapt(player);
Plot lastPlot = pp.getMeta(PlotPlayer.META_LAST_PLOT); try (final MetaDataAccess<Plot> lastPlotAccess =
pp.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_LAST_PLOT)) {
Plot lastPlot = lastPlotAccess.get().orElse(null);
org.bukkit.Location to = event.getTo(); org.bukkit.Location to = event.getTo();
//noinspection ConstantConditions //noinspection ConstantConditions
if (to != null) { if (to != null) {
@ -740,9 +744,12 @@ import java.util.regex.Pattern;
if (area == null) { if (area == null) {
if (lastPlot != null) { if (lastPlot != null) {
plotExit(pp, lastPlot); plotExit(pp, lastPlot);
pp.deleteMeta(PlotPlayer.META_LAST_PLOT); lastPlotAccess.remove();
}
try (final MetaDataAccess<Location> lastLocationAccess =
pp.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_LOCATION)) {
lastLocationAccess.remove();
} }
pp.deleteMeta(PlotPlayer.META_LOCATION);
return; return;
} }
Plot plot = area.getPlot(location); Plot plot = area.getPlot(location);
@ -752,14 +759,13 @@ import java.util.regex.Pattern;
// to is identical to the plot's home location, and untrusted-visit is true // to is identical to the plot's home location, and untrusted-visit is true
// i.e. untrusted-visit can override deny-teleport // i.e. untrusted-visit can override deny-teleport
// this is acceptable, because otherwise it wouldn't make sense to have both flags set // this is acceptable, because otherwise it wouldn't make sense to have both flags set
if (!result && !(plot.getFlag(UntrustedVisitFlag.class) && plot.getHomeSynchronous() if (!result && !(plot.getFlag(UntrustedVisitFlag.class) && plot.getHomeSynchronous().equals(BukkitUtil.adaptComplete(to)))) {
.equals(BukkitUtil.adaptComplete(to)))) { MainUtil.sendMessage(pp, Captions.NO_PERMISSION_EVENT, Captions.PERMISSION_ADMIN_ENTRY_DENIED);
MainUtil.sendMessage(pp, Captions.NO_PERMISSION_EVENT,
Captions.PERMISSION_ADMIN_ENTRY_DENIED);
event.setCancelled(true); event.setCancelled(true);
} }
} }
} }
}
playerMove(event); playerMove(event);
} }
@ -847,19 +853,29 @@ import java.util.regex.Pattern;
} }
// Set last location // Set last location
Location location = BukkitUtil.adapt(to); Location location = BukkitUtil.adapt(to);
pp.setMeta(PlotPlayer.META_LOCATION, location); try (final MetaDataAccess<Location> lastLocationAccess =
pp.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_LOCATION)) {
lastLocationAccess.remove();
}
PlotArea area = location.getPlotArea(); PlotArea area = location.getPlotArea();
if (area == null) { if (area == null) {
pp.deleteMeta(PlotPlayer.META_LAST_PLOT); try (final MetaDataAccess<Plot> lastPlotAccess =
pp.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_LAST_PLOT)) {
lastPlotAccess.remove();
}
return; return;
} }
Plot now = area.getPlot(location); Plot now = area.getPlot(location);
Plot lastPlot = pp.getMeta(PlotPlayer.META_LAST_PLOT); Plot lastPlot;
try (final MetaDataAccess<Plot> lastPlotAccess =
pp.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_LAST_PLOT)) {
lastPlot = lastPlotAccess.get().orElse(null);
}
if (now == null) { if (now == null) {
if (lastPlot != null && !plotExit(pp, lastPlot) && this.tmpTeleport && !pp try (final MetaDataAccess<Boolean> kickAccess =
.getMeta("kick", false)) { pp.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_KICK)) {
MainUtil.sendMessage(pp, Captions.NO_PERMISSION_EVENT, if (lastPlot != null && !plotExit(pp, lastPlot) && this.tmpTeleport && !kickAccess.get().orElse(false)) {
Captions.PERMISSION_ADMIN_EXIT_DENIED); MainUtil.sendMessage(pp, Captions.NO_PERMISSION_EVENT, Captions.PERMISSION_ADMIN_EXIT_DENIED);
this.tmpTeleport = false; this.tmpTeleport = false;
if (lastPlot.equals(BukkitUtil.adapt(from).getPlot())) { if (lastPlot.equals(BukkitUtil.adapt(from).getPlot())) {
player.teleport(from); player.teleport(from);
@ -870,6 +886,7 @@ import java.util.regex.Pattern;
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
}
} else if (now.equals(lastPlot)) { } else if (now.equals(lastPlot)) {
ForceFieldListener.handleForcefield(player, pp, now); ForceFieldListener.handleForcefield(player, pp, now);
} else if (!plotEntry(pp, now) && this.tmpTeleport) { } else if (!plotEntry(pp, now) && this.tmpTeleport) {
@ -909,19 +926,29 @@ import java.util.regex.Pattern;
} }
// Set last location // Set last location
Location location = BukkitUtil.adapt(to); Location location = BukkitUtil.adapt(to);
pp.setMeta(PlotPlayer.META_LOCATION, location); try (final MetaDataAccess<Location> lastLocationAccess =
pp.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_LOCATION)) {
lastLocationAccess.set(location);
}
PlotArea area = location.getPlotArea(); PlotArea area = location.getPlotArea();
if (area == null) { if (area == null) {
pp.deleteMeta(PlotPlayer.META_LAST_PLOT); try (final MetaDataAccess<Plot> lastPlotAccess =
pp.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_LAST_PLOT)) {
lastPlotAccess.remove();
}
return; return;
} }
Plot now = area.getPlot(location); Plot now = area.getPlot(location);
Plot lastPlot = pp.getMeta(PlotPlayer.META_LAST_PLOT); Plot lastPlot;
try (final MetaDataAccess<Plot> lastPlotAccess =
pp.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_LAST_PLOT)) {
lastPlot = lastPlotAccess.get().orElse(null);
}
if (now == null) { if (now == null) {
if (lastPlot != null && !plotExit(pp, lastPlot) && this.tmpTeleport && !pp try (final MetaDataAccess<Boolean> kickAccess =
.getMeta("kick", false)) { pp.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_KICK)) {
MainUtil.sendMessage(pp, Captions.NO_PERMISSION_EVENT, if (lastPlot != null && !plotExit(pp, lastPlot) && this.tmpTeleport && !kickAccess.get().orElse(false)) {
Captions.PERMISSION_ADMIN_EXIT_DENIED); MainUtil.sendMessage(pp, Captions.NO_PERMISSION_EVENT, Captions.PERMISSION_ADMIN_EXIT_DENIED);
this.tmpTeleport = false; this.tmpTeleport = false;
if (lastPlot.equals(BukkitUtil.adapt(from).getPlot())) { if (lastPlot.equals(BukkitUtil.adapt(from).getPlot())) {
player.teleport(from); player.teleport(from);
@ -932,6 +959,7 @@ import java.util.regex.Pattern;
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
}
} else if (now.equals(lastPlot)) { } else if (now.equals(lastPlot)) {
ForceFieldListener.handleForcefield(player, pp, now); ForceFieldListener.handleForcefield(player, pp, now);
} else if (!plotEntry(pp, now) && this.tmpTeleport) { } else if (!plotEntry(pp, now) && this.tmpTeleport) {
@ -1155,8 +1183,15 @@ import java.util.regex.Pattern;
Player player = event.getPlayer(); Player player = event.getPlayer();
BukkitPlayer pp = BukkitUtil.adapt(player); BukkitPlayer pp = BukkitUtil.adapt(player);
// Delete last location // Delete last location
Plot plot = (Plot) pp.deleteMeta(PlotPlayer.META_LAST_PLOT); Plot plot;
pp.deleteMeta(PlotPlayer.META_LOCATION); try (final MetaDataAccess<Plot> lastPlotAccess =
pp.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_LAST_PLOT)) {
plot = lastPlotAccess.remove();
}
try (final MetaDataAccess<Location> lastLocationAccess =
pp.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_LOCATION)) {
lastLocationAccess.remove();
}
if (plot != null) { if (plot != null) {
plotExit(pp, plot); plotExit(pp, plot);
} }
@ -1167,9 +1202,6 @@ import java.util.regex.Pattern;
} }
} }
} }
if (Settings.Enabled_Components.PERMISSION_CACHE) {
pp.deleteMeta("perm");
}
Location location = pp.getLocation(); Location location = pp.getLocation();
PlotArea area = location.getPlotArea(); PlotArea area = location.getPlotArea();
if (location.isPlotArea()) { if (location.isPlotArea()) {

View File

@ -0,0 +1,86 @@
/*
* _____ _ _ _____ _
* | __ \| | | | / ____| | |
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
* | |
* |_|
* 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.permissions;
import com.plotsquared.bukkit.player.BukkitPlayer;
import com.plotsquared.core.permissions.ConsolePermissionProfile;
import com.plotsquared.core.permissions.PermissionHandler;
import com.plotsquared.core.permissions.PermissionProfile;
import com.plotsquared.core.player.ConsolePlayer;
import com.plotsquared.core.player.OfflinePlotPlayer;
import com.plotsquared.core.player.PlotPlayer;
import org.bukkit.entity.Player;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.lang.ref.WeakReference;
import java.util.EnumSet;
import java.util.Optional;
import java.util.Set;
public class BukkitPermissionHandler implements PermissionHandler {
@Override public void initialize() {
}
@Nonnull @Override public Optional<PermissionProfile> getPermissionProfile(
@Nonnull PlotPlayer<?> playerPlotPlayer) {
if (playerPlotPlayer instanceof BukkitPlayer) {
final BukkitPlayer bukkitPlayer = (BukkitPlayer) playerPlotPlayer;
return Optional.of(new BukkitPermissionProfile(bukkitPlayer.getPlatformPlayer()));
} else if (playerPlotPlayer instanceof ConsolePlayer) {
return Optional.of(ConsolePermissionProfile.INSTANCE);
}
return Optional.empty();
}
@Nonnull @Override public Optional<PermissionProfile> getPermissionProfile(
@Nonnull OfflinePlotPlayer offlinePlotPlayer) {
return Optional.empty();
}
@Nonnull @Override public Set<PermissionHandlerCapability> getCapabilities() {
return EnumSet.of(PermissionHandlerCapability.ONLINE_PERMISSIONS);
}
private static final class BukkitPermissionProfile implements PermissionProfile {
private final WeakReference<Player> playerReference;
private BukkitPermissionProfile(@Nonnull final Player player) {
this.playerReference = new WeakReference<>(player);
}
@Override public boolean hasPermission(@Nullable final String world,
@Nonnull final String permission) {
final Player player = this.playerReference.get();
return player != null && player.hasPermission(permission);
}
}
}

View File

@ -0,0 +1,109 @@
/*
* _____ _ _ _____ _
* | __ \| | | | / ____| | |
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
* | |
* |_|
* 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.permissions;
import com.plotsquared.bukkit.player.BukkitOfflinePlayer;
import com.plotsquared.bukkit.player.BukkitPlayer;
import com.plotsquared.core.permissions.ConsolePermissionProfile;
import com.plotsquared.core.permissions.PermissionHandler;
import com.plotsquared.core.permissions.PermissionProfile;
import com.plotsquared.core.player.ConsolePlayer;
import com.plotsquared.core.player.OfflinePlotPlayer;
import com.plotsquared.core.player.PlotPlayer;
import net.milkbowl.vault.permission.Permission;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.plugin.RegisteredServiceProvider;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.EnumSet;
import java.util.Optional;
import java.util.Set;
public class VaultPermissionHandler implements PermissionHandler {
private Permission permissions;
@Override public void initialize() {
if (Bukkit.getServer().getPluginManager().getPlugin("Vault") == null) {
throw new IllegalStateException("Vault is not present on the server");
}
RegisteredServiceProvider<Permission> permissionProvider =
Bukkit.getServer().getServicesManager().getRegistration(Permission.class);
if (permissionProvider != null) {
this.permissions = permissionProvider.getProvider();
}
}
@Nonnull @Override public Optional<PermissionProfile> getPermissionProfile(
@Nonnull PlotPlayer<?> playerPlotPlayer) {
if (playerPlotPlayer instanceof BukkitPlayer) {
final BukkitPlayer bukkitPlayer = (BukkitPlayer) playerPlotPlayer;
return Optional.of(new VaultPermissionProfile(bukkitPlayer.getPlatformPlayer()));
} else if (playerPlotPlayer instanceof ConsolePlayer) {
return Optional.of(ConsolePermissionProfile.INSTANCE);
}
return Optional.empty();
}
@Nonnull @Override public Optional<PermissionProfile> getPermissionProfile(
@Nonnull OfflinePlotPlayer offlinePlotPlayer) {
if (offlinePlotPlayer instanceof BukkitOfflinePlayer) {
return Optional.of(new VaultPermissionProfile(((BukkitOfflinePlayer) offlinePlotPlayer).player));
}
return Optional.empty();
}
@Nonnull @Override public Set<PermissionHandlerCapability> getCapabilities() {
return EnumSet.of(PermissionHandlerCapability.PER_WORLD_PERMISSIONS,
PermissionHandlerCapability.ONLINE_PERMISSIONS,
PermissionHandlerCapability.OFFLINE_PERMISSIONS);
}
private final class VaultPermissionProfile implements PermissionProfile {
private final OfflinePlayer offlinePlayer;
private VaultPermissionProfile(@Nonnull final OfflinePlayer offlinePlayer) {
this.offlinePlayer = offlinePlayer;
}
@Override public boolean hasPermission(@Nullable final String world,
@Nonnull final String permission) {
if (permissions == null) {
return false;
}
if (world == null && offlinePlayer instanceof BukkitPlayer) {
return permissions.playerHas(((BukkitPlayer) offlinePlayer).getPlatformPlayer(), permission);
}
return permissions.playerHas(world, offlinePlayer, permission);
}
}
}

View File

@ -25,39 +25,49 @@
*/ */
package com.plotsquared.bukkit.player; package com.plotsquared.bukkit.player;
import com.plotsquared.core.permissions.NullPermissionProfile;
import com.plotsquared.core.permissions.PermissionHandler;
import com.plotsquared.core.permissions.PermissionProfile;
import com.plotsquared.core.player.OfflinePlotPlayer; import com.plotsquared.core.player.OfflinePlotPlayer;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import javax.annotation.Nonnegative;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.UUID; import java.util.UUID;
public class BukkitOfflinePlayer implements OfflinePlotPlayer { public class BukkitOfflinePlayer implements OfflinePlotPlayer {
public final OfflinePlayer player; public final OfflinePlayer player;
private final PermissionProfile permissionProfile;
/** /**
* Please do not use this method. Instead use BukkitUtil.getPlayer(Player), * Please do not use this method. Instead use BukkitUtil.getPlayer(Player),
* as it caches player objects. * as it caches player objects.
*
* @param player
*/ */
public BukkitOfflinePlayer(OfflinePlayer player) { public BukkitOfflinePlayer(@Nonnull final OfflinePlayer player, @Nonnull final
PermissionHandler permissionHandler) {
this.player = player; this.player = player;
this.permissionProfile = permissionHandler.getPermissionProfile(this)
.orElse(NullPermissionProfile.INSTANCE);
} }
@Nonnull @Override public UUID getUUID() { @Nonnull @Override public UUID getUUID() {
return this.player.getUniqueId(); return this.player.getUniqueId();
} }
@Override public long getLastPlayed() { @Override @Nonnegative public long getLastPlayed() {
return this.player.getLastPlayed(); return this.player.getLastSeen();
}
@Override public boolean isOnline() {
return this.player.isOnline();
} }
@Override public String getName() { @Override public String getName() {
return this.player.getName(); return this.player.getName();
} }
@Override public boolean hasPermission(@Nullable final String world,
@Nonnull final String permission) {
return this.permissionProfile.hasPermission(world, permission);
}
} }

View File

@ -32,6 +32,7 @@ import com.plotsquared.core.configuration.Captions;
import com.plotsquared.core.configuration.Settings; import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.events.TeleportCause; import com.plotsquared.core.events.TeleportCause;
import com.plotsquared.core.location.Location; import com.plotsquared.core.location.Location;
import com.plotsquared.core.permissions.PermissionHandler;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.PlotWeather; import com.plotsquared.core.plot.PlotWeather;
import com.plotsquared.core.plot.world.PlotAreaManager; import com.plotsquared.core.plot.world.PlotAreaManager;
@ -53,6 +54,8 @@ import org.bukkit.event.EventException;
import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.permissions.PermissionAttachmentInfo; import org.bukkit.permissions.PermissionAttachmentInfo;
import org.bukkit.plugin.RegisteredListener; import org.bukkit.plugin.RegisteredListener;
import javax.annotation.Nonnegative;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -69,13 +72,11 @@ import static com.sk89q.worldedit.world.gamemode.GameModes.SURVIVAL;
public class BukkitPlayer extends PlotPlayer<Player> { public class BukkitPlayer extends PlotPlayer<Player> {
private static boolean CHECK_EFFECTIVE = true; private static boolean CHECK_EFFECTIVE = true;
private final EconHandler econHandler;
public final Player player; public final Player player;
private boolean offline; private final EconHandler econHandler;
private String name; private String name;
private String lastMessage = "";
private long lastMessageTime = 0L;
/** /**
* <p>Please do not use this method. Instead use * <p>Please do not use this method. Instead use
* BukkitUtil.getPlayer(Player), as it caches player objects.</p> * BukkitUtil.getPlayer(Player), as it caches player objects.</p>
@ -83,21 +84,16 @@ public class BukkitPlayer extends PlotPlayer<Player> {
* @param player Bukkit player instance * @param player Bukkit player instance
*/ */
public BukkitPlayer(@Nonnull final PlotAreaManager plotAreaManager, @Nonnull final EventDispatcher eventDispatcher, public BukkitPlayer(@Nonnull final PlotAreaManager plotAreaManager, @Nonnull final EventDispatcher eventDispatcher,
@Nonnull final Player player, @Nullable final EconHandler econHandler) { @Nonnull final Player player, @Nullable final EconHandler econHandler, @Nonnull final PermissionHandler permissionHandler) {
this(plotAreaManager, eventDispatcher, player, false, econHandler); this(plotAreaManager, eventDispatcher, player, false, econHandler, permissionHandler);
}
public BukkitPlayer(@Nonnull final PlotAreaManager plotAreaManager, @Nonnull final EventDispatcher eventDispatcher,
@Nonnull final Player player, final boolean offline, @Nullable final EconHandler econHandler) {
this(plotAreaManager, eventDispatcher, player, offline, true, econHandler);
} }
public BukkitPlayer(@Nonnull final PlotAreaManager plotAreaManager, @Nonnull final public BukkitPlayer(@Nonnull final PlotAreaManager plotAreaManager, @Nonnull final
EventDispatcher eventDispatcher, @Nonnull final Player player, final boolean offline, EventDispatcher eventDispatcher, @Nonnull final Player player,
final boolean realPlayer, @Nullable final EconHandler econHandler) { final boolean realPlayer, @Nullable final EconHandler econHandler,
super(plotAreaManager, eventDispatcher, econHandler); @Nonnull final PermissionHandler permissionHandler) {
super(plotAreaManager, eventDispatcher, econHandler, permissionHandler);
this.player = player; this.player = player;
this.offline = offline;
this.econHandler = econHandler; this.econHandler = econHandler;
if (realPlayer) { if (realPlayer) {
super.populatePersistentMetaMap(); super.populatePersistentMetaMap();
@ -125,8 +121,8 @@ public class BukkitPlayer extends PlotPlayer<Player> {
return player.getUniqueId(); return player.getUniqueId();
} }
@Override public long getLastPlayed() { @Override @Nonnegative public long getLastPlayed() {
return this.player.getLastPlayed(); return this.player.getLastSeen();
} }
@Override public boolean canTeleport(@Nonnull final Location location) { @Override public boolean canTeleport(@Nonnull final Location location) {
@ -161,14 +157,8 @@ public class BukkitPlayer extends PlotPlayer<Player> {
} }
} }
@Override public boolean hasPermission(final String permission) { @Override @Nonnegative public int hasPermissionRange(@Nonnull final String stub,
if (this.offline && this.econHandler != null) { @Nonnegative final int range) {
return this.econHandler.hasPermission(getName(), permission);
}
return this.player.hasPermission(permission);
}
@Override public int hasPermissionRange(final String stub, final int range) {
if (hasPermission(Captions.PERMISSION_ADMIN.getTranslated())) { if (hasPermission(Captions.PERMISSION_ADMIN.getTranslated())) {
return Integer.MAX_VALUE; return Integer.MAX_VALUE;
} }
@ -228,16 +218,12 @@ public class BukkitPlayer extends PlotPlayer<Player> {
return max; return max;
} }
@Override public boolean isPermissionSet(final String permission) {
return this.player.isPermissionSet(permission);
}
@Override public void sendMessage(String message) { @Override public void sendMessage(String message) {
message = message.replace('\u2010', '%').replace('\u2020', '&').replace('\u2030', '&'); message = message.replace('\u2010', '%').replace('\u2020', '&').replace('\u2030', '&');
if (!StringMan.isEqual(this.getMeta("lastMessage"), message) || ( if (!StringMan.isEqual(this.lastMessage, message) || (
System.currentTimeMillis() - this.<Long>getMeta("lastMessageTime") > 5000)) { System.currentTimeMillis() - this.lastMessageTime > 5000)) {
setMeta("lastMessage", message); this.lastMessage = message;
setMeta("lastMessageTime", System.currentTimeMillis()); this.lastMessageTime = System.currentTimeMillis();
this.player.sendMessage(message); this.player.sendMessage(message);
} }
} }
@ -260,10 +246,6 @@ public class BukkitPlayer extends PlotPlayer<Player> {
return this.name; return this.name;
} }
@Override public boolean isOnline() {
return !this.offline && this.player.isOnline();
}
@Override public void setCompassTarget(Location location) { @Override public void setCompassTarget(Location location) {
this.player.setCompassTarget( this.player.setCompassTarget(
new org.bukkit.Location(BukkitUtil.getWorld(location.getWorldName()), location.getX(), new org.bukkit.Location(BukkitUtil.getWorld(location.getWorldName()), location.getX(),

View File

@ -27,6 +27,7 @@ package com.plotsquared.bukkit.player;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Singleton; import com.google.inject.Singleton;
import com.plotsquared.core.permissions.PermissionHandler;
import com.plotsquared.core.plot.world.PlotAreaManager; import com.plotsquared.core.plot.world.PlotAreaManager;
import com.plotsquared.core.util.EconHandler; import com.plotsquared.core.util.EconHandler;
import com.plotsquared.core.util.EventDispatcher; import com.plotsquared.core.util.EventDispatcher;
@ -46,21 +47,26 @@ import java.util.UUID;
private final PlotAreaManager plotAreaManager; private final PlotAreaManager plotAreaManager;
private final EventDispatcher eventDispatcher; private final EventDispatcher eventDispatcher;
private final EconHandler econHandler; private final EconHandler econHandler;
private final PermissionHandler permissionHandler;
@Inject public BukkitPlayerManager(@Nonnull final PlotAreaManager plotAreaManager, @Inject public BukkitPlayerManager(@Nonnull final PlotAreaManager plotAreaManager,
@Nonnull final EventDispatcher eventDispatcher, @Nonnull final EventDispatcher eventDispatcher,
@Nullable final EconHandler econHandler) { @Nullable final EconHandler econHandler,
@Nonnull final PermissionHandler permissionHandler) {
this.plotAreaManager = plotAreaManager; this.plotAreaManager = plotAreaManager;
this.eventDispatcher = eventDispatcher; this.eventDispatcher = eventDispatcher;
this.econHandler = econHandler; this.econHandler = econHandler;
this.permissionHandler = permissionHandler;
} }
@Nonnull @Override public BukkitPlayer getPlayer(@Nonnull final Player object) { @Nonnull @Override public BukkitPlayer getPlayer(@Nonnull final Player object) {
if (!object.isOnline()) {
throw new NoSuchPlayerException(object.getUniqueId());
}
try { try {
return getPlayer(object.getUniqueId()); return getPlayer(object.getUniqueId());
} catch (final NoSuchPlayerException exception) { } catch (final NoSuchPlayerException exception) {
return new BukkitPlayer(this.plotAreaManager, this.eventDispatcher, object, return new BukkitPlayer(this.plotAreaManager, this.eventDispatcher, object, false, this.econHandler, this.permissionHandler);
object.isOnline(), false, this.econHandler);
} }
} }
@ -69,18 +75,18 @@ import java.util.UUID;
if (player == null || !player.isOnline()) { if (player == null || !player.isOnline()) {
throw new NoSuchPlayerException(uuid); throw new NoSuchPlayerException(uuid);
} }
return new BukkitPlayer(this.plotAreaManager, this.eventDispatcher, player, this.econHandler); return new BukkitPlayer(this.plotAreaManager, this.eventDispatcher, player, this.econHandler, this.permissionHandler);
} }
@Nullable @Override public BukkitOfflinePlayer getOfflinePlayer(@Nullable final UUID uuid) { @Nullable @Override public BukkitOfflinePlayer getOfflinePlayer(@Nullable final UUID uuid) {
if (uuid == null) { if (uuid == null) {
return null; return null;
} }
return new BukkitOfflinePlayer(Bukkit.getOfflinePlayer(uuid)); return new BukkitOfflinePlayer(Bukkit.getOfflinePlayer(uuid), this.permissionHandler);
} }
@Nonnull @Override public BukkitOfflinePlayer getOfflinePlayer(@Nonnull final String username) { @Nonnull @Override public BukkitOfflinePlayer getOfflinePlayer(@Nonnull final String username) {
return new BukkitOfflinePlayer(Bukkit.getOfflinePlayer(username)); return new BukkitOfflinePlayer(Bukkit.getOfflinePlayer(username), this.permissionHandler);
} }
} }

View File

@ -25,31 +25,21 @@
*/ */
package com.plotsquared.bukkit.util; package com.plotsquared.bukkit.util;
import com.google.inject.Inject;
import com.google.inject.Singleton; import com.google.inject.Singleton;
import com.plotsquared.bukkit.player.BukkitOfflinePlayer; import com.plotsquared.bukkit.player.BukkitOfflinePlayer;
import com.plotsquared.bukkit.player.BukkitPlayer; import com.plotsquared.bukkit.player.BukkitPlayer;
import com.plotsquared.core.player.OfflinePlotPlayer; import com.plotsquared.core.player.OfflinePlotPlayer;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.util.EconHandler; import com.plotsquared.core.util.EconHandler;
import com.plotsquared.core.util.PermHandler;
import net.milkbowl.vault.economy.Economy; import net.milkbowl.vault.economy.Economy;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.plugin.RegisteredServiceProvider; import org.bukkit.plugin.RegisteredServiceProvider;
import javax.annotation.Nullable;
@Singleton public class BukkitEconHandler extends EconHandler { @Singleton public class BukkitEconHandler extends EconHandler {
private Economy econ; private Economy econ;
private final PermHandler permHandler; @Override public boolean init() {
@Inject public BukkitEconHandler(@Nullable final PermHandler permHandler) {
this.permHandler = permHandler;
}
@Override
public boolean init() {
if (this.econ == null) { if (this.econ == null) {
setupEconomy(); setupEconomy();
} }
@ -87,17 +77,6 @@ import javax.annotation.Nullable;
this.econ.depositPlayer(((BukkitOfflinePlayer) player).player, amount); this.econ.depositPlayer(((BukkitOfflinePlayer) player).player, amount);
} }
/**
* @deprecated Use {@link PermHandler#hasPermission(String, String, String)} instead
*/
@Deprecated @Override public boolean hasPermission(String world, String player, String perm) {
if (this.permHandler != null) {
return this.permHandler.hasPermission(world, player, perm);
} else {
return false;
}
}
@Override public double getBalance(PlotPlayer<?> player) { @Override public double getBalance(PlotPlayer<?> player) {
return this.econ.getBalance(player.getName()); return this.econ.getBalance(player.getName());
} }

View File

@ -51,7 +51,6 @@ import io.papermc.lib.PaperLib;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.Biome; import org.bukkit.block.Biome;
import org.bukkit.block.Block; import org.bukkit.block.Block;
@ -113,25 +112,6 @@ public class BukkitUtil extends WorldUtil {
LoggerFactory.getLogger("P2/" + BukkitUtil.class.getSimpleName()); LoggerFactory.getLogger("P2/" + BukkitUtil.class.getSimpleName());
private final Collection<BlockType> tileEntityTypes = new HashSet<>(); private final Collection<BlockType> tileEntityTypes = new HashSet<>();
/**
* Get a {@link PlotPlayer} from an {@link OfflinePlayer}. If the player is
* online, it returns a complete player. If the player is offline, it creates
* a fake player
*
* @param op Offline player
* @return Plot player instance
*/
@Nonnull public static PlotPlayer<Player> adapt(@Nonnull final OfflinePlayer op) {
if (op.isOnline()) {
return adapt(Objects.requireNonNull(op.getPlayer()));
}
final Player player = OfflinePlayerUtil.loadPlayer(op);
player.loadData();
return new BukkitPlayer(PlotSquared.get().getPlotAreaManager(),
PlotSquared.get().getEventDispatcher(), player, true,
PlotSquared.platform().getEconHandler());
}
/** /**
* Turn a Bukkit {@link Player} into a PlotSquared {@link PlotPlayer} * Turn a Bukkit {@link Player} into a PlotSquared {@link PlotPlayer}
* *
@ -213,20 +193,8 @@ public class BukkitUtil extends WorldUtil {
} }
} }
/** @Override public boolean isBlockSame(@Nonnull final BlockState block1,
* Gets the PlotPlayer for a UUID. The PlotPlayer is usually cached and @Nonnull final BlockState block2) {
* will provide useful functions relating to players.
*
* @param uuid the uuid to wrap
* @return a {@code PlotPlayer}
* @see PlotPlayer#wrap(Object)
*/
@Override @Nonnull public PlotPlayer<?> getPlayer(@Nonnull final UUID uuid) {
return PlotPlayer.wrap(Bukkit.getOfflinePlayer(uuid));
}
@Override
public boolean isBlockSame(@Nonnull final BlockState block1, @Nonnull final BlockState block2) {
if (block1.equals(block2)) { if (block1.equals(block2)) {
return true; return true;
} }

View File

@ -1,133 +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.OfflinePlayer;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.UUID;
import static com.plotsquared.core.util.ReflectionUtils.callConstructor;
import static com.plotsquared.core.util.ReflectionUtils.callMethod;
import static com.plotsquared.core.util.ReflectionUtils.getCbClass;
import static com.plotsquared.core.util.ReflectionUtils.getField;
import static com.plotsquared.core.util.ReflectionUtils.getNmsClass;
import static com.plotsquared.core.util.ReflectionUtils.getUtilClass;
import static com.plotsquared.core.util.ReflectionUtils.makeConstructor;
import static com.plotsquared.core.util.ReflectionUtils.makeField;
import static com.plotsquared.core.util.ReflectionUtils.makeMethod;
public class OfflinePlayerUtil {
public static Player loadPlayer(OfflinePlayer player) {
if (player == null) {
return null;
}
if (player instanceof Player) {
return (Player) player;
}
return loadPlayer(player.getUniqueId(), player.getName());
}
private static Player loadPlayer(UUID id, String name) {
Object server = getMinecraftServer();
Object interactManager = newPlayerInteractManager();
Object worldServer = getWorldServer();
Object profile = newGameProfile(id, name);
Class<?> entityPlayerClass = getNmsClass("EntityPlayer");
Constructor entityPlayerConstructor =
makeConstructor(entityPlayerClass, getNmsClass("MinecraftServer"),
getNmsClass("WorldServer"), getUtilClass("com.mojang.authlib.GameProfile"),
getNmsClass("PlayerInteractManager"));
Object entityPlayer =
callConstructor(entityPlayerConstructor, server, worldServer, profile, interactManager);
return (Player) getBukkitEntity(entityPlayer);
}
private static Object newGameProfile(UUID id, String name) {
Class<?> gameProfileClass = getUtilClass("com.mojang.authlib.GameProfile");
if (gameProfileClass == null) { //Before uuids
return name;
}
Constructor gameProfileConstructor =
makeConstructor(gameProfileClass, UUID.class, String.class);
if (gameProfileConstructor == null) { //Version has string constructor
gameProfileConstructor = makeConstructor(gameProfileClass, String.class, String.class);
return callConstructor(gameProfileConstructor, id.toString(), name);
} else { //Version has uuid constructor
return callConstructor(gameProfileConstructor, id, name);
}
}
private static Object newPlayerInteractManager() {
Object worldServer = getWorldServer();
Class<?> playerInteractClass = getNmsClass("PlayerInteractManager");
Class<?> worldClass = getNmsClass("World");
Constructor<?> c = makeConstructor(playerInteractClass, worldClass);
if (c == null) {
c = makeConstructor(playerInteractClass, getNmsClass("WorldServer"));
}
return callConstructor(c, worldServer);
}
public static Object getWorldServerNew() {
Object server = getMinecraftServer();
Class<?> minecraftServerClass = getNmsClass("MinecraftServer");
Class<?> dimensionManager = getNmsClass("DimensionManager");
Object overworld = getField(makeField(dimensionManager, "OVERWORLD"), null);
Method getWorldServer =
makeMethod(minecraftServerClass, "getWorldServer", dimensionManager);
return callMethod(getWorldServer, server, overworld);
}
private static Object getWorldServer() {
Object server = getMinecraftServer();
Class<?> minecraftServerClass = getNmsClass("MinecraftServer");
Method getWorldServer = makeMethod(minecraftServerClass, "getWorldServer", int.class);
Object o;
try {
o = callMethod(getWorldServer, server, 0);
} catch (final RuntimeException e) {
o = getWorldServerNew();
}
return o;
}
//NMS Utils
private static Object getMinecraftServer() {
return callMethod(makeMethod(getCbClass("CraftServer"), "getServer"), Bukkit.getServer());
}
private static Entity getBukkitEntity(Object o) {
Method getBukkitEntity = makeMethod(o.getClass(), "getBukkitEntity");
return callMethod(getBukkitEntity, o);
}
}

View File

@ -20,6 +20,8 @@ dependencies {
compile("com.google.inject:guice:4.2.3") compile("com.google.inject:guice:4.2.3")
compile("com.google.inject.extensions:guice-assistedinject:4.2.3") compile("com.google.inject.extensions:guice-assistedinject:4.2.3")
compile group: 'com.google.code.findbugs', name: 'annotations', version: '3.0.1' compile group: 'com.google.code.findbugs', name: 'annotations', version: '3.0.1'
compile group: 'javax.inject', name: 'javax.inject', version: '1'
compile group: 'aopalliance', name: 'aopalliance', version: '1.0'
// logging // logging
implementation("org.apache.logging.log4j:log4j-slf4j-impl:2.8.1") implementation("org.apache.logging.log4j:log4j-slf4j-impl:2.8.1")
} }

View File

@ -36,6 +36,18 @@
<version>3.0.1</version> <version>3.0.1</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
<scope>compile</scope>
</dependency>
<dependency> <dependency>
<groupId>org.projectlombok</groupId> <groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId> <artifactId>lombok</artifactId>

View File

@ -39,6 +39,8 @@ import com.plotsquared.core.util.SchematicHandler;
import com.plotsquared.core.util.query.PlotQuery; import com.plotsquared.core.util.query.PlotQuery;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collections; import java.util.Collections;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
@ -178,10 +180,9 @@ import java.util.UUID;
* *
* @param uuid the uuid of the player to wrap * @param uuid the uuid of the player to wrap
* @return a {@code PlotPlayer} * @return a {@code PlotPlayer}
* @see PlotPlayer#wrap(Object)
*/ */
public PlotPlayer wrapPlayer(UUID uuid) { @Nullable public PlotPlayer<?> wrapPlayer(@Nonnull final UUID uuid) {
return PlotPlayer.wrap(uuid); return PlotSquared.platform().getPlayerManager().getPlayerIfExists(uuid);
} }
/** /**
@ -189,10 +190,9 @@ import java.util.UUID;
* *
* @param player the player to wrap * @param player the player to wrap
* @return a {@code PlotPlayer} * @return a {@code PlotPlayer}
* @see PlotPlayer#wrap(Object)
*/ */
public PlotPlayer wrapPlayer(String player) { @Nullable public PlotPlayer<?> wrapPlayer(@Nonnull final String player) {
return PlotPlayer.wrap(player); return PlotSquared.platform().getPlayerManager().getPlayerIfExists(player);
} }
/** /**

View File

@ -27,12 +27,14 @@ package com.plotsquared.core;
import com.google.inject.Injector; import com.google.inject.Injector;
import com.google.inject.Key; import com.google.inject.Key;
import com.google.inject.TypeLiteral;
import com.plotsquared.core.backup.BackupManager; import com.plotsquared.core.backup.BackupManager;
import com.plotsquared.core.generator.GeneratorWrapper; import com.plotsquared.core.generator.GeneratorWrapper;
import com.plotsquared.core.generator.HybridUtils; import com.plotsquared.core.generator.HybridUtils;
import com.plotsquared.core.generator.IndependentPlotGenerator; import com.plotsquared.core.generator.IndependentPlotGenerator;
import com.plotsquared.core.inject.annotations.DefaultGenerator; import com.plotsquared.core.inject.annotations.DefaultGenerator;
import com.plotsquared.core.location.World; import com.plotsquared.core.location.World;
import com.plotsquared.core.permissions.PermissionHandler;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.queue.GlobalBlockQueue; import com.plotsquared.core.queue.GlobalBlockQueue;
import com.plotsquared.core.util.ChatManager; import com.plotsquared.core.util.ChatManager;
@ -79,14 +81,6 @@ public interface PlotPlatform<P> extends ILogger {
*/ */
File getWorldContainer(); File getWorldContainer();
/**
* Wraps a player into a PlotPlayer object.
*
* @param player The player to convert to a PlotPlayer
* @return A PlotPlayer
*/
@Nullable PlotPlayer<P> wrapPlayer(Object player);
/** /**
* Completely shuts down the plugin. * Completely shuts down the plugin.
*/ */
@ -185,7 +179,7 @@ public interface PlotPlatform<P> extends ILogger {
* @return Player manager * @return Player manager
*/ */
@Nonnull default PlayerManager<? extends PlotPlayer<P>, ? extends P> getPlayerManager() { @Nonnull default PlayerManager<? extends PlotPlayer<P>, ? extends P> getPlayerManager() {
return getInjector().getInstance(PlayerManager.class); return getInjector().getInstance(Key.get(new TypeLiteral<PlayerManager<? extends PlotPlayer<P>, ? extends P>>() {}));
} }
/** /**
@ -266,4 +260,13 @@ public interface PlotPlatform<P> extends ILogger {
return getInjector().getInstance(ChunkManager.class); return getInjector().getInstance(ChunkManager.class);
} }
/**
* Get the {@link PermissionHandler} implementation for the platform
*
* @return Permission handler
*/
@Nonnull default PermissionHandler getPermissionHandler() {
return getInjector().getInstance(PermissionHandler.class);
}
} }

View File

@ -79,9 +79,12 @@ import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.UUID;
@CommandDeclaration(command = "area", @CommandDeclaration(command = "area",
permission = "plots.area", permission = "plots.area",
@ -102,6 +105,8 @@ public class Area extends SubCommand {
private final RegionManager regionManager; private final RegionManager regionManager;
private final GlobalBlockQueue blockQueue; private final GlobalBlockQueue blockQueue;
private final Map<UUID, Map<String, Object>> metaData = new HashMap<>();
@Inject public Area(@Nonnull final PlotAreaManager plotAreaManager, @Inject public Area(@Nonnull final PlotAreaManager plotAreaManager,
@WorldConfig @Nonnull final YamlConfiguration worldConfiguration, @WorldConfig @Nonnull final YamlConfiguration worldConfiguration,
@WorldFile @Nonnull final File worldFile, @WorldFile @Nonnull final File worldFile,
@ -282,14 +287,16 @@ public class Area extends SubCommand {
case 2: case 2:
switch (args[1].toLowerCase()) { switch (args[1].toLowerCase()) {
case "pos1": { // Set position 1 case "pos1": { // Set position 1
HybridPlotWorld area = player.getMeta("area_create_area"); HybridPlotWorld area = (HybridPlotWorld) metaData.computeIfAbsent(player.getUUID(), missingUUID -> new HashMap<>())
.get("area_create_area");
if (area == null) { if (area == null) {
Captions.COMMAND_SYNTAX.send(player, Captions.COMMAND_SYNTAX.send(player,
"/plot area create [world[:id]] [<modifier>=<value>]..."); "/plot area create [world[:id]] [<modifier>=<value>]...");
return false; return false;
} }
Location location = player.getLocation(); Location location = player.getLocation();
player.setMeta("area_pos1", location); metaData.computeIfAbsent(player.getUUID(), missingUUID -> new HashMap<>())
.put("area_pos1", location);
Captions.SET_ATTRIBUTE.send(player, "area_pos1", Captions.SET_ATTRIBUTE.send(player, "area_pos1",
location.getX() + "," + location.getZ()); location.getX() + "," + location.getZ());
MainUtil.sendMessage(player, MainUtil.sendMessage(player,
@ -298,14 +305,15 @@ public class Area extends SubCommand {
return true; return true;
} }
case "pos2": // Set position 2 and finish creation for type=2 (partial) case "pos2": // Set position 2 and finish creation for type=2 (partial)
final HybridPlotWorld area = player.getMeta("area_create_area"); final HybridPlotWorld area = (HybridPlotWorld) metaData
.computeIfAbsent(player.getUUID(), missingUUID -> new HashMap<>()).get("area_create_area");
if (area == null) { if (area == null) {
Captions.COMMAND_SYNTAX.send(player, Captions.COMMAND_SYNTAX.send(player,
"/plot area create [world[:id]] [<modifier>=<value>]..."); "/plot area create [world[:id]] [<modifier>=<value>]...");
return false; return false;
} }
Location pos1 = player.getLocation(); Location pos1 = player.getLocation();
Location pos2 = player.getMeta("area_pos1"); Location pos2 = (Location) metaData.computeIfAbsent(player.getUUID(), missingUUID -> new HashMap<>()).get("area_pos1");
int dx = Math.abs(pos1.getX() - pos2.getX()); int dx = Math.abs(pos1.getX() - pos2.getX());
int dz = Math.abs(pos1.getZ() - pos2.getZ()); int dz = Math.abs(pos1.getZ() - pos2.getZ());
int numX = Math.max(1, int numX = Math.max(1,
@ -521,7 +529,7 @@ public class Area extends SubCommand {
player.teleport(this.worldUtil.getSpawn(pa.getWorldName()), player.teleport(this.worldUtil.getSpawn(pa.getWorldName()),
TeleportCause.COMMAND); TeleportCause.COMMAND);
} }
player.setMeta("area_create_area", pa); metaData.computeIfAbsent(player.getUUID(), missingUUID -> new HashMap<>()).put("area_create_area", pa);
MainUtil.sendMessage(player, MainUtil.sendMessage(player,
"$1Go to the first corner and use: $2 " + getCommandString() "$1Go to the first corner and use: $2 " + getCommandString()
+ " create pos1"); + " create pos1");

View File

@ -26,7 +26,6 @@
package com.plotsquared.core.command; package com.plotsquared.core.command;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.primitives.Ints;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.plotsquared.core.PlotSquared; import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.CaptionUtility; import com.plotsquared.core.configuration.CaptionUtility;
@ -37,6 +36,9 @@ import com.plotsquared.core.events.PlayerAutoPlotEvent;
import com.plotsquared.core.events.PlotAutoMergeEvent; import com.plotsquared.core.events.PlotAutoMergeEvent;
import com.plotsquared.core.events.Result; import com.plotsquared.core.events.Result;
import com.plotsquared.core.events.TeleportCause; import com.plotsquared.core.events.TeleportCause;
import com.plotsquared.core.player.MetaDataAccess;
import com.plotsquared.core.player.PlayerMetaDataKeys;
import com.plotsquared.core.permissions.PermissionHandler;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea; import com.plotsquared.core.plot.PlotArea;
@ -91,8 +93,10 @@ public class Auto extends SubCommand {
} }
int diff = allowedPlots - currentPlots; int diff = allowedPlots - currentPlots;
if (diff - sizeX * sizeZ < 0) { if (diff - sizeX * sizeZ < 0) {
if (player.hasPersistentMeta("grantedPlots")) { try (final MetaDataAccess<Integer> metaDataAccess = player.accessPersistentMetaData(
int grantedPlots = Ints.fromByteArray(player.getPersistentMeta("grantedPlots")); PlayerMetaDataKeys.PERSISTENT_GRANTED_PLOTS)) {
if (metaDataAccess.isPresent()) {
int grantedPlots = metaDataAccess.get().orElse(0);
if (diff < 0 && grantedPlots < sizeX * sizeZ) { if (diff < 0 && grantedPlots < sizeX * sizeZ) {
MainUtil.sendMessage(player, Captions.CANT_CLAIM_MORE_PLOTS); MainUtil.sendMessage(player, Captions.CANT_CLAIM_MORE_PLOTS);
return false; return false;
@ -102,18 +106,18 @@ public class Auto extends SubCommand {
} else { } else {
int left = grantedPlots + diff < 0 ? 0 : diff - sizeX * sizeZ; int left = grantedPlots + diff < 0 ? 0 : diff - sizeX * sizeZ;
if (left == 0) { if (left == 0) {
player.removePersistentMeta("grantedPlots"); metaDataAccess.remove();
} else { } else {
player.setPersistentMeta("grantedPlots", Ints.toByteArray(left)); metaDataAccess.set(left);
} }
MainUtil.sendMessage(player, Captions.REMOVED_GRANTED_PLOT, MainUtil.sendMessage(player, Captions.REMOVED_GRANTED_PLOT, "" + (grantedPlots - left), "" + left);
"" + (grantedPlots - left), "" + left);
} }
} else { } else {
MainUtil.sendMessage(player, Captions.CANT_CLAIM_MORE_PLOTS); MainUtil.sendMessage(player, Captions.CANT_CLAIM_MORE_PLOTS);
return false; return false;
} }
} }
}
return true; return true;
} }
@ -146,7 +150,10 @@ public class Auto extends SubCommand {
*/ */
public static void autoClaimSafe(final PlotPlayer<?> player, final PlotArea area, PlotId start, public static void autoClaimSafe(final PlotPlayer<?> player, final PlotArea area, PlotId start,
final String schematic) { final String schematic) {
player.setMeta(Auto.class.getName(), true); try (final MetaDataAccess<Boolean> metaDataAccess =
player.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_AUTO)) {
metaDataAccess.set(true);
}
autoClaimFromDatabase(player, area, start, new RunnableVal<Plot>() { autoClaimFromDatabase(player, area, start, new RunnableVal<Plot>() {
@Override public void run(final Plot plot) { @Override public void run(final Plot plot) {
try { try {
@ -175,9 +182,11 @@ public class Auto extends SubCommand {
@Override public boolean onCommand(final PlotPlayer<?> player, String[] args) { @Override public boolean onCommand(final PlotPlayer<?> player, String[] args) {
PlotArea plotarea = player.getApplicablePlotArea(); PlotArea plotarea = player.getApplicablePlotArea();
if (plotarea == null) { if (plotarea == null) {
if (this.econHandler != null) { final PermissionHandler permissionHandler = PlotSquared.platform().getPermissionHandler();
for (PlotArea area : this.plotAreaManager.getAllPlotAreas()) { if (permissionHandler.hasCapability(
if (this.econHandler.hasPermission(area.getWorldName(), player.getName(), "plots.auto")) { PermissionHandler.PermissionHandlerCapability.PER_WORLD_PERMISSIONS)) {
for (final PlotArea area : this.plotAreaManager.getAllPlotAreas()) {
if (player.hasPermission(area.getWorldName(), "plots.auto")) {
if (plotarea != null) { if (plotarea != null) {
plotarea = null; plotarea = null;
break; break;
@ -250,10 +259,13 @@ public class Auto extends SubCommand {
return false; return false;
} }
final int allowed_plots = player.getAllowedPlots(); final int allowed_plots = player.getAllowedPlots();
if (!force && (player.getMeta(Auto.class.getName(), false) || !checkAllowedPlots(player, try (final MetaDataAccess<Boolean> metaDataAccess =
player.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_AUTO)) {
if (!force && (metaDataAccess.get().orElse(false) || !checkAllowedPlots(player,
plotarea, allowed_plots, size_x, size_z))) { plotarea, allowed_plots, size_x, size_z))) {
return false; return false;
} }
}
if (schematic != null && !schematic.isEmpty()) { if (schematic != null && !schematic.isEmpty()) {
if (!plotarea.hasSchematic(schematic)) { if (!plotarea.hasSchematic(schematic)) {

View File

@ -93,7 +93,7 @@ public class Buy extends Command {
this.econHandler.depositMoney(PlotSquared.platform().getPlayerManager().getOfflinePlayer(plot.getOwnerAbs()), price); this.econHandler.depositMoney(PlotSquared.platform().getPlayerManager().getOfflinePlayer(plot.getOwnerAbs()), price);
PlotPlayer owner = PlotSquared.platform().getPlayerManager().getPlayerIfExists(plot.getOwnerAbs()); PlotPlayer<?> owner = PlotSquared.platform().getPlayerManager().getPlayerIfExists(plot.getOwnerAbs());
if (owner != null) { if (owner != null) {
Captions.PLOT_SOLD.send(owner, plot.getId(), player.getName(), price); Captions.PLOT_SOLD.send(owner, plot.getId(), player.getName(), price);
} }

View File

@ -25,7 +25,6 @@
*/ */
package com.plotsquared.core.command; package com.plotsquared.core.command;
import com.google.common.primitives.Ints;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.plotsquared.core.configuration.CaptionUtility; import com.plotsquared.core.configuration.CaptionUtility;
import com.plotsquared.core.configuration.Captions; import com.plotsquared.core.configuration.Captions;
@ -36,6 +35,8 @@ import com.plotsquared.core.events.PlotMergeEvent;
import com.plotsquared.core.events.Result; import com.plotsquared.core.events.Result;
import com.plotsquared.core.location.Direction; import com.plotsquared.core.location.Direction;
import com.plotsquared.core.location.Location; import com.plotsquared.core.location.Location;
import com.plotsquared.core.player.MetaDataAccess;
import com.plotsquared.core.player.PlayerMetaDataKeys;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea; import com.plotsquared.core.plot.PlotArea;
@ -85,32 +86,34 @@ public class Claim extends SubCommand {
int currentPlots = Settings.Limit.GLOBAL ? int currentPlots = Settings.Limit.GLOBAL ?
player.getPlotCount() : player.getPlotCount() :
player.getPlotCount(location.getWorldName()); player.getPlotCount(location.getWorldName());
final PlotArea area = plot.getArea();
try (final MetaDataAccess<Integer> metaDataAccess = player.accessPersistentMetaData(PlayerMetaDataKeys.PERSISTENT_GRANTED_PLOTS)) {
int grants = 0; int grants = 0;
if (currentPlots >= player.getAllowedPlots() && !force) { if (currentPlots >= player.getAllowedPlots() && !force) {
if (player.hasPersistentMeta("grantedPlots")) { if (metaDataAccess.isPresent()) {
grants = Ints.fromByteArray(player.getPersistentMeta("grantedPlots")); grants = metaDataAccess.get().orElse(0);
if (grants <= 0) { if (grants <= 0) {
player.removePersistentMeta("grantedPlots"); metaDataAccess.remove();
return sendMessage(player, Captions.CANT_CLAIM_MORE_PLOTS); return sendMessage(player, Captions.CANT_CLAIM_MORE_PLOTS);
} }
} else { } else {
return sendMessage(player, Captions.CANT_CLAIM_MORE_PLOTS); return sendMessage(player, Captions.CANT_CLAIM_MORE_PLOTS);
} }
} }
if (!plot.canClaim(player)) { if (!plot.canClaim(player)) {
return sendMessage(player, Captions.PLOT_IS_CLAIMED); return sendMessage(player, Captions.PLOT_IS_CLAIMED);
} }
final PlotArea area = plot.getArea();
if (schematic != null && !schematic.isEmpty()) { if (schematic != null && !schematic.isEmpty()) {
if (area.isSchematicClaimSpecify()) { if (area.isSchematicClaimSpecify()) {
if (!area.hasSchematic(schematic)) { if (!area.hasSchematic(schematic)) {
return sendMessage(player, Captions.SCHEMATIC_INVALID, return sendMessage(player, Captions.SCHEMATIC_INVALID, "non-existent: " + schematic);
"non-existent: " + schematic);
} }
if (!Permissions.hasPermission(player, CaptionUtility if (!Permissions.hasPermission(player, CaptionUtility.format(player, Captions.PERMISSION_CLAIM_SCHEMATIC.getTranslated(),
.format(player, Captions.PERMISSION_CLAIM_SCHEMATIC.getTranslated(), schematic)) schematic)) && !Permissions.hasPermission(player, Captions.PERMISSION_ADMIN_COMMAND_SCHEMATIC)
&& !Permissions && !force) {
.hasPermission(player, Captions.PERMISSION_ADMIN_COMMAND_SCHEMATIC) && !force) {
return sendMessage(player, Captions.NO_SCHEMATIC_PERMISSION, schematic); return sendMessage(player, Captions.NO_SCHEMATIC_PERMISSION, schematic);
} }
} }
@ -128,12 +131,13 @@ public class Claim extends SubCommand {
} }
if (grants > 0) { if (grants > 0) {
if (grants == 1) { if (grants == 1) {
player.removePersistentMeta("grantedPlots"); metaDataAccess.remove();
} else { } else {
player.setPersistentMeta("grantedPlots", Ints.toByteArray(grants - 1)); metaDataAccess.set(grants - 1);
} }
sendMessage(player, Captions.REMOVED_GRANTED_PLOT, "1", (grants - 1)); sendMessage(player, Captions.REMOVED_GRANTED_PLOT, "1", (grants - 1));
} }
}
int border = area.getBorder(); int border = area.getBorder();
if (border != Integer.MAX_VALUE && plot.getDistanceFromOrigin() > border && !force) { if (border != Integer.MAX_VALUE && plot.getDistanceFromOrigin() > border && !force) {
return !sendMessage(player, Captions.BORDER); return !sendMessage(player, Captions.BORDER);

View File

@ -26,19 +26,29 @@
package com.plotsquared.core.command; package com.plotsquared.core.command;
import com.plotsquared.core.configuration.Captions; import com.plotsquared.core.configuration.Captions;
import com.plotsquared.core.player.MetaDataAccess;
import com.plotsquared.core.player.PlayerMetaDataKeys;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.task.TaskManager; import com.plotsquared.core.util.task.TaskManager;
import com.plotsquared.core.util.task.TaskTime; import com.plotsquared.core.util.task.TaskTime;
import javax.annotation.Nullable;
public class CmdConfirm { public class CmdConfirm {
public static CmdInstance getPending(PlotPlayer<?> player) { @Nullable public static CmdInstance getPending(PlotPlayer<?> player) {
return player.getMeta("cmdConfirm"); try (final MetaDataAccess<CmdInstance> metaDataAccess = player.accessTemporaryMetaData(
PlayerMetaDataKeys.TEMPORARY_CONFIRM)) {
return metaDataAccess.get().orElse(null);
}
} }
public static void removePending(PlotPlayer<?> player) { public static void removePending(PlotPlayer<?> player) {
player.deleteMeta("cmdConfirm"); try (final MetaDataAccess<CmdInstance> metaDataAccess = player.accessTemporaryMetaData(
PlayerMetaDataKeys.TEMPORARY_CONFIRM)) {
metaDataAccess.remove();
}
} }
public static void addPending(final PlotPlayer<?> player, String commandStr, public static void addPending(final PlotPlayer<?> player, String commandStr,
@ -49,7 +59,10 @@ public class CmdConfirm {
} }
TaskManager.runTaskLater(() -> { TaskManager.runTaskLater(() -> {
CmdInstance cmd = new CmdInstance(runnable); CmdInstance cmd = new CmdInstance(runnable);
player.setMeta("cmdConfirm", cmd); try (final MetaDataAccess<CmdInstance> metaDataAccess = player.accessTemporaryMetaData(
PlayerMetaDataKeys.TEMPORARY_CONFIRM)) {
metaDataAccess.set(cmd);
}
}, TaskTime.ticks(1L)); }, TaskTime.ticks(1L));
} }
} }

View File

@ -35,6 +35,7 @@ import com.plotsquared.core.util.StringComparison;
import com.plotsquared.core.util.StringMan; import com.plotsquared.core.util.StringMan;
import com.plotsquared.core.util.task.RunnableVal2; import com.plotsquared.core.util.task.RunnableVal2;
import com.plotsquared.core.util.task.RunnableVal3; import com.plotsquared.core.util.task.RunnableVal3;
import com.plotsquared.core.permissions.PermissionHolder;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@ -158,7 +159,7 @@ public abstract class Command {
return this.allCommands; return this.allCommands;
} }
public boolean hasConfirmation(CommandCaller player) { public boolean hasConfirmation(PermissionHolder player) {
return this.confirmation && !player.hasPermission(getPermission() + ".confirm.bypass"); return this.confirmation && !player.hasPermission(getPermission() + ".confirm.bypass");
} }

View File

@ -34,14 +34,6 @@ public interface CommandCaller {
*/ */
void sendMessage(String message); void sendMessage(String message);
/**
* Check the player's permissions. <i>Will be cached if permission caching is enabled.</i>
*
* @param permission the name of the permission
*/
boolean hasPermission(String permission);
boolean isPermissionSet(String permission);
RequiredType getSuperCaller(); RequiredType getSuperCaller();
} }

View File

@ -409,46 +409,6 @@ public class DebugExec extends SubCommand {
} }
}, "/plot debugexec list-scripts", "List of scripts"); }, "/plot debugexec list-scripts", "List of scripts");
return true; return true;
case "allcmd":
if (args.length < 3) {
Captions.COMMAND_SYNTAX
.send(player, "/plot debugexec allcmd <condition> <command>");
return false;
}
long start = System.currentTimeMillis();
Command cmd = MainCommand.getInstance().getCommand(args[3]);
String[] params = Arrays.copyOfRange(args, 4, args.length);
if ("true".equals(args[1])) {
Location location = player.getMeta(PlotPlayer.META_LOCATION);
Plot plot = player.getMeta(PlotPlayer.META_LAST_PLOT);
for (Plot current : PlotSquared.get().getBasePlots()) {
player.setMeta(PlotPlayer.META_LOCATION, current.getBottomAbs());
player.setMeta(PlotPlayer.META_LAST_PLOT, current);
cmd.execute(player, params, null, null);
}
if (location == null) {
player.deleteMeta(PlotPlayer.META_LOCATION);
} else {
player.setMeta(PlotPlayer.META_LOCATION, location);
}
if (plot == null) {
player.deleteMeta(PlotPlayer.META_LAST_PLOT);
} else {
player.setMeta(PlotPlayer.META_LAST_PLOT, plot);
}
player.sendMessage("&c> " + (System.currentTimeMillis() - start));
return true;
}
init();
this.scope.put("_2", params);
this.scope.put("_3", cmd);
script =
"_1=PS.getBasePlots().iterator();while(_1.hasNext()){plot=_1.next();if("
+ args[1]
+ "){PlotPlayer.setMeta(\"location\",plot.getBottomAbs());PlotPlayer.setMeta(\"lastplot\",plot);_3.onCommand"
+ "(PlotPlayer,_2)}}";
break;
case "all": case "all":
if (args.length < 3) { if (args.length < 3) {
Captions.COMMAND_SYNTAX Captions.COMMAND_SYNTAX

View File

@ -30,6 +30,8 @@ import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.CaptionUtility; import com.plotsquared.core.configuration.CaptionUtility;
import com.plotsquared.core.configuration.Captions; import com.plotsquared.core.configuration.Captions;
import com.plotsquared.core.database.DBFunc; import com.plotsquared.core.database.DBFunc;
import com.plotsquared.core.player.MetaDataAccess;
import com.plotsquared.core.player.PlayerMetaDataKeys;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.Permissions; import com.plotsquared.core.util.Permissions;
@ -42,7 +44,6 @@ import java.util.Map;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import java.util.function.Consumer;
@CommandDeclaration(command = "grant", @CommandDeclaration(command = "grant",
category = CommandCategory.CLAIMING, category = CommandCategory.CLAIMING,
@ -80,7 +81,20 @@ public class Grant extends Command {
MainUtil.sendMessage(player, Captions.INVALID_PLAYER); MainUtil.sendMessage(player, Captions.INVALID_PLAYER);
} else { } else {
final UUID uuid = uuids.toArray(new UUID[0])[0]; final UUID uuid = uuids.toArray(new UUID[0])[0];
final Consumer<byte[]> result = array -> { PlotPlayer<?> pp = PlotSquared.platform().getPlayerManager().getPlayerIfExists(uuid);
if (pp != null) {
try (final MetaDataAccess<Integer> access = pp.accessPersistentMetaData(
PlayerMetaDataKeys.PERSISTENT_GRANTED_PLOTS)) {
if (args[0].equalsIgnoreCase("check")) {
Captions.GRANTED_PLOTS.send(player, access.get().orElse(0));
} else {
access.set(access.get().orElse(0) + 1);
}
}
} else {
DBFunc.getPersistentMeta(uuid, new RunnableVal<Map<String, byte[]>>() {
@Override public void run(Map<String, byte[]> value) {
final byte[] array = value.get("grantedPlots");
if (arg0.equals("check")) { // check if (arg0.equals("check")) { // check
int granted; int granted;
if (array == null) { if (array == null) {
@ -99,23 +113,9 @@ public class Grant extends Command {
boolean replace = array != null; boolean replace = array != null;
String key = "grantedPlots"; String key = "grantedPlots";
byte[] rawData = Ints.toByteArray(amount); byte[] rawData = Ints.toByteArray(amount);
PlotPlayer online = PlotSquared.platform().getPlayerManager().getPlayerIfExists(uuid);
if (online != null) {
online.setPersistentMeta(key, rawData);
} else {
DBFunc.addPersistentMeta(uuid, key, rawData, replace); DBFunc.addPersistentMeta(uuid, key, rawData, replace);
} }
} }
};
PlotPlayer<?> pp = PlotSquared.platform().getPlayerManager().getPlayerIfExists(uuid);
if (pp != null) {
result.accept(player.getPersistentMeta("grantedPlots"));
} else {
DBFunc.getPersistentMeta(uuid, new RunnableVal<Map<String, byte[]>>() {
@Override public void run(Map<String, byte[]> value) {
result.accept(value.get("grantedPlots"));
}
}); });
} }
} }

View File

@ -25,7 +25,9 @@
*/ */
package com.plotsquared.core.command; package com.plotsquared.core.command;
import com.google.inject.TypeLiteral;
import com.plotsquared.core.configuration.Captions; import com.plotsquared.core.configuration.Captions;
import com.plotsquared.core.player.MetaDataAccess;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.comment.CommentInbox; import com.plotsquared.core.plot.comment.CommentInbox;
@ -34,6 +36,7 @@ import com.plotsquared.core.plot.comment.PlotComment;
import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.StringMan; import com.plotsquared.core.util.StringMan;
import com.plotsquared.core.util.task.RunnableVal; import com.plotsquared.core.util.task.RunnableVal;
import com.plotsquared.core.player.MetaDataKey;
import java.util.List; import java.util.List;
@ -140,7 +143,10 @@ public class Inbox extends SubCommand {
StringMan.join(CommentManager.inboxes.keySet(), ", ")); StringMan.join(CommentManager.inboxes.keySet(), ", "));
return false; return false;
} }
player.setMeta("inbox:" + inbox.toString(), System.currentTimeMillis()); final MetaDataKey<Long> metaDataKey = MetaDataKey.of(String.format("inbox:%s", inbox.toString()), new TypeLiteral<Long>() {});
try (final MetaDataAccess<Long> metaDataAccess = player.accessTemporaryMetaData(metaDataKey)) {
metaDataAccess.set(System.currentTimeMillis());
}
final int page; final int page;
if (args.length > 1) { if (args.length > 1) {
switch (args[1].toLowerCase()) { switch (args[1].toLowerCase()) {

View File

@ -28,6 +28,8 @@ package com.plotsquared.core.command;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.plotsquared.core.configuration.Captions; import com.plotsquared.core.configuration.Captions;
import com.plotsquared.core.configuration.Settings; import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.player.MetaDataAccess;
import com.plotsquared.core.player.PlayerMetaDataKeys;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea; import com.plotsquared.core.plot.PlotArea;
@ -43,6 +45,7 @@ import javax.annotation.Nonnull;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.util.Collections;
import java.util.List; import java.util.List;
@CommandDeclaration(command = "load", @CommandDeclaration(command = "load",
@ -86,9 +89,11 @@ public class Load extends SubCommand {
return false; return false;
} }
try (final MetaDataAccess<List<String>> metaDataAccess =
player.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_SCHEMATICS)) {
if (args.length != 0) { if (args.length != 0) {
if (args.length == 1) { if (args.length == 1) {
List<String> schematics = player.getMeta("plot_schematics"); List<String> schematics = metaDataAccess.get().orElse(null);
if (schematics == null) { if (schematics == null) {
// No schematics found: // No schematics found:
MainUtil.sendMessage(player, Captions.LOAD_NULL); MainUtil.sendMessage(player, Captions.LOAD_NULL);
@ -122,8 +127,8 @@ public class Load extends SubCommand {
return; return;
} }
PlotArea area = plot.getArea(); PlotArea area = plot.getArea();
this.schematicHandler.paste(taskSchematic, plot, 0, area.getMinBuildHeight(), 0, false, this.schematicHandler
new RunnableVal<Boolean>() { .paste(taskSchematic, plot, 0, area.getMinBuildHeight(), 0, false, new RunnableVal<Boolean>() {
@Override public void run(Boolean value) { @Override public void run(Boolean value) {
plot.removeRunning(); plot.removeRunning();
if (value) { if (value) {
@ -143,7 +148,7 @@ public class Load extends SubCommand {
// list schematics // list schematics
List<String> schematics = player.getMeta("plot_schematics"); List<String> schematics = metaDataAccess.get().orElse(null);
if (schematics == null) { if (schematics == null) {
plot.addRunning(); plot.addRunning();
TaskManager.runTaskAsync(() -> { TaskManager.runTaskAsync(() -> {
@ -153,17 +158,20 @@ public class Load extends SubCommand {
MainUtil.sendMessage(player, Captions.LOAD_FAILED); MainUtil.sendMessage(player, Captions.LOAD_FAILED);
return; return;
} }
player.setMeta("plot_schematics", schematics1); metaDataAccess.set(schematics1);
displaySaves(player); displaySaves(player);
}); });
} else { } else {
displaySaves(player); displaySaves(player);
} }
}
return true; return true;
} }
public void displaySaves(PlotPlayer<?> player) { public void displaySaves(PlotPlayer<?> player) {
List<String> schematics = player.getMeta("plot_schematics"); try (final MetaDataAccess<List<String>> metaDataAccess =
player.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_SCHEMATICS)) {
List<String> schematics = metaDataAccess.get().orElse(Collections.emptyList());
for (int i = 0; i < Math.min(schematics.size(), 32); i++) { for (int i = 0; i < Math.min(schematics.size(), 32); i++) {
try { try {
String schematic = schematics.get(i).split("\\.")[0]; String schematic = schematics.get(i).split("\\.")[0];
@ -171,8 +179,7 @@ public class Load extends SubCommand {
if (split.length < 5) { if (split.length < 5) {
continue; continue;
} }
String time = String time = secToTime((System.currentTimeMillis() / 1000) - Long.parseLong(split[0]));
secToTime((System.currentTimeMillis() / 1000) - Long.parseLong(split[0]));
String world = split[1]; String world = split[1];
PlotId id = PlotId.fromString(split[2] + ';' + split[3]); PlotId id = PlotId.fromString(split[2] + ';' + split[3]);
String size = split[4]; String size = split[4];
@ -186,6 +193,7 @@ public class Load extends SubCommand {
} }
MainUtil.sendMessage(player, Captions.LOAD_LIST); MainUtil.sendMessage(player, Captions.LOAD_LIST);
} }
}
public String secToTime(long time) { public String secToTime(long time) {
StringBuilder toreturn = new StringBuilder(); StringBuilder toreturn = new StringBuilder();

View File

@ -31,6 +31,8 @@ import com.plotsquared.core.configuration.Captions;
import com.plotsquared.core.configuration.Settings; import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.location.Location; import com.plotsquared.core.location.Location;
import com.plotsquared.core.player.ConsolePlayer; import com.plotsquared.core.player.ConsolePlayer;
import com.plotsquared.core.player.MetaDataAccess;
import com.plotsquared.core.player.PlayerMetaDataKeys;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea; import com.plotsquared.core.plot.PlotArea;
@ -230,8 +232,6 @@ public class MainCommand extends Command {
public CompletableFuture<Boolean> execute(final PlotPlayer<?> player, String[] args, public CompletableFuture<Boolean> execute(final PlotPlayer<?> player, String[] args,
RunnableVal3<Command, Runnable, Runnable> confirm, RunnableVal3<Command, Runnable, Runnable> confirm,
RunnableVal2<Command, CommandResult> whenDone) { RunnableVal2<Command, CommandResult> whenDone) {
// Clear perm caching //
player.deleteMeta("perm");
// Optional command scope // // Optional command scope //
Location location = null; Location location = null;
Plot plot = null; Plot plot = null;
@ -246,12 +246,17 @@ public class MainCommand extends Command {
Location newLoc = newPlot.getCenterSynchronous(); Location newLoc = newPlot.getCenterSynchronous();
if (player.canTeleport(newLoc)) { if (player.canTeleport(newLoc)) {
// Save meta // Save meta
location = player.getMeta(PlotPlayer.META_LOCATION); try (final MetaDataAccess<Location> locationMetaDataAccess
plot = player.getMeta(PlotPlayer.META_LAST_PLOT); = player.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_LOCATION)) {
location = locationMetaDataAccess.get().orElse(null);
locationMetaDataAccess.set(newLoc);
}
try (final MetaDataAccess<Plot> plotMetaDataAccess
= player.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_LAST_PLOT)) {
plot = plotMetaDataAccess.get().orElse(null);
plotMetaDataAccess.set(newPlot);
}
tp = true; tp = true;
// Set loc
player.setMeta(PlotPlayer.META_LOCATION, newLoc);
player.setMeta(PlotPlayer.META_LAST_PLOT, newPlot);
} else { } else {
Captions.BORDER.send(player); Captions.BORDER.send(player);
} }
@ -304,15 +309,21 @@ public class MainCommand extends Command {
} }
// Reset command scope // // Reset command scope //
if (tp && !(player instanceof ConsolePlayer)) { if (tp && !(player instanceof ConsolePlayer)) {
try (final MetaDataAccess<Location> locationMetaDataAccess
= player.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_LOCATION)) {
if (location == null) { if (location == null) {
player.deleteMeta(PlotPlayer.META_LOCATION); locationMetaDataAccess.remove();
} else { } else {
player.setMeta(PlotPlayer.META_LOCATION, location); locationMetaDataAccess.set(location);
} }
}
try (final MetaDataAccess<Plot> plotMetaDataAccess
= player.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_LAST_PLOT)) {
if (plot == null) { if (plot == null) {
player.deleteMeta(PlotPlayer.META_LAST_PLOT); plotMetaDataAccess.remove();
} else { } else {
player.setMeta(PlotPlayer.META_LAST_PLOT, plot); plotMetaDataAccess.set(plot);
}
} }
} }
return CompletableFuture.completedFuture(true); return CompletableFuture.completedFuture(true);

View File

@ -28,6 +28,8 @@ package com.plotsquared.core.command;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.plotsquared.core.configuration.Captions; import com.plotsquared.core.configuration.Captions;
import com.plotsquared.core.location.Location; import com.plotsquared.core.location.Location;
import com.plotsquared.core.player.MetaDataAccess;
import com.plotsquared.core.player.PlayerMetaDataKeys;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotId; import com.plotsquared.core.plot.PlotId;
@ -104,9 +106,9 @@ public class Save extends SubCommand {
return; return;
} }
MainUtil.sendMessage(player, Captions.SAVE_SUCCESS); MainUtil.sendMessage(player, Captions.SAVE_SUCCESS);
List<String> schematics = player.getMeta("plot_schematics"); try (final MetaDataAccess<List<String>> schematicAccess =
if (schematics != null) { player.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_SCHEMATICS)) {
schematics.add(file + ".schem"); schematicAccess.get().ifPresent(schematics -> schematics.add(file + ".schem"));
} }
} }
}); });

View File

@ -29,6 +29,8 @@ import com.google.inject.Inject;
import com.plotsquared.core.PlotSquared; import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.Captions; import com.plotsquared.core.configuration.Captions;
import com.plotsquared.core.generator.GeneratorWrapper; import com.plotsquared.core.generator.GeneratorWrapper;
import com.plotsquared.core.player.MetaDataAccess;
import com.plotsquared.core.player.PlayerMetaDataKeys;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.setup.SetupProcess; import com.plotsquared.core.setup.SetupProcess;
import com.plotsquared.core.setup.SetupStep; import com.plotsquared.core.setup.SetupStep;
@ -72,14 +74,16 @@ public class Setup extends SubCommand {
} }
@Override public boolean onCommand(PlotPlayer<?> player, String[] args) { @Override public boolean onCommand(PlotPlayer<?> player, String[] args) {
SetupProcess process = player.getMeta("setup"); try (final MetaDataAccess<SetupProcess> metaDataAccess =
player.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_SETUP)) {
SetupProcess process = metaDataAccess.get().orElse(null);
if (process == null) { if (process == null) {
if (args.length > 0) { if (args.length > 0) {
MainUtil.sendMessage(player, Captions.SETUP_NOT_STARTED); MainUtil.sendMessage(player, Captions.SETUP_NOT_STARTED);
return true; return true;
} }
process = new SetupProcess(); process = new SetupProcess();
player.setMeta("setup", process); metaDataAccess.set(process);
this.setupUtils.updateGenerators(); this.setupUtils.updateGenerators();
SetupStep step = process.getCurrentStep(); SetupStep step = process.getCurrentStep();
step.announce(player); step.announce(player);
@ -91,7 +95,7 @@ public class Setup extends SubCommand {
process.back(); process.back();
process.getCurrentStep().announce(player); process.getCurrentStep().announce(player);
} else if ("cancel".equalsIgnoreCase(args[0])) { } else if ("cancel".equalsIgnoreCase(args[0])) {
player.deleteMeta("setup"); metaDataAccess.remove();
MainUtil.sendMessage(player, Captions.SETUP_CANCELLED); MainUtil.sendMessage(player, Captions.SETUP_CANCELLED);
} else { } else {
process.handleInput(player, args[0]); process.handleInput(player, args[0]);
@ -103,11 +107,15 @@ public class Setup extends SubCommand {
process.getCurrentStep().announce(player); process.getCurrentStep().announce(player);
} }
return true; return true;
}
} }
@Override public Collection<Command> tab(PlotPlayer player, String[] args, boolean space) { @Override public Collection<Command> tab(PlotPlayer player, String[] args, boolean space) {
SetupProcess process = (SetupProcess) player.getMeta("setup"); // TODO use generics -> auto cast SetupProcess process;
try (final MetaDataAccess<SetupProcess> metaDataAccess =
player.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_SETUP)) {
process = metaDataAccess.get().orElse(null);
}
if (process == null) { if (process == null) {
return Collections.emptyList(); return Collections.emptyList();
} }

View File

@ -26,12 +26,14 @@
package com.plotsquared.core.listener; package com.plotsquared.core.listener;
import com.plotsquared.core.PlotSquared; import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.collection.ByteArrayUtilities;
import com.plotsquared.core.configuration.Captions; import com.plotsquared.core.configuration.Captions;
import com.plotsquared.core.configuration.Settings; import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.events.PlotFlagRemoveEvent; import com.plotsquared.core.events.PlotFlagRemoveEvent;
import com.plotsquared.core.events.Result; import com.plotsquared.core.events.Result;
import com.plotsquared.core.location.Location; import com.plotsquared.core.location.Location;
import com.plotsquared.core.player.MetaDataAccess;
import com.plotsquared.core.player.MetaDataKey;
import com.plotsquared.core.player.PlayerMetaDataKeys;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea; import com.plotsquared.core.plot.PlotArea;
@ -71,6 +73,7 @@ import javax.annotation.Nullable;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.UUID; import java.util.UUID;
public class PlotListener { public class PlotListener {
@ -94,7 +97,7 @@ public class PlotListener {
++value.count; ++value.count;
if (value.count == value.interval) { if (value.count == value.interval) {
value.count = 0; value.count = 0;
PlotPlayer<?> player = PlotPlayer.wrap(entry.getKey()); final PlotPlayer<?> player = PlotSquared.platform().getPlayerManager().getPlayerIfExists(entry.getKey());
if (player == null) { if (player == null) {
iterator.remove(); iterator.remove();
continue; continue;
@ -114,7 +117,7 @@ public class PlotListener {
++value.count; ++value.count;
if (value.count == value.interval) { if (value.count == value.interval) {
value.count = 0; value.count = 0;
PlotPlayer<?> player = PlotSquared.platform().getWorldUtil().getPlayer(entry.getKey()); final PlotPlayer<?> player = PlotSquared.platform().getPlayerManager().getPlayerIfExists(entry.getKey());
if (player == null) { if (player == null) {
iterator.remove(); iterator.remove();
continue; continue;
@ -134,14 +137,16 @@ public class PlotListener {
.hasPermission(player, "plots.admin.entry.denied")) { .hasPermission(player, "plots.admin.entry.denied")) {
return false; return false;
} }
Plot last = player.getMeta(PlotPlayer.META_LAST_PLOT); try (final MetaDataAccess<Plot> lastPlot = player.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_LAST_PLOT)) {
Plot last = lastPlot.get().orElse(null);
if ((last != null) && !last.getId().equals(plot.getId())) { if ((last != null) && !last.getId().equals(plot.getId())) {
plotExit(player, last); plotExit(player, last);
} }
if (ExpireManager.IMP != null) { if (ExpireManager.IMP != null) {
ExpireManager.IMP.handleEntry(player, plot); ExpireManager.IMP.handleEntry(player, plot);
} }
player.setMeta(PlotPlayer.META_LAST_PLOT, plot); lastPlot.set(plot);
}
this.eventDispatcher.callEntry(player, plot); this.eventDispatcher.callEntry(player, plot);
if (plot.hasOwner()) { if (plot.hasOwner()) {
// This will inherit values from PlotArea // This will inherit values from PlotArea
@ -177,8 +182,9 @@ public class PlotListener {
boolean flight = player.getFlight(); boolean flight = player.getFlight();
GameMode gamemode = player.getGameMode(); GameMode gamemode = player.getGameMode();
if (flight != (gamemode == GameModes.CREATIVE || gamemode == GameModes.SPECTATOR)) { if (flight != (gamemode == GameModes.CREATIVE || gamemode == GameModes.SPECTATOR)) {
player.setPersistentMeta("flight", try (final MetaDataAccess<Boolean> metaDataAccess = player.accessPersistentMetaData(PlayerMetaDataKeys.PERSISTENT_FLIGHT)) {
ByteArrayUtilities.booleanToBytes(player.getFlight())); metaDataAccess.set(player.getFlight());
}
} }
player.setFlight(flyStatus == FlyFlag.FlyStatus.ENABLED); player.setFlight(flyStatus == FlyFlag.FlyStatus.ENABLED);
} }
@ -227,39 +233,47 @@ public class PlotListener {
player.setWeather(plot.getFlag(WeatherFlag.class)); player.setWeather(plot.getFlag(WeatherFlag.class));
ItemType musicFlag = plot.getFlag(MusicFlag.class); ItemType musicFlag = plot.getFlag(MusicFlag.class);
try (final MetaDataAccess<Location> musicMeta =
player.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_MUSIC)) {
if (musicFlag != null) { if (musicFlag != null) {
final String rawId = musicFlag.getId(); final String rawId = musicFlag.getId();
if (rawId.contains("disc") || musicFlag == ItemTypes.AIR) { if (rawId.contains("disc") || musicFlag == ItemTypes.AIR) {
Location location = player.getLocation(); Location location = player.getLocation();
Location lastLocation = player.getMeta("music"); Location lastLocation = musicMeta.get().orElse(null);
if (lastLocation != null) { if (lastLocation != null) {
player.playMusic(lastLocation, musicFlag); player.playMusic(lastLocation, musicFlag);
if (musicFlag == ItemTypes.AIR) { if (musicFlag == ItemTypes.AIR) {
player.deleteMeta("music"); musicMeta.remove();
} }
} }
if (musicFlag != ItemTypes.AIR) { if (musicFlag != ItemTypes.AIR) {
try { try {
player.setMeta("music", location); musicMeta.set(location);
player.playMusic(location, musicFlag); player.playMusic(location, musicFlag);
} catch (Exception ignored) { } catch (Exception ignored) {
} }
} }
} }
} else { } else {
Location lastLoc = player.getMeta("music"); musicMeta.get().ifPresent(lastLoc -> {
if (lastLoc != null) { musicMeta.remove();
player.deleteMeta("music");
player.playMusic(lastLoc, ItemTypes.AIR); player.playMusic(lastLoc, ItemTypes.AIR);
});
} }
} }
CommentManager.sendTitle(player, plot); CommentManager.sendTitle(player, plot);
if (titles && !player.getAttribute("disabletitles")) { if (titles && !player.getAttribute("disabletitles")) {
if (!Captions.TITLE_ENTERED_PLOT.getTranslated().isEmpty() if (!Captions.TITLE_ENTERED_PLOT.getTranslated().isEmpty()
|| !Captions.TITLE_ENTERED_PLOT_SUB.getTranslated().isEmpty()) { || !Captions.TITLE_ENTERED_PLOT_SUB.getTranslated().isEmpty()) {
TaskManager.runTaskLaterAsync(() -> { TaskManager.runTaskLaterAsync(() -> {
Plot lastPlot = player.getMeta(PlotPlayer.META_LAST_PLOT); Plot lastPlot = null;
try (final MetaDataAccess<Plot> lastPlotAccess =
player.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_LAST_PLOT)) {
lastPlot = lastPlotAccess.get().orElse(null);
}
if ((lastPlot != null) && plot.getId().equals(lastPlot.getId())) { if ((lastPlot != null) && plot.getId().equals(lastPlot.getId())) {
Map<String, String> replacements = new HashMap<>(); Map<String, String> replacements = new HashMap<>();
replacements.put("%x%", String.valueOf(lastPlot.getId().getX())); replacements.put("%x%", String.valueOf(lastPlot.getId().getX()));
@ -296,21 +310,25 @@ public class PlotListener {
} }
public boolean plotExit(final PlotPlayer<?> player, Plot plot) { public boolean plotExit(final PlotPlayer<?> player, Plot plot) {
Object previous = player.deleteMeta(PlotPlayer.META_LAST_PLOT); try (final MetaDataAccess<Plot> lastPlot = player.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_LAST_PLOT)) {
final Plot previous = lastPlot.remove();
this.eventDispatcher.callLeave(player, plot); this.eventDispatcher.callLeave(player, plot);
if (plot.hasOwner()) { if (plot.hasOwner()) {
PlotArea pw = plot.getArea(); PlotArea pw = plot.getArea();
if (pw == null) { if (pw == null) {
return true; return true;
} }
try (final MetaDataAccess<Boolean> kickAccess =
player.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_KICK)) {
if (plot.getFlag(DenyExitFlag.class) && !Permissions if (plot.getFlag(DenyExitFlag.class) && !Permissions
.hasPermission(player, Captions.PERMISSION_ADMIN_EXIT_DENIED) && !player .hasPermission(player, Captions.PERMISSION_ADMIN_EXIT_DENIED) &&
.getMeta("kick", false)) { !kickAccess.get().orElse(false)) {
if (previous != null) { if (previous != null) {
player.setMeta(PlotPlayer.META_LAST_PLOT, previous); lastPlot.set(previous);
} }
return false; return false;
} }
}
if (!plot.getFlag(GamemodeFlag.class).equals(GamemodeFlag.DEFAULT) || !plot if (!plot.getFlag(GamemodeFlag.class).equals(GamemodeFlag.DEFAULT) || !plot
.getFlag(GuestGamemodeFlag.class).equals(GamemodeFlag.DEFAULT)) { .getFlag(GuestGamemodeFlag.class).equals(GamemodeFlag.DEFAULT)) {
if (player.getGameMode() != pw.getGameMode()) { if (player.getGameMode() != pw.getGameMode()) {
@ -346,10 +364,11 @@ public class PlotListener {
final FlyFlag.FlyStatus flyStatus = plot.getFlag(FlyFlag.class); final FlyFlag.FlyStatus flyStatus = plot.getFlag(FlyFlag.class);
if (flyStatus != FlyFlag.FlyStatus.DEFAULT) { if (flyStatus != FlyFlag.FlyStatus.DEFAULT) {
if (player.hasPersistentMeta("flight")) { try (final MetaDataAccess<Boolean> metaDataAccess = player.accessPersistentMetaData(PlayerMetaDataKeys.PERSISTENT_FLIGHT)) {
player.setFlight( final Optional<Boolean> value = metaDataAccess.get();
ByteArrayUtilities.bytesToBoolean(player.getPersistentMeta("flight"))); if (value.isPresent()) {
player.removePersistentMeta("flight"); player.setFlight(value.get());
metaDataAccess.remove();
} else { } else {
GameMode gameMode = player.getGameMode(); GameMode gameMode = player.getGameMode();
if (gameMode == GameModes.SURVIVAL || gameMode == GameModes.ADVENTURE) { if (gameMode == GameModes.SURVIVAL || gameMode == GameModes.ADVENTURE) {
@ -359,6 +378,7 @@ public class PlotListener {
} }
} }
} }
}
if (plot.getFlag(TimeFlag.class) != TimeFlag.TIME_DISABLED.getValue().longValue()) { if (plot.getFlag(TimeFlag.class) != TimeFlag.TIME_DISABLED.getValue().longValue()) {
player.setTime(Long.MAX_VALUE); player.setTime(Long.MAX_VALUE);
@ -369,15 +389,18 @@ public class PlotListener {
player.setWeather(PlotWeather.RESET); player.setWeather(PlotWeather.RESET);
} }
Location lastLoc = player.getMeta("music"); try (final MetaDataAccess<Location> musicAccess =
if (lastLoc != null) { player.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_MUSIC)) {
player.deleteMeta("music"); musicAccess.get().ifPresent(lastLoc -> {
musicAccess.remove();
player.playMusic(lastLoc, ItemTypes.AIR); player.playMusic(lastLoc, ItemTypes.AIR);
});
} }
feedRunnable.remove(player.getUUID()); feedRunnable.remove(player.getUUID());
healRunnable.remove(player.getUUID()); healRunnable.remove(player.getUUID());
} }
}
return true; return true;
} }

View File

@ -26,6 +26,7 @@
package com.plotsquared.core.listener; package com.plotsquared.core.listener;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.Captions; import com.plotsquared.core.configuration.Captions;
import com.plotsquared.core.configuration.Settings; import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
@ -72,7 +73,7 @@ public class WESubscriber {
Actor actor = event.getActor(); Actor actor = event.getActor();
if (actor != null && actor.isPlayer()) { if (actor != null && actor.isPlayer()) {
String name = actor.getName(); String name = actor.getName();
PlotPlayer plotPlayer = PlotPlayer.wrap(name); final PlotPlayer<?> plotPlayer = PlotSquared.platform().getPlayerManager().getPlayerIfExists(name);
Set<CuboidRegion> mask; Set<CuboidRegion> mask;
if (plotPlayer == null) { if (plotPlayer == null) {
Player player = (Player) actor; Player player = (Player) actor;

View File

@ -0,0 +1,39 @@
/*
* _____ _ _ _____ _
* | __ \| | | | / ____| | |
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
* | |
* |_|
* 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.permissions;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public enum ConsolePermissionProfile implements PermissionProfile {
INSTANCE;
@Override public boolean hasPermission(@Nullable final String world,
@Nonnull final String permission) {
return true;
}
}

View File

@ -23,15 +23,17 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package com.plotsquared.core.util; package com.plotsquared.core.permissions;
public abstract class PermHandler { import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public abstract boolean init(); public enum NullPermissionProfile implements PermissionProfile {
INSTANCE;
public abstract boolean hasPermission(String world, String player, String perm); @Override public boolean hasPermission(@Nullable final String world,
@Nonnull final String permission) {
public boolean hasPermission(String player, String perm) { return false;
return hasPermission(null, player, perm);
} }
} }

View File

@ -0,0 +1,99 @@
/*
* _____ _ _ _____ _
* | __ \| | | | / ____| | |
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
* | |
* |_|
* 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.permissions;
import com.plotsquared.core.player.OfflinePlotPlayer;
import com.plotsquared.core.player.PlotPlayer;
import javax.annotation.Nonnull;
import java.util.Optional;
import java.util.Set;
/**
* Permission handler
*/
public interface PermissionHandler {
/**
* Initialize the permission handler
*/
void initialize();
/**
* Attempt to construct a permission profile for a plot player
*
* @param playerPlotPlayer Plot player
* @return Permission profile, if one was able to be constructed
*/
@Nonnull Optional<PermissionProfile> getPermissionProfile(
@Nonnull PlotPlayer<?> playerPlotPlayer);
/**
* Attempt to construct a permission profile for an offline plot player
*
* @param offlinePlotPlayer Offline player
* @return Permission profile, if one was able to be constructed
*/
@Nonnull Optional<PermissionProfile> getPermissionProfile(
@Nonnull OfflinePlotPlayer offlinePlotPlayer);
/**
* Get all capabilities that the permission handler has
*
* @return Immutable set of capabilities
*/
@Nonnull Set<PermissionHandlerCapability> getCapabilities();
/**
* Check whether or not the permission handler has a given capability
*
* @param capability Capability
* @return {@code true} if the handler has the capability, else {@code false}
*/
default boolean hasCapability(@Nonnull final PermissionHandlerCapability capability) {
return this.getCapabilities().contains(capability);
}
/**
* Permission handler capabilities
*/
enum PermissionHandlerCapability {
/**
* The ability to check for online (player) permissions
*/
ONLINE_PERMISSIONS,
/**
* The ability to check for offline (player) permissions
*/
OFFLINE_PERMISSIONS,
/**
* Per world permissions
*/
PER_WORLD_PERMISSIONS
}
}

View File

@ -0,0 +1,94 @@
/*
* _____ _ _ _____ _
* | __ \| | | | / ____| | |
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
* | |
* |_|
* 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.permissions;
import com.plotsquared.core.configuration.Captions;
import com.plotsquared.core.configuration.Settings;
import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* Any object which can hold permissions
*/
public interface PermissionHolder {
/**
* Check if the owner of the profile has a given (global) permission
*
* @param permission Permission
* @return {@code true} if the owner has the given permission, else {@code false}
*/
default boolean hasPermission(@Nonnull final String permission) {
return hasPermission(null ,permission);
}
/**
* Check the the highest permission a PlotPlayer has within a specified range.<br>
* - Excessively high values will lag<br>
* - The default range that is checked is {@link Settings.Limit#MAX_PLOTS}<br>
*
* @param stub The permission stub to check e.g. for `plots.plot.#` the stub is `plots.plot`
* @param range The range to check
* @return The highest permission they have within that range
*/
@Nonnegative default int hasPermissionRange(@Nonnull final String stub,
@Nonnegative final int range) {
if (hasPermission(Captions.PERMISSION_ADMIN.getTranslated())) {
return Integer.MAX_VALUE;
}
String[] nodes = stub.split("\\.");
StringBuilder builder = new StringBuilder();
for (int i = 0; i < (nodes.length - 1); i++) {
builder.append(nodes[i]).append(".");
if (!stub.equals(builder + Captions.PERMISSION_STAR.getTranslated())) {
if (hasPermission(builder + Captions.PERMISSION_STAR.getTranslated())) {
return Integer.MAX_VALUE;
}
}
}
if (hasPermission(stub + ".*")) {
return Integer.MAX_VALUE;
}
for (int i = range; i > 0; i--) {
if (hasPermission(stub + "." + i)) {
return i;
}
}
return 0;
}
/**
* Check if the owner of the profile has a given permission
*
* @param world World name
* @param permission Permission
* @return {@code true} if the owner has the given permission, else {@code false}
*/
boolean hasPermission(@Nullable String world, @Nonnull String permission);
}

View File

@ -0,0 +1,55 @@
/*
* _____ _ _ _____ _
* | __ \| | | | / ____| | |
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
* | |
* |_|
* 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.permissions;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* A permission profile that can be used to check for permissions
*/
public interface PermissionProfile {
/**
* Check if the owner of the profile has a given (global) permission
*
* @param permission Permission
* @return {@code true} if the owner has the given permission, else {@code false}
*/
default boolean hasPermission(@Nonnull final String permission) {
return hasPermission(null ,permission);
}
/**
* Check if the owner of the profile has a given permission
*
* @param world World name
* @param permission Permission
* @return {@code true} if the owner has the given permission, else {@code false}
*/
boolean hasPermission(@Nullable final String world, @Nonnull String permission);
}

View File

@ -32,6 +32,8 @@ import com.plotsquared.core.database.DBFunc;
import com.plotsquared.core.events.TeleportCause; import com.plotsquared.core.events.TeleportCause;
import com.plotsquared.core.inject.annotations.ConsoleActor; import com.plotsquared.core.inject.annotations.ConsoleActor;
import com.plotsquared.core.location.Location; import com.plotsquared.core.location.Location;
import com.plotsquared.core.permissions.PermissionHandler;
import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea; import com.plotsquared.core.plot.PlotArea;
import com.plotsquared.core.plot.PlotWeather; import com.plotsquared.core.plot.PlotWeather;
import com.plotsquared.core.plot.world.PlotAreaManager; import com.plotsquared.core.plot.world.PlotAreaManager;
@ -47,6 +49,8 @@ import javax.annotation.Nullable;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.UUID; import java.util.UUID;
public class ConsolePlayer extends PlotPlayer<Actor> { public class ConsolePlayer extends PlotPlayer<Actor> {
@ -59,8 +63,9 @@ public class ConsolePlayer extends PlotPlayer<Actor> {
@Inject private ConsolePlayer(@Nonnull final PlotAreaManager plotAreaManager, @Inject private ConsolePlayer(@Nonnull final PlotAreaManager plotAreaManager,
@Nonnull final EventDispatcher eventDispatcher, @Nonnull final EventDispatcher eventDispatcher,
@ConsoleActor @Nonnull final Actor actor, @ConsoleActor @Nonnull final Actor actor,
@Nullable final EconHandler econHandler) { @Nullable final EconHandler econHandler,
super(plotAreaManager, eventDispatcher, econHandler); @Nonnull final PermissionHandler permissionHandler) {
super(plotAreaManager, eventDispatcher, econHandler, permissionHandler);
this.actor = actor; this.actor = actor;
final PlotArea[] areas = plotAreaManager.getAllPlotAreas(); final PlotArea[] areas = plotAreaManager.getAllPlotAreas();
final PlotArea area; final PlotArea area;
@ -118,15 +123,7 @@ public class ConsolePlayer extends PlotPlayer<Actor> {
} }
@Override public long getLastPlayed() { @Override public long getLastPlayed() {
return 0; return System.currentTimeMillis();
}
@Override public boolean hasPermission(String permission) {
return true;
}
@Override public boolean isPermissionSet(String permission) {
return true;
} }
@Override public void sendMessage(String message) { @Override public void sendMessage(String message) {
@ -134,12 +131,16 @@ public class ConsolePlayer extends PlotPlayer<Actor> {
} }
@Override public void teleport(Location location, TeleportCause cause) { @Override public void teleport(Location location, TeleportCause cause) {
setMeta(META_LAST_PLOT, location.getPlot()); try (final MetaDataAccess<Plot> lastPlot = accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_LAST_PLOT)) {
setMeta(META_LOCATION, location); if (location.getPlot() == null) {
lastPlot.remove();
} else {
lastPlot.set(location.getPlot());
}
}
try (final MetaDataAccess<Location> locationMetaDataAccess = accessPersistentMetaData(PlayerMetaDataKeys.TEMPORARY_LOCATION)) {
locationMetaDataAccess.set(location);
} }
@Override public boolean isOnline() {
return true;
} }
@Override public String getName() { @Override public String getName() {

View File

@ -0,0 +1,129 @@
/*
* _____ _ _ _____ _
* | __ \| | | | / ____| | |
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
* | |
* |_|
* 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.player;
import com.plotsquared.core.synchronization.LockRepository;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Optional;
/**
* Access to player meta data
*
* @param <T> Meta data type
*/
public abstract class MetaDataAccess<T> implements AutoCloseable {
private final PlotPlayer<?> player;
private final MetaDataKey<T> metaDataKey;
private final LockRepository.LockAccess lockAccess;
private boolean closed = false;
MetaDataAccess(@Nonnull final PlotPlayer<?> player, @Nonnull final MetaDataKey<T> metaDataKey,
@Nonnull final LockRepository.LockAccess lockAccess) {
this.player = player;
this.metaDataKey = metaDataKey;
this.lockAccess = lockAccess;
}
/**
* Check if the player has meta data stored with the given key
*
* @return {@code true} if player has meta data with this key, or
* {@code false}
*/
public abstract boolean isPresent();
/**
* Remove the stored value meta data
*
* @return Old value, or {@code null}
*/
@Nullable public abstract T remove();
/**
* Set the meta data value
*
* @param value New value
*/
public abstract void set(@Nonnull final T value);
/**
* Get the stored meta data value
*
* @return Stored value, or {@link Optional#empty()}
*/
@Nonnull public abstract Optional<T> get();
@Override public final void close() {
this.lockAccess.close();
this.closed = true;
}
/**
* Get the owner of the meta data
*
* @return Player
*/
@Nonnull public PlotPlayer<?> getPlayer() {
return this.player;
}
/**
* Get the meta data key
*
* @return Meta data key
*/
@Nonnull public MetaDataKey<T> getMetaDataKey() {
return this.metaDataKey;
}
/**
* Check whether or not the meta data access has been closed.
* After being closed, all attempts to access the meta data
* through the instance, will lead to {@link IllegalAccessException}
* being thrown
*
* @return {@code true} if the access has been closed
*/
public boolean isClosed() {
return this.closed;
}
protected void checkClosed() {
if (this.closed) {
sneakyThrow(new IllegalAccessException("The meta data access instance has been closed"));
}
}
@SuppressWarnings("ALL")
private static <E extends Throwable> void sneakyThrow(final Throwable e) throws E {
throw (E) e;
}
}

View File

@ -0,0 +1,108 @@
/*
* _____ _ _ _____ _
* | __ \| | | | / ____| | |
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
* | |
* |_|
* 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.player;
import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
import com.google.inject.TypeLiteral;
import com.plotsquared.core.synchronization.LockKey;
import javax.annotation.Nonnull;
import java.util.HashMap;
import java.util.Map;
/**
* Key used to access meta data
*
* @param <T> Meta data type
*/
public final class MetaDataKey<T> {
private static final Map<String, MetaDataKey> keyMap = new HashMap<>();
private static final Object keyMetaData = new Object();
private final String key;
private final TypeLiteral<T> type;
private final LockKey lockKey;
private MetaDataKey(@Nonnull final String key, @Nonnull final TypeLiteral<T> type) {
this.key = Preconditions.checkNotNull(key, "Key may not be null");
this.type = Preconditions.checkNotNull(type, "Type may not be null");
this.lockKey = LockKey.of(this.key);
}
/**
* Get a new named lock key
*
* @param key Key name
* @param <T> Type
* @return MetaData key instance
*/
@Nonnull public static <T> MetaDataKey<T> of(@Nonnull final String key, @Nonnull final TypeLiteral<T> type) {
synchronized (keyMetaData) {
return (MetaDataKey<T>)
keyMap.computeIfAbsent(key, missingKey -> new MetaDataKey<>(missingKey, type));
}
}
@Override public String toString() {
return this.key;
}
@Override public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final MetaDataKey lockKey = (MetaDataKey) o;
return Objects.equal(this.key, lockKey.key);
}
@Override public int hashCode() {
return Objects.hashCode(this.key);
}
/**
* Get the {@link LockKey} associated with this key
*
* @return Lock key
*/
@Nonnull public LockKey getLockKey() {
return this.lockKey;
}
/**
* Get the meta data type
*
* @return Meta data type
*/
@Nonnull public TypeLiteral<T> getType() {
return this.type;
}
}

View File

@ -25,9 +25,12 @@
*/ */
package com.plotsquared.core.player; package com.plotsquared.core.player;
import com.plotsquared.core.permissions.PermissionHolder;
import javax.annotation.Nonnegative;
import java.util.UUID; import java.util.UUID;
public interface OfflinePlotPlayer { public interface OfflinePlotPlayer extends PermissionHolder {
/** /**
* Gets the {@code UUID} of this player * Gets the {@code UUID} of this player
@ -40,16 +43,8 @@ public interface OfflinePlotPlayer {
* Gets the time in milliseconds when the player was last seen online. * Gets the time in milliseconds when the player was last seen online.
* *
* @return the time in milliseconds when last online * @return the time in milliseconds when last online
* @deprecated This method may be inconsistent across platforms. The javadoc may be wrong depending on which platform is used.
*/ */
@SuppressWarnings("DeprecatedIsStillUsed") @Deprecated long getLastPlayed(); @Nonnegative long getLastPlayed();
/**
* Checks if this player is online.
*
* @return {@code true} if this player is online
*/
boolean isOnline();
/** /**
* Gets the name of this player. * Gets the name of this player.
@ -57,4 +52,5 @@ public interface OfflinePlotPlayer {
* @return the player name * @return the player name
*/ */
String getName(); String getName();
} }

View File

@ -0,0 +1,66 @@
/*
* _____ _ _ _____ _
* | __ \| | | | / ____| | |
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
* | |
* |_|
* 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.player;
import com.plotsquared.core.synchronization.LockRepository;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Optional;
final class PersistentMetaDataAccess<T> extends MetaDataAccess<T> {
PersistentMetaDataAccess(@Nonnull final PlotPlayer<?> player,
@Nonnull final MetaDataKey<T> metaDataKey,
@Nonnull final LockRepository.LockAccess lockAccess) {
super(player, metaDataKey, lockAccess);
}
@Override public boolean isPresent() {
this.checkClosed();
return this.getPlayer().hasPersistentMeta(getMetaDataKey().toString());
}
@Override @Nullable public T remove() {
this.checkClosed();
final Object old = this.getPlayer().removePersistentMeta(this.getMetaDataKey().toString());
if (old == null) {
return null;
}
return (T) old;
}
@Override public void set(@Nonnull T value) {
this.checkClosed();
this.getPlayer().setPersistentMeta(this.getMetaDataKey(), value);
}
@Nonnull @Override public Optional<T> get() {
this.checkClosed();
return Optional.ofNullable(this.getPlayer().getPersistentMeta(this.getMetaDataKey()));
}
}

View File

@ -0,0 +1,60 @@
/*
* _____ _ _ _____ _
* | __ \| | | | / ____| | |
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
* | |
* |_|
* PlotSquared plot management system for Minecraft
* Copyright (C) 2020 IntellectualSites
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.player;
import com.google.inject.TypeLiteral;
import com.plotsquared.core.command.Auto;
import com.plotsquared.core.command.CmdInstance;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotInventory;
import com.plotsquared.core.setup.SetupProcess;
import java.util.List;
public final class PlayerMetaDataKeys {
//@formatter:off
public static final MetaDataKey<Boolean> PERSISTENT_FLIGHT = MetaDataKey.of("flight", new TypeLiteral<Boolean>() {});
public static final MetaDataKey<Integer> PERSISTENT_GRANTED_PLOTS = MetaDataKey.of("grantedPlots", new TypeLiteral<Integer>() {});
public static final MetaDataKey<Plot> TEMPORARY_LAST_PLOT = MetaDataKey.of("lastplot", new TypeLiteral<Plot>() {});
public static final MetaDataKey<Location> TEMPORARY_MUSIC = MetaDataKey.of("music", new TypeLiteral<Location>() {});
public static final MetaDataKey<Boolean> TEMPORARY_KICK = MetaDataKey.of("kick", new TypeLiteral<Boolean>() {});
public static final MetaDataKey<SetupProcess> TEMPORARY_SETUP = MetaDataKey.of("setup", new TypeLiteral<SetupProcess>() {});
public static final MetaDataKey<PlotInventory> TEMPORARY_INVENTORY = MetaDataKey.of("inventory", new TypeLiteral<PlotInventory>() {});
public static final MetaDataKey<Boolean> TEMPORARY_IGNORE_EXPIRE_TASK = MetaDataKey.of("ignoreExpireTask", new TypeLiteral<Boolean>() {});
public static final MetaDataKey<Plot> TEMPORARY_WORLD_EDIT_REGION_PLOT = MetaDataKey.of("WorldEditRegionPlot", new TypeLiteral<Plot>() {});
public static final MetaDataKey<Boolean> TEMPORARY_AUTO = MetaDataKey.of(Auto.class.getName(), new TypeLiteral<Boolean>() {});
public static final MetaDataKey<List<String>> TEMPORARY_SCHEMATICS = MetaDataKey.of("plot_schematics", new TypeLiteral<List<String>>() {});
public static final MetaDataKey<Location> TEMPORARY_LOCATION = MetaDataKey.of("location", new TypeLiteral<Location>() {});
public static final MetaDataKey<CmdInstance> TEMPORARY_CONFIRM = MetaDataKey.of("cmdConfirm", new TypeLiteral<CmdInstance>() {});
//@formatter:on
private PlayerMetaDataKeys() {
}
}

View File

@ -26,7 +26,9 @@
package com.plotsquared.core.player; package com.plotsquared.core.player;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.primitives.Ints;
import com.plotsquared.core.PlotSquared; import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.collection.ByteArrayUtilities;
import com.plotsquared.core.command.CommandCaller; import com.plotsquared.core.command.CommandCaller;
import com.plotsquared.core.command.RequiredType; import com.plotsquared.core.command.RequiredType;
import com.plotsquared.core.configuration.CaptionUtility; import com.plotsquared.core.configuration.CaptionUtility;
@ -35,6 +37,9 @@ import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.database.DBFunc; import com.plotsquared.core.database.DBFunc;
import com.plotsquared.core.events.TeleportCause; import com.plotsquared.core.events.TeleportCause;
import com.plotsquared.core.location.Location; import com.plotsquared.core.location.Location;
import com.plotsquared.core.permissions.NullPermissionProfile;
import com.plotsquared.core.permissions.PermissionHandler;
import com.plotsquared.core.permissions.PermissionProfile;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea; import com.plotsquared.core.plot.PlotArea;
import com.plotsquared.core.plot.PlotCluster; import com.plotsquared.core.plot.PlotCluster;
@ -45,6 +50,7 @@ import com.plotsquared.core.plot.flag.implementations.DoneFlag;
import com.plotsquared.core.plot.world.PlotAreaManager; import com.plotsquared.core.plot.world.PlotAreaManager;
import com.plotsquared.core.plot.world.SinglePlotArea; import com.plotsquared.core.plot.world.SinglePlotArea;
import com.plotsquared.core.plot.world.SinglePlotAreaManager; import com.plotsquared.core.plot.world.SinglePlotAreaManager;
import com.plotsquared.core.synchronization.LockRepository;
import com.plotsquared.core.util.EconHandler; import com.plotsquared.core.util.EconHandler;
import com.plotsquared.core.util.EventDispatcher; import com.plotsquared.core.util.EventDispatcher;
import com.plotsquared.core.util.Permissions; import com.plotsquared.core.util.Permissions;
@ -54,11 +60,11 @@ import com.plotsquared.core.util.task.TaskManager;
import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.world.gamemode.GameMode; import com.sk89q.worldedit.world.gamemode.GameMode;
import com.sk89q.worldedit.world.item.ItemType; import com.sk89q.worldedit.world.item.ItemType;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@ -78,9 +84,6 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer
private static final Logger logger = LoggerFactory.getLogger("P2/" + PlotPlayer.class.getSimpleName()); private static final Logger logger = LoggerFactory.getLogger("P2/" + PlotPlayer.class.getSimpleName());
public static final String META_LAST_PLOT = "lastplot";
public static final String META_LOCATION = "location";
// Used to track debug mode // Used to track debug mode
private static final Set<PlotPlayer<?>> debugModeEnabled = Collections.synchronizedSet(new HashSet<>()); private static final Set<PlotPlayer<?>> debugModeEnabled = Collections.synchronizedSet(new HashSet<>());
@ -92,14 +95,20 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer
private ConcurrentHashMap<String, Object> meta; private ConcurrentHashMap<String, Object> meta;
private int hash; private int hash;
private final LockRepository lockRepository = new LockRepository();
private final PlotAreaManager plotAreaManager; private final PlotAreaManager plotAreaManager;
private final EventDispatcher eventDispatcher; private final EventDispatcher eventDispatcher;
private final EconHandler econHandler; private final EconHandler econHandler;
private final PermissionProfile permissionProfile;
public PlotPlayer(@Nonnull final PlotAreaManager plotAreaManager, @Nonnull final EventDispatcher eventDispatcher, @Nullable final EconHandler econHandler) { public PlotPlayer(@Nonnull final PlotAreaManager plotAreaManager, @Nonnull final EventDispatcher eventDispatcher, @Nullable final EconHandler econHandler,
@Nonnull final PermissionHandler permissionHandler) {
this.plotAreaManager = plotAreaManager; this.plotAreaManager = plotAreaManager;
this.eventDispatcher = eventDispatcher; this.eventDispatcher = eventDispatcher;
this.econHandler = econHandler; this.econHandler = econHandler;
this.permissionProfile = permissionHandler.getPermissionProfile(this).orElse(
NullPermissionProfile.INSTANCE);
} }
public static <T> PlotPlayer<T> from(@Nonnull final T object) { public static <T> PlotPlayer<T> from(@Nonnull final T object) {
@ -133,18 +142,9 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer
return players; return players;
} }
/** @Override public final boolean hasPermission(@Nullable final String world,
* Efficiently wrap a Player, or OfflinePlayer object to get a PlotPlayer (or fetch if it's already cached)<br> @Nonnull final String permission) {
* - Accepts sponge/bukkit Player (online) return this.permissionProfile.hasPermission(world, permission);
* - Accepts player name (online)
* - Accepts UUID
* - Accepts bukkit OfflinePlayer (offline)
*
* @param player Player object to wrap
* @return Wrapped player
*/
public static PlotPlayer<?> wrap(Object player) {
return PlotSquared.platform().wrapPlayer(player);
} }
public abstract Actor toActor(); public abstract Actor toActor();
@ -157,7 +157,7 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer
* @param key * @param key
* @param value * @param value
*/ */
public void setMeta(String key, Object value) { void setMeta(String key, Object value) {
if (value == null) { if (value == null) {
deleteMeta(key); deleteMeta(key);
} else { } else {
@ -175,14 +175,14 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer
* @param <T> the object type to return * @param <T> the object type to return
* @return the value assigned to the key or null if it does not exist * @return the value assigned to the key or null if it does not exist
*/ */
public <T> T getMeta(String key) { <T> T getMeta(String key) {
if (this.meta != null) { if (this.meta != null) {
return (T) this.meta.get(key); return (T) this.meta.get(key);
} }
return null; return null;
} }
public <T> T getMeta(String key, T defaultValue) { <T> T getMeta(String key, T defaultValue) {
T meta = getMeta(key); T meta = getMeta(key);
if (meta == null) { if (meta == null) {
return defaultValue; return defaultValue;
@ -201,7 +201,7 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer
* *
* @param key * @param key
*/ */
public Object deleteMeta(String key) { Object deleteMeta(String key) {
return this.meta == null ? null : this.meta.remove(key); return this.meta == null ? null : this.meta.remove(key);
} }
@ -220,11 +220,13 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer
* @return the plot the player is standing on or null if standing on a road or not in a {@link PlotArea} * @return the plot the player is standing on or null if standing on a road or not in a {@link PlotArea}
*/ */
public Plot getCurrentPlot() { public Plot getCurrentPlot() {
Plot value = getMeta(PlotPlayer.META_LAST_PLOT); try (final MetaDataAccess<Plot> lastPlotAccess =
if (value == null && !Settings.Enabled_Components.EVENTS) { this.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_LAST_PLOT)) {
return getLocation().getPlot(); if (lastPlotAccess.get().orElse(null) == null && !Settings.Enabled_Components.EVENTS) {
return this.getLocation().getPlot();
}
return lastPlotAccess.get().orElse(null);
} }
return value;
} }
/** /**
@ -246,31 +248,6 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer
return Permissions.hasPermissionRange(this, "plots.cluster", Settings.Limit.MAX_PLOTS); return Permissions.hasPermissionRange(this, "plots.cluster", Settings.Limit.MAX_PLOTS);
} }
public int hasPermissionRange(String stub, int range) {
if (hasPermission(Captions.PERMISSION_ADMIN.getTranslated())) {
return Integer.MAX_VALUE;
}
String[] nodes = stub.split("\\.");
StringBuilder builder = new StringBuilder();
for (int i = 0; i < (nodes.length - 1); i++) {
builder.append(nodes[i]).append(".");
if (!stub.equals(builder + Captions.PERMISSION_STAR.getTranslated())) {
if (hasPermission(builder + Captions.PERMISSION_STAR.getTranslated())) {
return Integer.MAX_VALUE;
}
}
}
if (hasPermission(stub + ".*")) {
return Integer.MAX_VALUE;
}
for (int i = range; i > 0; i--) {
if (hasPermission(stub + "." + i)) {
return i;
}
}
return 0;
}
/** /**
* Get the number of plots this player owns. * Get the number of plots this player owns.
* *
@ -721,18 +698,85 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer
} }
} }
public byte[] getPersistentMeta(String key) { byte[] getPersistentMeta(String key) {
return this.metaMap.get(key); return this.metaMap.get(key);
} }
public void removePersistentMeta(String key) { Object removePersistentMeta(String key) {
this.metaMap.remove(key); final Object old = this.metaMap.remove(key);
if (Settings.Enabled_Components.PERSISTENT_META) { if (Settings.Enabled_Components.PERSISTENT_META) {
DBFunc.removePersistentMeta(getUUID(), key); DBFunc.removePersistentMeta(getUUID(), key);
} }
return old;
} }
public void setPersistentMeta(String key, byte[] value) { /**
* Access keyed persistent meta data for this player. This returns a meta data
* access instance, that MUST be closed. It is meant to be used with try-with-resources,
* like such:
* <pre>{@code
* try (final MetaDataAccess<Integer> access = player.accessPersistentMetaData(PlayerMetaKeys.GRANTS)) {
* int grants = access.get();
* access.set(grants + 1);
* }
* }</pre>
*
* @param key Meta data key
* @param <T> Meta data type
* @return Meta data access. MUST be closed after being used
*/
@Nonnull public <T> MetaDataAccess<T> accessPersistentMetaData(@Nonnull final MetaDataKey<T> key) {
return new PersistentMetaDataAccess<>(this, key, this.lockRepository.lock(key.getLockKey()));
}
/**
* Access keyed temporary meta data for this player. This returns a meta data
* access instance, that MUST be closed. It is meant to be used with try-with-resources,
* like such:
* <pre>{@code
* try (final MetaDataAccess<Integer> access = player.accessTemporaryMetaData(PlayerMetaKeys.GRANTS)) {
* int grants = access.get();
* access.set(grants + 1);
* }
* }</pre>
*
* @param key Meta data key
* @param <T> Meta data type
* @return Meta data access. MUST be closed after being used
*/
@Nonnull public <T> MetaDataAccess<T> accessTemporaryMetaData(@Nonnull final MetaDataKey<T> key) {
return new TemporaryMetaDataAccess<>(this, key, this.lockRepository.lock(key.getLockKey()));
}
<T> void setPersistentMeta(@Nonnull final MetaDataKey<T> key,
@Nonnull final T value) {
final Object rawValue = value;
if (key.getType().getRawType().equals(Integer.class)) {
this.setPersistentMeta(key.toString(), Ints.toByteArray((int) rawValue));
} else if (key.getType().getRawType().equals(Boolean.class)) {
this.setPersistentMeta(key.toString(), ByteArrayUtilities.booleanToBytes((boolean) rawValue));
} else {
throw new IllegalArgumentException(String.format("Unknown meta data type '%s'", key.getType().toString()));
}
}
@Nullable <T> T getPersistentMeta(@Nonnull final MetaDataKey<T> key) {
final byte[] value = this.getPersistentMeta(key.toString());
if (value == null) {
return null;
}
final Object returnValue;
if (key.getType().getRawType().equals(Integer.class)) {
returnValue = Ints.fromByteArray(value);
} else if (key.getType().getRawType().equals(Boolean.class)) {
returnValue = ByteArrayUtilities.bytesToBoolean(value);
} else {
throw new IllegalArgumentException(String.format("Unknown meta data type '%s'", key.getType().toString()));
}
return (T) returnValue;
}
void setPersistentMeta(String key, byte[] value) {
boolean delete = hasPersistentMeta(key); boolean delete = hasPersistentMeta(key);
this.metaMap.put(key, value); this.metaMap.put(key, value);
if (Settings.Enabled_Components.PERSISTENT_META) { if (Settings.Enabled_Components.PERSISTENT_META) {
@ -740,7 +784,7 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer
} }
} }
public boolean hasPersistentMeta(String key) { boolean hasPersistentMeta(String key) {
return this.metaMap.containsKey(key); return this.metaMap.containsKey(key);
} }
@ -784,6 +828,15 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer
} }
} }
/**
* Get this player's {@link LockRepository}
*
* @return Lock repository instance
*/
@Nonnull public LockRepository getLockRepository() {
return this.lockRepository;
}
@FunctionalInterface @FunctionalInterface
public interface PlotPlayerConverter<BaseObject> { public interface PlotPlayerConverter<BaseObject> {
PlotPlayer<?> convert(BaseObject object); PlotPlayer<?> convert(BaseObject object);

View File

@ -0,0 +1,66 @@
/*
* _____ _ _ _____ _
* | __ \| | | | / ____| | |
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
* | |
* |_|
* 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.player;
import com.plotsquared.core.synchronization.LockRepository;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Optional;
final class TemporaryMetaDataAccess<T> extends MetaDataAccess<T> {
TemporaryMetaDataAccess(@Nonnull final PlotPlayer<?> player,
@Nonnull final MetaDataKey<T> metaDataKey,
@Nonnull final LockRepository.LockAccess lockAccess) {
super(player, metaDataKey, lockAccess);
}
@Override public boolean isPresent() {
this.checkClosed();
return this.getPlayer().getMeta(this.getMetaDataKey().toString()) != null;
}
@Override @Nullable public T remove() {
this.checkClosed();
final Object old = getPlayer().deleteMeta(this.getMetaDataKey().toString());
if (old == null) {
return null;
}
return (T) old;
}
@Override public void set(@Nonnull T value) {
this.checkClosed();
this.getPlayer().setMeta(this.getMetaDataKey().toString(), null);
}
@Nonnull @Override public Optional<T> get() {
this.checkClosed();
return Optional.ofNullable(this.getPlayer().getMeta(this.getMetaDataKey().toString()));
}
}

View File

@ -1935,11 +1935,16 @@ public class Plot {
DBFunc.createPlotAndSettings(this, () -> { DBFunc.createPlotAndSettings(this, () -> {
PlotArea plotworld = Plot.this.area; PlotArea plotworld = Plot.this.area;
if (notify && plotworld.isAutoMerge()) { if (notify && plotworld.isAutoMerge()) {
PlotPlayer player = this.worldUtil.getPlayer(uuid); final PlotPlayer<?> player = PlotSquared.platform().getPlayerManager()
.getPlayerIfExists(uuid);
PlotMergeEvent event = this.eventDispatcher PlotMergeEvent event = this.eventDispatcher
.callMerge(this, Direction.ALL, Integer.MAX_VALUE, player); .callMerge(this, Direction.ALL, Integer.MAX_VALUE, player);
if (event.getEventResult() == Result.DENY) { if (event.getEventResult() == Result.DENY) {
if (player != null) {
sendMessage(player, Captions.EVENT_DENIED, "Auto merge on claim"); sendMessage(player, Captions.EVENT_DENIED, "Auto merge on claim");
}
return; return;
} }
Plot.this.autoMerge(event.getDir(), event.getMax(), uuid, true); Plot.this.autoMerge(event.getDir(), event.getMax(), uuid, true);
@ -3095,10 +3100,10 @@ public class Plot {
if (!TaskManager.removeFromTeleportQueue(name)) { if (!TaskManager.removeFromTeleportQueue(name)) {
return; return;
} }
if (player.isOnline()) { try {
MainUtil.sendMessage(player, Captions.TELEPORTED_TO_PLOT); MainUtil.sendMessage(player, Captions.TELEPORTED_TO_PLOT);
player.teleport(location, cause); player.teleport(location, cause);
} } catch (final Exception ignored) {}
}, TaskTime.seconds(Settings.Teleport.DELAY)); }, TaskTime.seconds(Settings.Teleport.DELAY));
resultConsumer.accept(true); resultConsumer.accept(true);
}; };

View File

@ -43,6 +43,8 @@ import com.plotsquared.core.inject.annotations.WorldConfig;
import com.plotsquared.core.location.Direction; import com.plotsquared.core.location.Direction;
import com.plotsquared.core.location.Location; import com.plotsquared.core.location.Location;
import com.plotsquared.core.location.PlotLoc; import com.plotsquared.core.location.PlotLoc;
import com.plotsquared.core.player.MetaDataAccess;
import com.plotsquared.core.player.PlayerMetaDataKeys;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.flag.FlagContainer; import com.plotsquared.core.plot.flag.FlagContainer;
import com.plotsquared.core.plot.flag.FlagParseException; import com.plotsquared.core.plot.flag.FlagParseException;
@ -788,8 +790,11 @@ public abstract class PlotArea {
} }
public boolean addPlot(@Nonnull final Plot plot) { public boolean addPlot(@Nonnull final Plot plot) {
for (PlotPlayer pp : plot.getPlayersInPlot()) { for (final PlotPlayer<?> pp : plot.getPlayersInPlot()) {
pp.setMeta(PlotPlayer.META_LAST_PLOT, plot); try (final MetaDataAccess<Plot> metaDataAccess = pp.accessTemporaryMetaData(
PlayerMetaDataKeys.TEMPORARY_LAST_PLOT)) {
metaDataAccess.set(plot);
}
} }
return this.plots.put(plot.getId(), plot) == null; return this.plots.put(plot.getId(), plot) == null;
} }
@ -827,8 +832,11 @@ public abstract class PlotArea {
public boolean addPlotIfAbsent(@Nonnull final Plot plot) { public boolean addPlotIfAbsent(@Nonnull final Plot plot) {
if (this.plots.putIfAbsent(plot.getId(), plot) == null) { if (this.plots.putIfAbsent(plot.getId(), plot) == null) {
for (PlotPlayer pp : plot.getPlayersInPlot()) { for (PlotPlayer<?> pp : plot.getPlayersInPlot()) {
pp.setMeta(PlotPlayer.META_LAST_PLOT, plot); try (final MetaDataAccess<Plot> metaDataAccess = pp.accessTemporaryMetaData(
PlayerMetaDataKeys.TEMPORARY_LAST_PLOT)) {
metaDataAccess.set(plot);
}
} }
return true; return true;
} }

View File

@ -25,18 +25,19 @@
*/ */
package com.plotsquared.core.plot; package com.plotsquared.core.plot;
import com.plotsquared.core.player.MetaDataAccess;
import com.plotsquared.core.player.PlayerMetaDataKeys;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.util.InventoryUtil; import com.plotsquared.core.util.InventoryUtil;
import javax.annotation.Nonnull;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import javax.annotation.Nonnull;
public class PlotInventory { public class PlotInventory {
private static final Logger logger = LoggerFactory.getLogger("P2/" + PlotInventory.class.getSimpleName()); private static final Logger logger = LoggerFactory.getLogger("P2/" + PlotInventory.class.getSimpleName());
private static final String META_KEY = "inventory";
public final PlotPlayer<?> player; public final PlotPlayer<?> player;
public final int size; public final int size;
private final PlotItemStack[] items; private final PlotItemStack[] items;
@ -58,16 +59,25 @@ public class PlotInventory {
} }
public static PlotInventory getOpenPlotInventory(@Nonnull final PlotPlayer<?> plotPlayer) { public static PlotInventory getOpenPlotInventory(@Nonnull final PlotPlayer<?> plotPlayer) {
return plotPlayer.getMeta(META_KEY, null); try (final MetaDataAccess<PlotInventory> inventoryAccess = plotPlayer.accessTemporaryMetaData(
PlayerMetaDataKeys.TEMPORARY_INVENTORY)) {
return inventoryAccess.get().orElse(null);
}
} }
public static void setPlotInventoryOpen(@Nonnull final PlotPlayer<?> plotPlayer, public static void setPlotInventoryOpen(@Nonnull final PlotPlayer<?> plotPlayer,
@Nonnull final PlotInventory plotInventory) { @Nonnull final PlotInventory plotInventory) {
plotPlayer.setMeta(META_KEY, plotInventory); try (final MetaDataAccess<PlotInventory> inventoryAccess = plotPlayer.accessTemporaryMetaData(
PlayerMetaDataKeys.TEMPORARY_INVENTORY)) {
inventoryAccess.set(plotInventory);
}
} }
public static void removePlotInventoryOpen(@Nonnull final PlotPlayer<?>plotPlayer) { public static void removePlotInventoryOpen(@Nonnull final PlotPlayer<?>plotPlayer) {
plotPlayer.deleteMeta(META_KEY); try (final MetaDataAccess<PlotInventory> inventoryAccess = plotPlayer.accessTemporaryMetaData(
PlayerMetaDataKeys.TEMPORARY_INVENTORY)) {
inventoryAccess.remove();
}
} }
public boolean onClick(int index) { public boolean onClick(int index) {

View File

@ -26,8 +26,11 @@
package com.plotsquared.core.plot.comment; package com.plotsquared.core.plot.comment;
import com.google.common.annotations.Beta; import com.google.common.annotations.Beta;
import com.google.inject.TypeLiteral;
import com.plotsquared.core.configuration.Captions; import com.plotsquared.core.configuration.Captions;
import com.plotsquared.core.configuration.Settings; import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.player.MetaDataAccess;
import com.plotsquared.core.player.MetaDataKey;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.util.task.RunnableVal; import com.plotsquared.core.util.task.RunnableVal;
@ -77,7 +80,10 @@ import java.util.concurrent.atomic.AtomicInteger;
} }
public static long getTimestamp(PlotPlayer<?> player, String inbox) { public static long getTimestamp(PlotPlayer<?> player, String inbox) {
return player.getMeta("inbox:" + inbox, player.getLastPlayed()); final MetaDataKey<Long> inboxKey = MetaDataKey.of(String.format("inbox:%s", inbox), new TypeLiteral<Long>() {});
try (final MetaDataAccess<Long> inboxAccess = player.accessTemporaryMetaData(inboxKey)) {
return inboxAccess.get().orElse(player.getLastPlayed());
}
} }
public static void addInbox(CommentInbox inbox) { public static void addInbox(CommentInbox inbox) {

View File

@ -31,7 +31,9 @@ import com.plotsquared.core.database.DBFunc;
import com.plotsquared.core.events.PlotFlagAddEvent; import com.plotsquared.core.events.PlotFlagAddEvent;
import com.plotsquared.core.events.PlotUnlinkEvent; import com.plotsquared.core.events.PlotUnlinkEvent;
import com.plotsquared.core.events.Result; import com.plotsquared.core.events.Result;
import com.plotsquared.core.player.MetaDataAccess;
import com.plotsquared.core.player.OfflinePlotPlayer; import com.plotsquared.core.player.OfflinePlotPlayer;
import com.plotsquared.core.player.PlayerMetaDataKeys;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea; import com.plotsquared.core.plot.PlotArea;
@ -137,35 +139,32 @@ public class ExpireManager {
} }
} }
public void confirmExpiry(final PlotPlayer pp) { public void confirmExpiry(final PlotPlayer<?> pp) {
if (pp.getMeta("ignoreExpireTask") != null) { try (final MetaDataAccess<Boolean> metaDataAccess = pp.accessTemporaryMetaData(
PlayerMetaDataKeys.TEMPORARY_IGNORE_EXPIRE_TASK)) {
if (metaDataAccess.isPresent()) {
return; return;
} }
if (plotsToDelete != null && !plotsToDelete.isEmpty() && pp if (plotsToDelete != null && !plotsToDelete.isEmpty() && pp.hasPermission("plots.admin.command.autoclear")) {
.hasPermission("plots.admin.command.autoclear")) {
final int num = plotsToDelete.size(); final int num = plotsToDelete.size();
while (!plotsToDelete.isEmpty()) { while (!plotsToDelete.isEmpty()) {
Iterator<Plot> iter = plotsToDelete.iterator(); Iterator<Plot> iter = plotsToDelete.iterator();
final Plot current = iter.next(); final Plot current = iter.next();
if (!isExpired(new ArrayDeque<>(tasks), current).isEmpty()) { if (!isExpired(new ArrayDeque<>(tasks), current).isEmpty()) {
TaskManager.runTask(() -> { TaskManager.runTask(() -> {
pp.setMeta("ignoreExpireTask", true); metaDataAccess.set(true);
current.getCenter(pp::teleport); current.getCenter(pp::teleport);
pp.deleteMeta("ignoreExpireTask"); metaDataAccess.remove();
PlotMessage msg = new PlotMessage() PlotMessage msg = new PlotMessage().text(
.text(num + " " + (num > 1 ? "plots are" : "plot is") + " expired: ") num + " " + (num > 1 ? "plots are" : "plot is") + " expired: ").color("$1").text(current.toString()).color("$2")
.color("$1").text(current.toString()).color("$2")
.command("/plot list expired").tooltip("/plot list expired") .command("/plot list expired").tooltip("/plot list expired")
//.text("\n - ").color("$3").text("Delete all (/plot delete expired)").color("$2").command("/plot delete expired") //.text("\n - ").color("$3").text("Delete all (/plot delete expired)").color("$2").command("/plot delete expired")
.text("\n - ").color("$3").text("Delete this (/plot delete)") .text("\n - ").color("$3").text("Delete this (/plot delete)").color("$2").command("/plot delete").tooltip("/plot delete")
.color("$2").command("/plot delete").tooltip("/plot delete") .text("\n - ").color("$3").text("Remind later (/plot flag set keep 1d)").color("$2")
.text("\n - ").color("$3").text("Remind later (/plot flag set keep 1d)") .command("/plot flag set keep 1d").tooltip("/plot flag set keep 1d")
.color("$2").command("/plot flag set keep 1d").tooltip("/plot flag set keep 1d") .text("\n - ").color("$3").text("Keep this (/plot flag set keep true)").color("$2")
.text("\n - ").color("$3").text("Keep this (/plot flag set keep true)") .command("/plot flag set keep true").tooltip("/plot flag set keep true").text("\n - ").color("$3")
.color("$2").command("/plot flag set keep true") .text("Don't show me this").color("$2").command("/plot toggle clear-confirmation")
.tooltip("/plot flag set keep true").text("\n - ").color("$3")
.text("Don't show me this").color("$2")
.command("/plot toggle clear-confirmation")
.tooltip("/plot toggle clear-confirmation"); .tooltip("/plot toggle clear-confirmation");
msg.send(pp); msg.send(pp);
}); });
@ -177,6 +176,7 @@ public class ExpireManager {
plotsToDelete.clear(); plotsToDelete.clear();
} }
} }
}
public boolean cancelTask() { public boolean cancelTask() {
@ -418,13 +418,13 @@ public class ExpireManager {
} }
} }
for (UUID helper : plot.getTrusted()) { for (UUID helper : plot.getTrusted()) {
PlotPlayer player = PlotSquared.platform().getPlayerManager().getPlayerIfExists(helper); PlotPlayer<?> player = PlotSquared.platform().getPlayerManager().getPlayerIfExists(helper);
if (player != null) { if (player != null) {
MainUtil.sendMessage(player, Captions.PLOT_REMOVED_USER, plot.toString()); MainUtil.sendMessage(player, Captions.PLOT_REMOVED_USER, plot.toString());
} }
} }
for (UUID helper : plot.getMembers()) { for (UUID helper : plot.getMembers()) {
PlotPlayer player = PlotSquared.platform().getPlayerManager().getPlayerIfExists(helper); PlotPlayer<?> player = PlotSquared.platform().getPlayerManager().getPlayerIfExists(helper);
if (player != null) { if (player != null) {
MainUtil.sendMessage(player, Captions.PLOT_REMOVED_USER, plot.toString()); MainUtil.sendMessage(player, Captions.PLOT_REMOVED_USER, plot.toString());
} }

View File

@ -30,6 +30,8 @@ import com.plotsquared.core.configuration.Caption;
import com.plotsquared.core.configuration.Captions; import com.plotsquared.core.configuration.Captions;
import com.plotsquared.core.events.TeleportCause; import com.plotsquared.core.events.TeleportCause;
import com.plotsquared.core.generator.GeneratorWrapper; import com.plotsquared.core.generator.GeneratorWrapper;
import com.plotsquared.core.player.MetaDataAccess;
import com.plotsquared.core.player.PlayerMetaDataKeys;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.PlotArea; import com.plotsquared.core.plot.PlotArea;
import com.plotsquared.core.plot.PlotAreaTerrainType; import com.plotsquared.core.plot.PlotAreaTerrainType;
@ -221,7 +223,10 @@ public enum CommonSetupSteps implements SetupStep {
MainUtil.sendMessage(plotPlayer, Captions.SETUP_WORLD_APPLY_PLOTSQUARED); MainUtil.sendMessage(plotPlayer, Captions.SETUP_WORLD_APPLY_PLOTSQUARED);
} }
builder.worldName(argument); builder.worldName(argument);
plotPlayer.deleteMeta("setup"); try (final MetaDataAccess<SetupProcess> setupAccess = plotPlayer.accessTemporaryMetaData(
PlayerMetaDataKeys.TEMPORARY_SETUP)) {
setupAccess.remove();
}
String world; String world;
if (builder.setupManager() == null) { if (builder.setupManager() == null) {
world = PlotSquared.platform().getInjector().getInstance(SetupUtils.class).setupWorld(builder); world = PlotSquared.platform().getInjector().getInstance(SetupUtils.class).setupWorld(builder);

View File

@ -0,0 +1,92 @@
/*
* _____ _ _ _____ _
* | __ \| | | | / ____| | |
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
* | |
* |_|
* 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.synchronization;
import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
import javax.annotation.Nonnull;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* Key used to access {@link java.util.concurrent.locks.Lock locks}
* from a {@link LockRepository}
*/
public final class LockKey {
private static final Map<String, LockKey> keyMap = new HashMap<>();
private static final Object keyLock = new Object();
private final String key;
private LockKey(@Nonnull final String key) {
this.key = Preconditions.checkNotNull(key, "Key may not be null");
}
/**
* Get a new named lock key
*
* @param key Key name
* @return Lock key instance
*/
@Nonnull public static LockKey of(@Nonnull final String key) {
synchronized (keyLock) {
return keyMap.computeIfAbsent(key, LockKey::new);
}
}
/**
* Get all currently recognized lock keys
*
* @return Currently recognized lock keys
*/
@Nonnull static Collection<LockKey> recognizedKeys() {
return Collections.unmodifiableCollection(keyMap.values());
}
@Override public String toString() {
return "LockKey{" + "key='" + key + '\'' + '}';
}
@Override public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final LockKey lockKey = (LockKey) o;
return Objects.equal(this.key, lockKey.key);
}
@Override public int hashCode() {
return Objects.hashCode(this.key);
}
}

View File

@ -0,0 +1,116 @@
/*
* _____ _ _ _____ _
* | __ \| | | | / ____| | |
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
* | |
* |_|
* 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.synchronization;
import com.google.common.util.concurrent.Striped;
import javax.annotation.Nonnull;
import java.util.concurrent.locks.Lock;
import java.util.function.Consumer;
/**
* A repository for keyed {@link java.util.concurrent.locks.Lock locks}
*/
public final class LockRepository {
private final Striped<Lock> striped;
public LockRepository() {
this.striped = Striped.lock(LockKey.recognizedKeys().size());
}
/**
* Get the lock corresponding to the given lock key
*
* @param key Lock key
* @return Lock
*/
@Nonnull public Lock getLock(@Nonnull final LockKey key) {
return this.striped.get(key);
}
/**
* Consume a lock
*
* @param key Lock key
* @param consumer Lock consumer
*/
public void useLock(@Nonnull final LockKey key, @Nonnull final Consumer<Lock> consumer) {
consumer.accept(this.getLock(key));
}
/**
* Wait for the lock to become available, and run
* the given runnable, then unlock the lock. This is
* a blocking method.
*
* @param key Lock key
* @param runnable Action to run when the lock is available
*/
public void useLock(@Nonnull final LockKey key, @Nonnull final Runnable runnable) {
this.useLock(key, lock -> {
lock.lock();
runnable.run();
lock.unlock();
});
}
/**
* Wait for a lock to be available, lock it and return
* an {@link AutoCloseable} instance that locks the key.
* <p>
* This is meant to be used with try-with-resources, like such:
* <pre>{@code
* try (final LockAccess lockAccess = lockRepository.lock(LockKey.of("your.key"))) {
* // use lock
* }
* }</pre>
*
* @param key Lock key
* @return Lock access. Must be closed.
*/
@Nonnull public LockAccess lock(@Nonnull final LockKey key) {
final Lock lock = this.getLock(key);
lock.lock();
return new LockAccess(lock);
}
public static class LockAccess implements AutoCloseable {
private final Lock lock;
private LockAccess(@Nonnull final Lock lock) {
this.lock = lock;
}
@Override public void close() {
this.lock.unlock();
}
}
}

View File

@ -48,16 +48,4 @@ public abstract class EconHandler {
public abstract void depositMoney(OfflinePlotPlayer player, double amount); public abstract void depositMoney(OfflinePlotPlayer player, double amount);
/**
* @deprecated Use {@link PermHandler#hasPermission(String, String, String)} instead
*/
@Deprecated public abstract boolean hasPermission(String world, String player, String perm);
/**
* @deprecated Use {@link PermHandler#hasPermission(String, String)} instead
*/
@Deprecated public boolean hasPermission(String player, String perm) {
return hasPermission(null, player, perm);
}
} }

View File

@ -25,12 +25,13 @@
*/ */
package com.plotsquared.core.util; package com.plotsquared.core.util;
import com.plotsquared.core.command.CommandCaller; import com.plotsquared.core.configuration.Caption;
import com.plotsquared.core.configuration.Captions; import com.plotsquared.core.configuration.Captions;
import com.plotsquared.core.configuration.Settings; import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.permissions.PermissionHolder;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import java.util.HashMap; import javax.annotation.Nonnull;
/** /**
* The Permissions class handles checking user permissions.<br> * The Permissions class handles checking user permissions.<br>
@ -39,78 +40,28 @@ import java.util.HashMap;
*/ */
public class Permissions { public class Permissions {
public static boolean hasPermission(PlotPlayer player, Captions caption, boolean notify) { public static boolean hasPermission(PlotPlayer<?> player, Captions caption, boolean notify) {
return hasPermission(player, caption.getTranslated(), notify); return hasPermission(player, caption.getTranslated(), notify);
} }
/** /**
* Check if a player has a permission (Captions class helps keep track of permissions). * Check if the owner of the profile has a given (global) permission
* *
* @param player * @param permission Permission
* @param caption * @return {@code true} if the owner has the given permission, else {@code false}
* @return
*/ */
public static boolean hasPermission(PlotPlayer player, Captions caption) { public static boolean hasPermission(@Nonnull final PermissionHolder caller, @Nonnull final Caption permission) {
return hasPermission(player, caption.getTranslated()); return caller.hasPermission(permission.getTranslated());
} }
/** /**
* Check if a {@link PlotPlayer} has a permission. * Check if the owner of the profile has a given (global) permission
* *
* @param player * @param permission Permission
* @param permission * @return {@code true} if the owner has the given permission, else {@code false}
* @return
*/ */
public static boolean hasPermission(PlotPlayer<?> player, String permission) { public static boolean hasPermission(@Nonnull final PermissionHolder caller, @Nonnull final String permission) {
if (!Settings.Enabled_Components.PERMISSION_CACHE) { return caller.hasPermission(permission);
return hasPermission((CommandCaller) player, permission);
}
HashMap<String, Boolean> map = player.getMeta("perm");
if (map != null) {
Boolean result = map.get(permission);
if (result != null) {
return result;
}
} else {
map = new HashMap<>();
player.setMeta("perm", map);
}
boolean result = hasPermission((CommandCaller) player, permission);
map.put(permission, result);
return result;
}
/**
* Check if a {@code CommandCaller} has a permission.
*
* @param caller
* @param permission
* @return
*/
public static boolean hasPermission(CommandCaller caller, String permission) {
if (caller.hasPermission(permission)) {
return true;
} else if (caller.isPermissionSet(permission)) {
return false;
}
if (caller.hasPermission(Captions.PERMISSION_ADMIN.getTranslated())) {
return true;
}
permission = permission.toLowerCase().replaceAll("^[^a-z|0-9|\\.|_|-]", "");
String[] nodes = permission.split("\\.");
StringBuilder n = new StringBuilder();
for (int i = 0; i <= (nodes.length - 1); i++) {
n.append(nodes[i] + ".");
String combined = n + Captions.PERMISSION_STAR.getTranslated();
if (!permission.equals(combined)) {
if (caller.hasPermission(combined)) {
return true;
} else if (caller.isPermissionSet(combined)) {
return false;
}
}
}
return false;
} }
/** /**
@ -121,7 +72,7 @@ public class Permissions {
* @param notify * @param notify
* @return * @return
*/ */
public static boolean hasPermission(PlotPlayer player, String permission, boolean notify) { public static boolean hasPermission(PlotPlayer<?> player, String permission, boolean notify) {
if (!hasPermission(player, permission)) { if (!hasPermission(player, permission)) {
if (notify) { if (notify) {
MainUtil.sendMessage(player, Captions.NO_PERMISSION_EVENT, permission); MainUtil.sendMessage(player, Captions.NO_PERMISSION_EVENT, permission);
@ -131,7 +82,7 @@ public class Permissions {
return true; return true;
} }
public static int hasPermissionRange(PlotPlayer player, Captions perm, int range) { public static int hasPermissionRange(PlotPlayer<?> player, Captions perm, int range) {
return hasPermissionRange(player, perm.getTranslated(), range); return hasPermissionRange(player, perm.getTranslated(), range);
} }
@ -140,12 +91,12 @@ public class Permissions {
* - Excessively high values will lag<br> * - Excessively high values will lag<br>
* - The default range that is checked is {@link Settings.Limit#MAX_PLOTS}<br> * - The default range that is checked is {@link Settings.Limit#MAX_PLOTS}<br>
* *
* @param player * @param player Player to check for
* @param stub The permission stub to check e.g. for `plots.plot.#` the stub is `plots.plot` * @param stub The permission stub to check e.g. for `plots.plot.#` the stub is `plots.plot`
* @param range The range to check * @param range The range to check
* @return The highest permission they have within that range * @return The highest permission they have within that range
*/ */
public static int hasPermissionRange(PlotPlayer player, String stub, int range) { public static int hasPermissionRange(PlotPlayer<?> player, String stub, int range) {
return player.hasPermissionRange(stub, range); return player.hasPermissionRange(stub, range);
} }
} }

View File

@ -239,7 +239,7 @@ public abstract class PlayerManager<P extends PlotPlayer<? extends T>, T> {
/** /**
* Get a plot player from a platform player object. This method requires * Get a plot player from a platform player object. This method requires
* that the caller actually knows that the player exists. * that the caller actually knows that the player exists and is online.
* <p> * <p>
* The method will throw an exception if there is no such * The method will throw an exception if there is no such
* player online. * player online.

View File

@ -28,6 +28,8 @@ package com.plotsquared.core.util;
import com.plotsquared.core.PlotSquared; import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.Settings; import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.location.Location; import com.plotsquared.core.location.Location;
import com.plotsquared.core.player.MetaDataAccess;
import com.plotsquared.core.player.PlayerMetaDataKeys;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea; import com.plotsquared.core.plot.PlotArea;
@ -100,8 +102,10 @@ public class WEManager {
} }
boolean allowMember = player.hasPermission("plots.worldedit.member"); boolean allowMember = player.hasPermission("plots.worldedit.member");
Plot plot = player.getCurrentPlot(); Plot plot = player.getCurrentPlot();
try (final MetaDataAccess<Plot> metaDataAccess =
player.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_WORLD_EDIT_REGION_PLOT)) {
if (plot == null) { if (plot == null) {
plot = player.getMeta("WorldEditRegionPlot"); plot = metaDataAccess.get().orElse(null);
} }
if (plot != null && (!Settings.Done.RESTRICT_BUILDING || !DoneFlag.isDone(plot)) && ( if (plot != null && (!Settings.Done.RESTRICT_BUILDING || !DoneFlag.isDone(plot)) && (
(allowMember && plot.isAdded(uuid)) || (!allowMember && (plot.isOwner(uuid)) || plot (allowMember && plot.isAdded(uuid)) || (!allowMember && (plot.isOwner(uuid)) || plot
@ -112,7 +116,8 @@ public class WEManager {
CuboidRegion copy = new CuboidRegion(pos1, pos2); CuboidRegion copy = new CuboidRegion(pos1, pos2);
regions.add(copy); regions.add(copy);
} }
player.setMeta("WorldEditRegionPlot", plot); metaDataAccess.set(plot);
}
} }
return regions; return regions;
} }

View File

@ -359,14 +359,6 @@ public abstract class WorldUtil {
*/ */
public abstract boolean isBlockSame(@Nonnull BlockState block1, @Nonnull BlockState block2); public abstract boolean isBlockSame(@Nonnull BlockState block1, @Nonnull BlockState block2);
/**
* Get a player object for the player with the given UUID
*
* @param uuid Player UUID
* @return Player object
*/
@Nonnull public abstract PlotPlayer<?> getPlayer(@Nonnull UUID uuid);
/** /**
* Get the player health * Get the player health
* *

View File

@ -30,6 +30,8 @@ import com.plotsquared.core.configuration.Captions;
import com.plotsquared.core.events.PlotMergeEvent; import com.plotsquared.core.events.PlotMergeEvent;
import com.plotsquared.core.events.Result; import com.plotsquared.core.events.Result;
import com.plotsquared.core.location.Direction; import com.plotsquared.core.location.Direction;
import com.plotsquared.core.player.MetaDataAccess;
import com.plotsquared.core.player.PlayerMetaDataKeys;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea; import com.plotsquared.core.plot.PlotArea;
@ -50,7 +52,10 @@ public final class AutoClaimFinishTask implements Callable<Boolean> {
private final EventDispatcher eventDispatcher; private final EventDispatcher eventDispatcher;
@Override public Boolean call() { @Override public Boolean call() {
player.deleteMeta(Auto.class.getName()); try (final MetaDataAccess<Boolean> autoAccess
= player.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_AUTO)) {
autoAccess.remove();
}
if (plot == null) { if (plot == null) {
sendMessage(player, Captions.NO_FREE_PLOTS); sendMessage(player, Captions.NO_FREE_PLOTS);
return false; return false;