365 lines
13 KiB
Java
365 lines
13 KiB
Java
package com.earth2me.essentials;
|
|
|
|
import com.earth2me.essentials.config.ConfigurateUtil;
|
|
import com.earth2me.essentials.config.EssentialsConfiguration;
|
|
import com.earth2me.essentials.config.entities.LazyLocation;
|
|
import com.earth2me.essentials.utils.AdventureUtil;
|
|
import net.ess3.api.IEssentials;
|
|
import net.ess3.api.IUser;
|
|
import net.ess3.api.TranslatableException;
|
|
import org.bukkit.Location;
|
|
import org.bukkit.entity.Entity;
|
|
import org.bukkit.entity.EntityType;
|
|
import org.bukkit.entity.Player;
|
|
import org.bukkit.event.EventHandler;
|
|
import org.bukkit.event.EventPriority;
|
|
import org.bukkit.event.Listener;
|
|
import org.bukkit.event.block.BlockBreakEvent;
|
|
import org.bukkit.event.block.BlockDamageEvent;
|
|
import org.bukkit.event.block.BlockPlaceEvent;
|
|
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
|
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
|
|
import org.bukkit.event.player.PlayerGameModeChangeEvent;
|
|
import org.bukkit.event.player.PlayerInteractEvent;
|
|
import org.bukkit.event.player.PlayerJoinEvent;
|
|
import org.bukkit.event.player.PlayerRespawnEvent;
|
|
import org.bukkit.event.player.PlayerTeleportEvent;
|
|
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
|
import org.bukkit.plugin.PluginManager;
|
|
import org.spongepowered.configurate.CommentedConfigurationNode;
|
|
|
|
import java.io.File;
|
|
import java.util.ArrayList;
|
|
import java.util.Collection;
|
|
import java.util.HashMap;
|
|
import java.util.Locale;
|
|
import java.util.Map;
|
|
import java.util.concurrent.CompletableFuture;
|
|
import java.util.logging.Level;
|
|
|
|
import static com.earth2me.essentials.I18n.tlLiteral;
|
|
|
|
public class Jails implements net.ess3.api.IJails {
|
|
private static transient boolean enabled = false;
|
|
private final IEssentials ess;
|
|
private final EssentialsConfiguration config;
|
|
private final Map<String, LazyLocation> jails = new HashMap<>();
|
|
|
|
public Jails(final IEssentials ess) {
|
|
this.ess = ess;
|
|
this.config = new EssentialsConfiguration(new File(ess.getDataFolder(), "jail.yml"));
|
|
reloadConfig();
|
|
}
|
|
|
|
@Override
|
|
public void reloadConfig() {
|
|
synchronized (jails) {
|
|
config.load();
|
|
jails.clear();
|
|
final CommentedConfigurationNode jailsNode = config.getSection("jails");
|
|
for (final Map.Entry<String, CommentedConfigurationNode> entry : ConfigurateUtil.getMap(jailsNode).entrySet()) {
|
|
final CommentedConfigurationNode jailNode = entry.getValue();
|
|
final String worldId = jailNode.node("world").getString();
|
|
if (worldId == null || worldId.isEmpty()) {
|
|
continue;
|
|
}
|
|
jails.put(entry.getKey().toLowerCase(Locale.ENGLISH), new LazyLocation(worldId, jailNode.node("world-name").getString(""), jailNode.node("x").getDouble(), jailNode.node("y").getDouble(),
|
|
jailNode.node("z").getDouble(), jailNode.node("yaw").getFloat(), jailNode.node("pitch").getFloat()));
|
|
}
|
|
checkRegister();
|
|
}
|
|
}
|
|
|
|
private void registerListeners() {
|
|
enabled = true;
|
|
final PluginManager pluginManager = ess.getServer().getPluginManager();
|
|
final JailListener blockListener = new JailListener();
|
|
pluginManager.registerEvents(blockListener, ess);
|
|
if (ess.getSettings().isDebug()) {
|
|
ess.getLogger().log(Level.INFO, "Registering Jail listener");
|
|
}
|
|
}
|
|
|
|
public void resetListener() {
|
|
enabled = false;
|
|
checkRegister();
|
|
}
|
|
|
|
private void checkRegister() {
|
|
if (!enabled && getCount() > 0) {
|
|
registerListeners();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void startTransaction() {
|
|
config.startTransaction();
|
|
}
|
|
|
|
@Override
|
|
public void stopTransaction(final boolean blocking) {
|
|
config.stopTransaction(blocking);
|
|
}
|
|
|
|
@Override
|
|
public Location getJail(String jailName) throws Exception {
|
|
if (jailName == null) {
|
|
throw new TranslatableException("jailNotExist");
|
|
}
|
|
|
|
jailName = jailName.toLowerCase(Locale.ENGLISH);
|
|
synchronized (jails) {
|
|
if (!jails.containsKey(jailName)) {
|
|
throw new TranslatableException("jailNotExist");
|
|
}
|
|
final Location location = jails.get(jailName).location();
|
|
if (location == null) {
|
|
throw new TranslatableException("jailWorldNotExist");
|
|
}
|
|
return location;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public Collection<String> getList() throws Exception {
|
|
synchronized (jails) {
|
|
return new ArrayList<>(jails.keySet());
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void removeJail(String jail) throws Exception {
|
|
if (jail == null) {
|
|
return;
|
|
}
|
|
|
|
jail = jail.toLowerCase(Locale.ENGLISH);
|
|
synchronized (jails) {
|
|
if (jails.remove(jail) != null) {
|
|
config.getSection("jails").node(jail).set(null);
|
|
config.save();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @deprecated This method does not use asynchronous teleportation. Use {@link Jails#sendToJail(IUser, String, CompletableFuture)}
|
|
*/
|
|
@SuppressWarnings("deprecation")
|
|
@Override
|
|
@Deprecated
|
|
public void sendToJail(final IUser user, String jail) throws Exception {
|
|
if (jail == null || jail.isEmpty()) {
|
|
return;
|
|
}
|
|
|
|
jail = jail.toLowerCase(Locale.ENGLISH);
|
|
synchronized (jails) {
|
|
if (jails.containsKey(jail)) {
|
|
if (user.getBase().isOnline()) {
|
|
user.getTeleport().now(getJail(jail), false, TeleportCause.COMMAND);
|
|
}
|
|
user.setJail(jail);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void sendToJail(final IUser user, final String jailName, final CompletableFuture<Boolean> future) throws Exception {
|
|
if (jailName == null || jailName.isEmpty()) {
|
|
return;
|
|
}
|
|
|
|
final String jail = jailName.toLowerCase(Locale.ENGLISH);
|
|
synchronized (jails) {
|
|
if (jails.containsKey(jail)) {
|
|
if (user.getBase().isOnline()) {
|
|
user.getAsyncTeleport().now(getJail(jail), false, TeleportCause.COMMAND, future);
|
|
future.thenAccept(success -> user.setJail(jail));
|
|
return;
|
|
}
|
|
user.setJail(jail);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void setJail(String jailName, final Location loc) throws Exception {
|
|
jailName = jailName.toLowerCase(Locale.ENGLISH);
|
|
synchronized (jails) {
|
|
jails.put(jailName, LazyLocation.fromLocation(loc));
|
|
config.setProperty("jails." + jailName, loc);
|
|
config.save();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public int getCount() {
|
|
try {
|
|
return getList().size();
|
|
} catch (final Exception ex) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
private class JailListener implements Listener {
|
|
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
|
public void onJailBlockBreak(final BlockBreakEvent event) {
|
|
if (shouldIgnore(event.getPlayer())) {
|
|
return;
|
|
}
|
|
|
|
final User user = ess.getUser(event.getPlayer());
|
|
if (user.isJailed() && !user.isAuthorized("essentials.jail.allow-break")) {
|
|
event.setCancelled(true);
|
|
}
|
|
}
|
|
|
|
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
|
public void onJailBlockPlace(final BlockPlaceEvent event) {
|
|
if (shouldIgnore(event.getPlayer())) {
|
|
return;
|
|
}
|
|
|
|
final User user = ess.getUser(event.getPlayer());
|
|
if (user.isJailed() && !user.isAuthorized("essentials.jail.allow-place")) {
|
|
event.setCancelled(true);
|
|
}
|
|
}
|
|
|
|
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
|
public void onJailBlockDamage(final BlockDamageEvent event) {
|
|
if (shouldIgnore(event.getPlayer())) {
|
|
return;
|
|
}
|
|
|
|
final User user = ess.getUser(event.getPlayer());
|
|
if (user.isJailed() && !user.isAuthorized("essentials.jail.allow-block-damage")) {
|
|
event.setCancelled(true);
|
|
}
|
|
}
|
|
|
|
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
|
public void onJailEntityDamageByEntity(final EntityDamageByEntityEvent event) {
|
|
if (event.getCause() != DamageCause.ENTITY_ATTACK || event.getEntity().getType() != EntityType.PLAYER) {
|
|
return;
|
|
}
|
|
final Entity damager = event.getDamager();
|
|
if (damager.getType() == EntityType.PLAYER) {
|
|
if (shouldIgnore((Player) damager)) {
|
|
return;
|
|
}
|
|
final User user = ess.getUser((Player) damager);
|
|
if (user != null && user.isJailed()) {
|
|
event.setCancelled(true);
|
|
}
|
|
}
|
|
}
|
|
|
|
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
|
public void onJailPlayerInteract(final PlayerInteractEvent event) {
|
|
if (shouldIgnore(event.getPlayer())) {
|
|
return;
|
|
}
|
|
|
|
final User user = ess.getUser(event.getPlayer());
|
|
if (user.isJailed() && !user.isAuthorized("essentials.jail.allow-interact")) {
|
|
event.setCancelled(true);
|
|
}
|
|
}
|
|
|
|
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
|
public void onJailPlayerGameModeChange(final PlayerGameModeChangeEvent event) {
|
|
if (shouldIgnore(event.getPlayer())) {
|
|
return;
|
|
}
|
|
|
|
final User user = ess.getUser(event.getPlayer());
|
|
if (user.isJailed()) {
|
|
event.setCancelled(true);
|
|
}
|
|
}
|
|
|
|
@EventHandler(priority = EventPriority.HIGHEST)
|
|
public void onJailPlayerRespawn(final PlayerRespawnEvent event) {
|
|
if (shouldIgnore(event.getPlayer())) {
|
|
return;
|
|
}
|
|
|
|
final User user = ess.getUser(event.getPlayer());
|
|
if (!user.isJailed() || user.getJail() == null || user.getJail().isEmpty()) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
event.setRespawnLocation(getJail(user.getJail()));
|
|
} catch (final Exception ex) {
|
|
if (ess.getSettings().isDebug()) {
|
|
ess.getLogger().log(Level.INFO, AdventureUtil.miniToLegacy(tlLiteral("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage())), ex);
|
|
} else {
|
|
ess.getLogger().log(Level.INFO, AdventureUtil.miniToLegacy(tlLiteral("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage())));
|
|
}
|
|
}
|
|
}
|
|
|
|
@EventHandler(priority = EventPriority.HIGH)
|
|
public void onJailPlayerTeleport(final PlayerTeleportEvent event) {
|
|
if (shouldIgnore(event.getPlayer())) {
|
|
return;
|
|
}
|
|
|
|
final User user = ess.getUser(event.getPlayer());
|
|
if (!user.isJailed() || user.getJail() == null || user.getJail().isEmpty()) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
event.setTo(getJail(user.getJail()));
|
|
} catch (final Exception ex) {
|
|
if (ess.getSettings().isDebug()) {
|
|
ess.getLogger().log(Level.INFO, AdventureUtil.miniToLegacy(tlLiteral("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage())), ex);
|
|
} else {
|
|
ess.getLogger().log(Level.INFO, AdventureUtil.miniToLegacy(tlLiteral("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage())));
|
|
}
|
|
}
|
|
user.sendTl("jailMessage");
|
|
}
|
|
|
|
@EventHandler(priority = EventPriority.HIGHEST)
|
|
public void onJailPlayerJoin(final PlayerJoinEvent event) {
|
|
if (shouldIgnore(event.getPlayer())) {
|
|
return;
|
|
}
|
|
|
|
final User user = ess.getUser(event.getPlayer());
|
|
final long currentTime = System.currentTimeMillis();
|
|
user.checkJailTimeout(currentTime);
|
|
if (!user.isJailed() || user.getJail() == null || user.getJail().isEmpty()) {
|
|
return;
|
|
}
|
|
|
|
final CompletableFuture<Boolean> future = new CompletableFuture<>();
|
|
future.exceptionally(ex -> {
|
|
if (ess.getSettings().isDebug()) {
|
|
ess.getLogger().log(Level.INFO, AdventureUtil.miniToLegacy(tlLiteral("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage())), ex);
|
|
} else {
|
|
ess.getLogger().log(Level.INFO, AdventureUtil.miniToLegacy(tlLiteral("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage())));
|
|
}
|
|
return false;
|
|
});
|
|
future.thenAccept(success -> user.sendTl("jailMessage"));
|
|
|
|
try {
|
|
sendToJail(user, user.getJail(), future);
|
|
} catch (final Exception ex) {
|
|
future.completeExceptionally(ex);
|
|
}
|
|
}
|
|
|
|
private boolean shouldIgnore(final Player base) {
|
|
// Ignore Citizens NPCs
|
|
return base.getUniqueId().version() == 2 || base.hasMetadata("NPC");
|
|
}
|
|
}
|
|
}
|