Merge remote-tracking branch 'origin/v6' into feature/v6/json

# Conflicts:
#	Bukkit/src/main/java/com/plotsquared/bukkit/BukkitPlatform.java
#	Bukkit/src/main/java/com/plotsquared/bukkit/listener/PlayerEvents.java
#	Bukkit/src/main/java/com/plotsquared/bukkit/player/BukkitOfflinePlayer.java
#	Bukkit/src/main/java/com/plotsquared/bukkit/player/BukkitPlayer.java
#	Bukkit/src/main/java/com/plotsquared/bukkit/queue/BukkitLocalQueue.java
#	Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitEconHandler.java
#	Core/pom.xml
#	Core/src/main/java/com/plotsquared/core/PlotAPI.java
#	Core/src/main/java/com/plotsquared/core/PlotPlatform.java
#	Core/src/main/java/com/plotsquared/core/PlotSquared.java
#	Core/src/main/java/com/plotsquared/core/command/Area.java
#	Core/src/main/java/com/plotsquared/core/command/Auto.java
#	Core/src/main/java/com/plotsquared/core/command/Claim.java
#	Core/src/main/java/com/plotsquared/core/command/CmdConfirm.java
#	Core/src/main/java/com/plotsquared/core/command/Command.java
#	Core/src/main/java/com/plotsquared/core/command/CommandCaller.java
#	Core/src/main/java/com/plotsquared/core/command/DebugExec.java
#	Core/src/main/java/com/plotsquared/core/command/Grant.java
#	Core/src/main/java/com/plotsquared/core/command/Inbox.java
#	Core/src/main/java/com/plotsquared/core/command/Load.java
#	Core/src/main/java/com/plotsquared/core/command/Save.java
#	Core/src/main/java/com/plotsquared/core/command/Setup.java
#	Core/src/main/java/com/plotsquared/core/listener/PlotListener.java
#	Core/src/main/java/com/plotsquared/core/player/ConsolePlayer.java
#	Core/src/main/java/com/plotsquared/core/player/PlotPlayer.java
#	Core/src/main/java/com/plotsquared/core/plot/Plot.java
#	Core/src/main/java/com/plotsquared/core/plot/comment/CommentManager.java
#	Core/src/main/java/com/plotsquared/core/util/BlockUtil.java
#	Core/src/main/java/com/plotsquared/core/util/Permissions.java
This commit is contained in:
Alexander Söderberg
2020-07-24 17:28:52 +02:00
67 changed files with 2097 additions and 1005 deletions

View File

@ -110,6 +110,8 @@ shadowJar {
include(dependency("javax.annotation:javax-annotation-api"))
include(dependency('org.apache.logging.log4j:log4j-slf4j-impl'))
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')

View File

@ -51,7 +51,7 @@
<dependency>
<groupId>io.papermc</groupId>
<artifactId>paperlib</artifactId>
<version>1.0.2</version>
<version>1.0.4</version>
<scope>compile</scope>
</dependency>
<dependency>

View File

@ -30,9 +30,11 @@ import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Stage;
import com.google.inject.TypeLiteral;
import com.plotsquared.bukkit.generator.BukkitPlotGenerator;
import com.plotsquared.bukkit.inject.BackupModule;
import com.plotsquared.bukkit.inject.BukkitModule;
import com.plotsquared.bukkit.inject.PermissionModule;
import com.plotsquared.bukkit.inject.WorldManagerModule;
import com.plotsquared.bukkit.listener.ChunkListener;
import com.plotsquared.bukkit.listener.EntitySpawnListener;
@ -42,6 +44,7 @@ import com.plotsquared.bukkit.listener.SingleWorldListener;
import com.plotsquared.bukkit.listener.WorldEvents;
import com.plotsquared.bukkit.placeholder.PlaceholderFormatter;
import com.plotsquared.bukkit.placeholder.Placeholders;
import com.plotsquared.bukkit.player.BukkitPlayer;
import com.plotsquared.bukkit.player.BukkitPlayerManager;
import com.plotsquared.bukkit.util.task.BukkitTaskManager;
import com.plotsquared.bukkit.util.BukkitUtil;
@ -99,8 +102,8 @@ import com.plotsquared.core.util.ConsoleColors;
import com.plotsquared.core.util.EconHandler;
import com.plotsquared.core.util.EventDispatcher;
import com.plotsquared.core.util.FileUtils;
import com.plotsquared.core.util.PermHandler;
import com.plotsquared.core.util.PlatformWorldManager;
import com.plotsquared.core.util.PlayerManager;
import com.plotsquared.core.util.PremiumVerification;
import com.plotsquared.core.util.ReflectionUtils;
import com.plotsquared.core.util.SetupUtils;
@ -118,7 +121,6 @@ import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.command.PluginCommand;
import org.bukkit.entity.Entity;
@ -178,7 +180,6 @@ import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
private boolean methodUnloadSetup = false;
private boolean metricsStarted;
private EconHandler econ;
private PermHandler perm;
private Injector injector;
@ -244,8 +245,11 @@ import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
// We create the injector after PlotSquared has been initialized, so that we have access
// to generated instances and settings
this.injector = Guice.createInjector(Stage.PRODUCTION, new WorldManagerModule(), new PlotSquaredModule(),
new BukkitModule(this), new BackupModule());
this.injector = Guice.createInjector(Stage.PRODUCTION, new PermissionModule(),
new WorldManagerModule(),
new PlotSquaredModule(),
new BukkitModule(this),
new BackupModule());
this.injector.injectMembers(this);
this.serverLocale = Locale.forLanguageTag(Settings.Enabled_Components.DEFAULT_LOCALE);
@ -334,10 +338,7 @@ import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
// Economy
if (Settings.Enabled_Components.ECONOMY) {
TaskManager.runTask(() -> {
final PermHandler permHandler = getInjector().getInstance(PermHandler.class);
if (permHandler != null) {
permHandler.init();
}
this.getPermissionHandler().initialize();
final EconHandler econHandler = getInjector().getInstance(EconHandler.class);
if (econHandler != null) {
econHandler.init();
@ -569,7 +570,8 @@ import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
}
final Plot plot = area.getOwnedPlot(id);
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()) {
world.setKeepSpawnInMemory(false);
return;
@ -1077,39 +1079,6 @@ import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
}
}
/**
* 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() {
final String name = Bukkit.getServer().getClass().getPackage().getName();
return name.substring(name.lastIndexOf('.') + 1);
@ -1130,7 +1099,7 @@ import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
return names;
}
@Override public com.plotsquared.core.location.World<?> getPlatformWorld(@Nonnull final String worldName) {
@Override @Nonnull public com.plotsquared.core.location.World<?> getPlatformWorld(@Nonnull final String worldName) {
return BukkitWorld.of(worldName);
}
@ -1158,4 +1127,13 @@ import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
throw new UnsupportedOperationException("Cannot replace server locale");
}
@Override @Nonnull public PlatformWorldManager<?> getWorldManager() {
return getInjector().getInstance(Key.get(new TypeLiteral<PlatformWorldManager<World>>() {}));
}
@Override @Nonnull @SuppressWarnings("ALL")
public PlayerManager<? extends PlotPlayer<Player>, ? extends Player> getPlayerManager() {
return (PlayerManager<BukkitPlayer, Player>) getInjector().getInstance(PlayerManager.class);
}
}

View File

@ -29,7 +29,6 @@ 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.util.Providers;
import com.plotsquared.bukkit.BukkitPlatform;
import com.plotsquared.bukkit.player.BukkitPlayerManager;
import com.plotsquared.bukkit.queue.BukkitLocalQueue;
@ -37,12 +36,9 @@ import com.plotsquared.bukkit.schematic.BukkitSchematicHandler;
import com.plotsquared.bukkit.util.BukkitChunkManager;
import com.plotsquared.bukkit.util.BukkitEconHandler;
import com.plotsquared.bukkit.util.BukkitInventoryUtil;
import com.plotsquared.bukkit.util.BukkitPermHandler;
import com.plotsquared.bukkit.util.BukkitRegionManager;
import com.plotsquared.bukkit.util.BukkitSetupUtils;
import com.plotsquared.bukkit.util.BukkitUtil;
import com.plotsquared.bukkit.util.task.PaperTimeConverter;
import com.plotsquared.bukkit.util.task.SpigotTimeConverter;
import com.plotsquared.core.PlotPlatform;
import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.generator.HybridGen;
@ -58,7 +54,6 @@ import com.plotsquared.core.queue.QueueProvider;
import com.plotsquared.core.util.ChunkManager;
import com.plotsquared.core.util.EconHandler;
import com.plotsquared.core.util.InventoryUtil;
import com.plotsquared.core.util.PermHandler;
import com.plotsquared.core.util.PlayerManager;
import com.plotsquared.core.util.RegionManager;
import com.plotsquared.core.util.SchematicHandler;
@ -71,6 +66,7 @@ import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.plugin.java.JavaPlugin;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class BukkitModule extends AbstractModule {
@ -97,7 +93,6 @@ public class BukkitModule extends AbstractModule {
bind(ChunkManager.class).to(BukkitChunkManager.class);
bind(RegionManager.class).to(BukkitRegionManager.class);
bind(SchematicHandler.class).to(BukkitSchematicHandler.class);
this.setupVault();
if (Settings.Enabled_Components.WORLDS) {
bind(PlotAreaManager.class).to(SinglePlotAreaManager.class);
} else {
@ -106,25 +101,14 @@ public class BukkitModule extends AbstractModule {
install(new FactoryModuleBuilder().build(HybridPlotWorldFactory.class));
}
private void setupVault() {
@Provides @Singleton @Nullable EconHandler provideEconHandler() {
if (Bukkit.getPluginManager().isPluginEnabled("Vault")) {
BukkitPermHandler bukkitPermHandler = null;
try {
bukkitPermHandler = new BukkitPermHandler();
bind(PermHandler.class).toInstance(bukkitPermHandler);
return new BukkitEconHandler();
} 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
* 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.plotsquared.core.util.PermHandler;
import net.milkbowl.vault.permission.Permission;
import com.plotsquared.bukkit.permissions.BukkitPermissionHandler;
import com.plotsquared.bukkit.permissions.VaultPermissionHandler;
import com.plotsquared.core.permissions.PermissionHandler;
import org.bukkit.Bukkit;
import org.bukkit.plugin.RegisteredServiceProvider;
@Singleton public class BukkitPermHandler extends PermHandler {
public class PermissionModule extends AbstractModule {
private Permission perms;
@Override
public boolean init() {
if (this.perms == null) {
setupPermissions();
@Provides @Singleton PermissionHandler providePermissionHandler() {
try {
if (Bukkit.getPluginManager().isPluginEnabled("Vault")) {
return new VaultPermissionHandler();
}
} catch (final Exception ignored) {
}
return this.perms != null;
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

@ -39,6 +39,8 @@ import com.plotsquared.core.database.DBFunc;
import com.plotsquared.core.listener.PlayerBlockEventType;
import com.plotsquared.core.listener.PlotListener;
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.plot.Plot;
import com.plotsquared.core.plot.PlotArea;
@ -731,34 +733,38 @@ import java.util.regex.Pattern;
public void onTeleport(PlayerTeleportEvent event) {
Player player = event.getPlayer();
BukkitPlayer pp = BukkitUtil.adapt(player);
Plot lastPlot = pp.getMeta(PlotPlayer.META_LAST_PLOT);
org.bukkit.Location to = event.getTo();
//noinspection ConstantConditions
if (to != null) {
Location location = BukkitUtil.adapt(to);
PlotArea area = location.getPlotArea();
if (area == null) {
if (lastPlot != null) {
plotExit(pp, lastPlot);
pp.deleteMeta(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();
//noinspection ConstantConditions
if (to != null) {
Location location = BukkitUtil.adapt(to);
PlotArea area = location.getPlotArea();
if (area == null) {
if (lastPlot != null) {
plotExit(pp, lastPlot);
lastPlotAccess.remove();
}
try (final MetaDataAccess<Location> lastLocationAccess =
pp.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_LOCATION)) {
lastLocationAccess.remove();
}
return;
}
pp.deleteMeta(PlotPlayer.META_LOCATION);
return;
}
Plot plot = area.getPlot(location);
if (plot != null) {
final boolean result = DenyTeleportFlag.allowsTeleport(pp, plot);
// there is one possibility to still allow teleportation:
// to is identical to the plot's home location, and untrusted-visit is true
// i.e. untrusted-visit can override deny-teleport
// this is acceptable, because otherwise it wouldn't make sense to have both flags set
if (!result && !(plot.getFlag(UntrustedVisitFlag.class) && plot.getHomeSynchronous()
.equals(BukkitUtil.adaptComplete(to)))) {
pp.sendMessage(
Plot plot = area.getPlot(location);
if (plot != null) {
final boolean result = DenyTeleportFlag.allowsTeleport(pp, plot);
// there is one possibility to still allow teleportation:
// to is identical to the plot's home location, and untrusted-visit is true
// i.e. untrusted-visit can override deny-teleport
// this is acceptable, because otherwise it wouldn't make sense to have both flags set
if (!result && !(plot.getFlag(UntrustedVisitFlag.class) && plot.getHomeSynchronous().equals(BukkitUtil.adaptComplete(to)))) {
pp.sendMessage(
TranslatableCaption.of("permission.no_permission_event"),
Template.of("node", "plots.admin.entry.denied")
);
event.setCancelled(true);
event.setCancelled(true);}
}
}
}
@ -849,18 +855,29 @@ import java.util.regex.Pattern;
}
// Set last location
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();
if (area == null) {
pp.deleteMeta(PlotPlayer.META_LAST_PLOT);
try (final MetaDataAccess<Plot> lastPlotAccess =
pp.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_LAST_PLOT)) {
lastPlotAccess.remove();
}
return;
}
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 (lastPlot != null && !plotExit(pp, lastPlot) && this.tmpTeleport && !pp
.getMeta("kick", false)) {
pp.sendMessage(
try (final MetaDataAccess<Boolean> kickAccess =
pp.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_KICK)) {
if (lastPlot != null && !plotExit(pp, lastPlot) && this.tmpTeleport && !kickAccess.get().orElse(false)) {
pp.sendMessage(
TranslatableCaption.of("permission.no_permission_event"),
Template.of("node", "plots.admin.exit.denied")
);
@ -872,7 +889,7 @@ import java.util.regex.Pattern;
}
this.tmpTeleport = true;
event.setCancelled(true);
return;
return;}
}
} else if (now.equals(lastPlot)) {
ForceFieldListener.handleForcefield(player, pp, now);
@ -915,18 +932,29 @@ import java.util.regex.Pattern;
}
// Set last location
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();
if (area == null) {
pp.deleteMeta(PlotPlayer.META_LAST_PLOT);
try (final MetaDataAccess<Plot> lastPlotAccess =
pp.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_LAST_PLOT)) {
lastPlotAccess.remove();
}
return;
}
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 (lastPlot != null && !plotExit(pp, lastPlot) && this.tmpTeleport && !pp
.getMeta("kick", false)) {
pp.sendMessage(
try (final MetaDataAccess<Boolean> kickAccess =
pp.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_KICK)) {
if (lastPlot != null && !plotExit(pp, lastPlot) && this.tmpTeleport && !kickAccess.get().orElse(false)) {
pp.sendMessage(
TranslatableCaption.of("permission.no_permission_event"),
Template.of("node", "plots.admin.exit.denied")
);
@ -938,7 +966,7 @@ import java.util.regex.Pattern;
}
this.tmpTeleport = true;
event.setCancelled(true);
return;
return;}
}
} else if (now.equals(lastPlot)) {
ForceFieldListener.handleForcefield(player, pp, now);
@ -1175,8 +1203,15 @@ import java.util.regex.Pattern;
Player player = event.getPlayer();
BukkitPlayer pp = BukkitUtil.adapt(player);
// Delete last location
Plot plot = (Plot) pp.deleteMeta(PlotPlayer.META_LAST_PLOT);
pp.deleteMeta(PlotPlayer.META_LOCATION);
Plot plot;
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) {
plotExit(pp, plot);
}
@ -1187,9 +1222,6 @@ import java.util.regex.Pattern;
}
}
}
if (Settings.Enabled_Components.PERMISSION_CACHE) {
pp.deleteMeta("perm");
}
Location location = pp.getLocation();
PlotArea area = location.getPlotArea();
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;
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 org.bukkit.OfflinePlayer;
import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.UUID;
public class BukkitOfflinePlayer implements OfflinePlotPlayer {
public final OfflinePlayer player;
private final PermissionProfile permissionProfile;
/**
* Please do not use this method. Instead use BukkitUtil.getPlayer(Player),
* 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.permissionProfile = permissionHandler.getPermissionProfile(this)
.orElse(NullPermissionProfile.INSTANCE);
}
@Nonnull @Override public UUID getUUID() {
return this.player.getUniqueId();
}
@Override public long getLastPlayed() {
return this.player.getLastPlayed();
}
@Override public boolean isOnline() {
return this.player.isOnline();
@Override @Nonnegative public long getLastPlayed() {
return this.player.getLastSeen();
}
@Override public String 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.events.TeleportCause;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.permissions.PermissionHandler;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.PlotWeather;
import com.plotsquared.core.plot.world.PlotAreaManager;
@ -54,6 +55,8 @@ import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.permissions.PermissionAttachmentInfo;
import org.bukkit.plugin.RegisteredListener;
import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Arrays;
@ -69,13 +72,11 @@ import static com.sk89q.worldedit.world.gamemode.GameModes.SURVIVAL;
public class BukkitPlayer extends PlotPlayer<Player> {
private static boolean CHECK_EFFECTIVE = true;
private final EconHandler econHandler;
public final Player player;
private boolean offline;
private final EconHandler econHandler;
private String name;
private String lastMessage = "";
private long lastMessageTime = 0L;
/**
* <p>Please do not use this method. Instead use
* BukkitUtil.getPlayer(Player), as it caches player objects.</p>
@ -83,22 +84,18 @@ public class BukkitPlayer extends PlotPlayer<Player> {
* @param player Bukkit player instance
*/
public BukkitPlayer(@Nonnull final PlotAreaManager plotAreaManager, @Nonnull final EventDispatcher eventDispatcher,
@Nonnull final Player player, @Nullable final EconHandler econHandler) {
this(plotAreaManager, eventDispatcher, player, false, econHandler);
}
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);
@Nonnull final Player player, @Nullable final EconHandler econHandler, @Nonnull final PermissionHandler permissionHandler) {
this(plotAreaManager, eventDispatcher, player, false, econHandler, permissionHandler);
}
public BukkitPlayer(@Nonnull final PlotAreaManager plotAreaManager, @Nonnull final
EventDispatcher eventDispatcher, @Nonnull final Player player, final boolean offline,
final boolean realPlayer, @Nullable final EconHandler econHandler) {
super(plotAreaManager, eventDispatcher, econHandler);
EventDispatcher eventDispatcher, @Nonnull final Player player,
final boolean realPlayer, @Nullable final EconHandler econHandler,
@Nonnull final PermissionHandler permissionHandler) {
super(plotAreaManager, eventDispatcher, econHandler, permissionHandler);
this.player = player;
this.offline = offline;
this.econHandler = econHandler;
this.setupPermissionProfile();
if (realPlayer) {
super.populatePersistentMetaMap();
}
@ -125,8 +122,8 @@ public class BukkitPlayer extends PlotPlayer<Player> {
return player.getUniqueId();
}
@Override public long getLastPlayed() {
return this.player.getLastPlayed();
@Override @Nonnegative public long getLastPlayed() {
return this.player.getLastSeen();
}
@Override public boolean canTeleport(@Nonnull final Location location) {
@ -163,7 +160,8 @@ public class BukkitPlayer extends PlotPlayer<Player> {
return this.player.hasPermission(permission);
}
@Override public int hasPermissionRange(final String stub, final int range) {
@Override @Nonnegative public int hasPermissionRange(@Nonnull final String stub,
@Nonnegative final int range) {
if (hasPermission(Captions.PERMISSION_ADMIN.getTranslated())) {
return Integer.MAX_VALUE;
}
@ -223,10 +221,6 @@ public class BukkitPlayer extends PlotPlayer<Player> {
return max;
}
@Override public boolean isPermissionSet(@Nonnull final String permission) {
return this.player.isPermissionSet(permission);
}
@Override
public void teleport(@Nonnull final Location location, @Nonnull final TeleportCause cause) {
if (Math.abs(location.getX()) >= 30000000 || Math.abs(location.getZ()) >= 30000000) {
@ -245,10 +239,6 @@ public class BukkitPlayer extends PlotPlayer<Player> {
return this.name;
}
@Override public boolean isOnline() {
return !this.offline && this.player.isOnline();
}
@Override public void setCompassTarget(Location location) {
this.player.setCompassTarget(
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.Singleton;
import com.plotsquared.core.permissions.PermissionHandler;
import com.plotsquared.core.plot.world.PlotAreaManager;
import com.plotsquared.core.util.EconHandler;
import com.plotsquared.core.util.EventDispatcher;
@ -46,21 +47,26 @@ import java.util.UUID;
private final PlotAreaManager plotAreaManager;
private final EventDispatcher eventDispatcher;
private final EconHandler econHandler;
private final PermissionHandler permissionHandler;
@Inject public BukkitPlayerManager(@Nonnull final PlotAreaManager plotAreaManager,
@Nonnull final EventDispatcher eventDispatcher,
@Nullable final EconHandler econHandler) {
@Nullable final EconHandler econHandler,
@Nonnull final PermissionHandler permissionHandler) {
this.plotAreaManager = plotAreaManager;
this.eventDispatcher = eventDispatcher;
this.econHandler = econHandler;
this.permissionHandler = permissionHandler;
}
@Nonnull @Override public BukkitPlayer getPlayer(@Nonnull final Player object) {
if (!object.isOnline()) {
throw new NoSuchPlayerException(object.getUniqueId());
}
try {
return getPlayer(object.getUniqueId());
} catch (final NoSuchPlayerException exception) {
return new BukkitPlayer(this.plotAreaManager, this.eventDispatcher, object,
object.isOnline(), false, this.econHandler);
return new BukkitPlayer(this.plotAreaManager, this.eventDispatcher, object, false, this.econHandler, this.permissionHandler);
}
}
@ -69,18 +75,18 @@ import java.util.UUID;
if (player == null || !player.isOnline()) {
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) {
if (uuid == 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) {
return new BukkitOfflinePlayer(Bukkit.getOfflinePlayer(username));
return new BukkitOfflinePlayer(Bukkit.getOfflinePlayer(username), this.permissionHandler);
}
}

View File

@ -29,6 +29,7 @@ import com.plotsquared.bukkit.schematic.StateWrapper;
import com.plotsquared.bukkit.util.BukkitBlockUtil;
import com.plotsquared.core.queue.BasicLocalBlockQueue;
import com.plotsquared.core.util.BlockUtil;
import com.plotsquared.core.util.ChunkUtil;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.WorldEdit;
@ -124,9 +125,9 @@ public class BukkitLocalQueue extends BasicLocalBlockQueue {
for (int j = 0; j < blocksLayer.length; j++) {
if (blocksLayer[j] != null) {
BaseBlock block = blocksLayer[j];
int x = MainUtil.x_loc[layer][j];
int y = MainUtil.y_loc[layer][j];
int z = MainUtil.z_loc[layer][j];
int x = ChunkUtil.getX(j);
int y = ChunkUtil.getY(layer, j);
int z = ChunkUtil.getZ(j);
BlockData blockData = BukkitAdapter.adapt(block);

View File

@ -25,14 +25,12 @@
*/
package com.plotsquared.bukkit.util;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.plotsquared.bukkit.player.BukkitOfflinePlayer;
import com.plotsquared.bukkit.player.BukkitPlayer;
import com.plotsquared.core.player.OfflinePlotPlayer;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.util.EconHandler;
import com.plotsquared.core.util.PermHandler;
import net.milkbowl.vault.economy.Economy;
import org.bukkit.Bukkit;
import org.bukkit.plugin.RegisteredServiceProvider;
@ -43,14 +41,7 @@ import javax.annotation.Nullable;
private Economy econ;
private final PermHandler permHandler;
@Inject public BukkitEconHandler(@Nullable final PermHandler permHandler) {
this.permHandler = permHandler;
}
@Override
public boolean init() {
@Override public boolean init() {
if (this.econ == null) {
setupEconomy();
}
@ -88,17 +79,6 @@ import javax.annotation.Nullable;
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) {
return this.econ.getBalance(player.getName());
}

View File

@ -59,7 +59,6 @@ import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.block.Biome;
import org.bukkit.block.Block;
@ -107,7 +106,6 @@ import java.util.Collection;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.function.Consumer;
import java.util.function.IntConsumer;
import java.util.stream.Stream;
@ -127,24 +125,6 @@ import java.util.stream.Stream;
super(regionManager);
}
/**
* 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}
*
@ -225,18 +205,6 @@ import java.util.stream.Stream;
}
}
/**
* Gets the PlotPlayer for a UUID. The PlotPlayer is usually cached and
* 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)) {

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);
}
}