mirror of
https://github.com/EssentialsX/Essentials.git
synced 2025-01-21 23:51:42 +01:00
Improvements to Random Teleport (#4271)
Co-authored-by: triagonal <10545540+triagonal@users.noreply.github.com> Co-authored-by: Josh Roy <10731363+JRoy@users.noreply.github.com>
This commit is contained in:
parent
1778bf5ada
commit
2418a6fb78
@ -7,7 +7,6 @@ import com.earth2me.essentials.utils.LocationUtil;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import net.ess3.api.IEssentials;
|
||||
import net.ess3.api.IUser;
|
||||
import net.ess3.api.InvalidWorldException;
|
||||
import net.ess3.api.TranslatableException;
|
||||
import net.ess3.api.events.UserWarpEvent;
|
||||
import net.ess3.api.events.teleport.PreTeleportEvent;
|
||||
@ -424,7 +423,7 @@ public class AsyncTeleport implements IAsyncTeleport {
|
||||
final Location loc;
|
||||
try {
|
||||
loc = ess.getWarps().getWarp(warp);
|
||||
} catch (final WarpNotFoundException | InvalidWorldException e) {
|
||||
} catch (final WarpNotFoundException e) {
|
||||
future.completeExceptionally(e);
|
||||
return;
|
||||
}
|
||||
|
@ -358,6 +358,10 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
upgrade.convertKits();
|
||||
execTimer.mark("Kits");
|
||||
|
||||
randomTeleport = new RandomTeleport(this);
|
||||
confList.add(randomTeleport);
|
||||
execTimer.mark("Init(RandomTeleport)");
|
||||
|
||||
upgrade.afterSettings();
|
||||
execTimer.mark("Upgrade3");
|
||||
|
||||
@ -373,13 +377,6 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
confList.add(itemDb);
|
||||
execTimer.mark("Init(ItemDB)");
|
||||
|
||||
randomTeleport = new RandomTeleport(this);
|
||||
if (randomTeleport.getPreCache()) {
|
||||
randomTeleport.cacheRandomLocations(randomTeleport.getCenter(), randomTeleport.getMinRange(), randomTeleport.getMaxRange());
|
||||
}
|
||||
confList.add(randomTeleport);
|
||||
execTimer.mark("Init(RandomTeleport)");
|
||||
|
||||
customItemResolver = new CustomItemResolver(this);
|
||||
try {
|
||||
itemDb.registerResolver(this, "custom_items", customItemResolver);
|
||||
|
@ -3,6 +3,7 @@ package com.earth2me.essentials;
|
||||
import com.earth2me.essentials.config.ConfigurateUtil;
|
||||
import com.earth2me.essentials.config.EssentialsConfiguration;
|
||||
import com.earth2me.essentials.config.EssentialsUserConfiguration;
|
||||
import com.earth2me.essentials.config.entities.LazyLocation;
|
||||
import com.earth2me.essentials.craftbukkit.BanLookup;
|
||||
import com.earth2me.essentials.userstorage.ModernUUIDCache;
|
||||
import com.earth2me.essentials.utils.AdventureUtil;
|
||||
@ -156,6 +157,39 @@ public class EssentialsUpgrade {
|
||||
ess.getLogger().info("To rerun the conversion type /essentials uuidconvert");
|
||||
}
|
||||
|
||||
public void updateRandomTeleport() {
|
||||
if (doneFile.getBoolean("updateRandomTeleport", false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final EssentialsConfiguration config = ess.getRandomTeleport().getConfig();
|
||||
|
||||
final LazyLocation center = config.getLocation("center");
|
||||
final Location centerLoc = center != null ? center.location() : null;
|
||||
if (center != null && centerLoc != null) {
|
||||
final double minRange = config.getDouble("min-range", Double.MIN_VALUE);
|
||||
final double maxRange = config.getDouble("max-range", Double.MIN_VALUE);
|
||||
for (final World world : ess.getServer().getWorlds()) {
|
||||
final String propPrefix = "locations." + world.getName() + ".";
|
||||
config.setProperty(propPrefix + "center", centerLoc);
|
||||
|
||||
if (minRange != Double.MIN_VALUE) {
|
||||
config.setProperty(propPrefix + "min-range", minRange);
|
||||
}
|
||||
if (maxRange != Double.MIN_VALUE) {
|
||||
config.setProperty(propPrefix + "max-range", maxRange);
|
||||
}
|
||||
}
|
||||
}
|
||||
config.removeProperty("center");
|
||||
|
||||
config.blockingSave();
|
||||
|
||||
doneFile.setProperty("updateRandomTeleport", true);
|
||||
doneFile.save();
|
||||
ess.getLogger().info("Done converting random teleport config.");
|
||||
}
|
||||
|
||||
public void convertMailList() {
|
||||
if (doneFile.getBoolean("updateUsersMailList", false)) {
|
||||
return;
|
||||
@ -1068,5 +1102,6 @@ public class EssentialsUpgrade {
|
||||
convertStupidCamelCaseUserdataKeys();
|
||||
convertMailList();
|
||||
purgeBrokenNpcAccounts();
|
||||
updateRandomTeleport();
|
||||
}
|
||||
}
|
||||
|
@ -106,6 +106,10 @@ public interface ISettings extends IConf {
|
||||
|
||||
boolean getRespawnAtHome();
|
||||
|
||||
String getRandomSpawnLocation();
|
||||
|
||||
String getRandomRespawnLocation();
|
||||
|
||||
boolean isRespawnAtAnchor();
|
||||
|
||||
Set getMultipleHomes();
|
||||
|
@ -1,17 +1,22 @@
|
||||
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.LocationUtil;
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import net.ess3.api.InvalidWorldException;
|
||||
import net.ess3.provider.BiomeKeyProvider;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
@ -23,58 +28,72 @@ public class RandomTeleport implements IConf {
|
||||
private static final int HIGHEST_BLOCK_Y_OFFSET = VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_15_R01) ? 1 : 0;
|
||||
private final IEssentials ess;
|
||||
private final EssentialsConfiguration config;
|
||||
private final ConcurrentLinkedQueue<Location> cachedLocations = new ConcurrentLinkedQueue<>();
|
||||
private final Map<String, ConcurrentLinkedQueue<Location>> cachedLocations = new HashMap<>();
|
||||
|
||||
public RandomTeleport(final IEssentials essentials) {
|
||||
this.ess = essentials;
|
||||
config = new EssentialsConfiguration(new File(essentials.getDataFolder(), "tpr.yml"), "/tpr.yml",
|
||||
"Configuration for the random teleport command.\nSome settings may be defaulted, and can be changed via the /settpr command in-game.");
|
||||
"Configuration for the random teleport command.\nUse the /settpr command in-game to set random teleport locations.");
|
||||
reloadConfig();
|
||||
}
|
||||
|
||||
public EssentialsConfiguration getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reloadConfig() {
|
||||
config.load();
|
||||
cachedLocations.clear();
|
||||
}
|
||||
|
||||
public Location getCenter() {
|
||||
try {
|
||||
final LazyLocation center = config.getLocation("center");
|
||||
public boolean hasLocation(final String name) {
|
||||
return config.hasProperty("locations." + name);
|
||||
}
|
||||
|
||||
public Location getCenter(final String name) {
|
||||
final LazyLocation center = config.getLocation(locationKey(name, "center"));
|
||||
if (center != null && center.location() != null) {
|
||||
return center.location();
|
||||
}
|
||||
} catch (final InvalidWorldException ignored) {
|
||||
}
|
||||
final Location center = ess.getServer().getWorlds().get(0).getWorldBorder().getCenter();
|
||||
center.setY(center.getWorld().getHighestBlockYAt(center) + HIGHEST_BLOCK_Y_OFFSET);
|
||||
setCenter(center);
|
||||
return center;
|
||||
|
||||
final Location worldCenter = ess.getServer().getWorlds().get(0).getWorldBorder().getCenter();
|
||||
worldCenter.setY(worldCenter.getWorld().getHighestBlockYAt(worldCenter) + HIGHEST_BLOCK_Y_OFFSET);
|
||||
setCenter(name, worldCenter);
|
||||
return worldCenter;
|
||||
}
|
||||
|
||||
public void setCenter(final Location center) {
|
||||
config.setProperty("center", center);
|
||||
public void setCenter(final String name, final Location center) {
|
||||
config.setProperty(locationKey(name, "center"), center);
|
||||
config.save();
|
||||
}
|
||||
|
||||
public double getMinRange() {
|
||||
return config.getDouble("min-range", 0d);
|
||||
public double getMinRange(final String name) {
|
||||
return config.getDouble(locationKey(name, "min-range"), 0d);
|
||||
}
|
||||
|
||||
public void setMinRange(final double minRange) {
|
||||
config.setProperty("min-range", minRange);
|
||||
public void setMinRange(final String name, final double minRange) {
|
||||
config.setProperty(locationKey(name, "min-range"), minRange);
|
||||
config.save();
|
||||
}
|
||||
|
||||
public double getMaxRange() {
|
||||
return config.getDouble("max-range", getCenter().getWorld().getWorldBorder().getSize() / 2);
|
||||
public double getMaxRange(final String name) {
|
||||
return config.getDouble(locationKey(name, "max-range"), getCenter(name).getWorld().getWorldBorder().getSize() / 2);
|
||||
}
|
||||
|
||||
public void setMaxRange(final double maxRange) {
|
||||
config.setProperty("max-range", maxRange);
|
||||
public void setMaxRange(final String name, final double maxRange) {
|
||||
config.setProperty(locationKey(name, "max-range"), maxRange);
|
||||
config.save();
|
||||
}
|
||||
|
||||
public String getDefaultLocation() {
|
||||
return config.getString("default-location", "{world}");
|
||||
}
|
||||
|
||||
public boolean isPerLocationPermission() {
|
||||
return config.getBoolean("per-location-permission", false);
|
||||
}
|
||||
|
||||
public Set<String> getExcludedBiomes() {
|
||||
final Set<String> excludedBiomes = new HashSet<>();
|
||||
for (final String key : config.getList("excluded-biomes", String.class)) {
|
||||
@ -91,39 +110,48 @@ public class RandomTeleport implements IConf {
|
||||
return config.getInt("cache-threshold", 10);
|
||||
}
|
||||
|
||||
public boolean getPreCache() {
|
||||
return config.getBoolean("pre-cache", false);
|
||||
public List<String> listLocations() {
|
||||
return new ArrayList<>(ConfigurateUtil.getKeys(config.getRootNode().node("locations")));
|
||||
}
|
||||
|
||||
public Queue<Location> getCachedLocations() {
|
||||
return cachedLocations;
|
||||
public Queue<Location> getCachedLocations(final String name) {
|
||||
this.cachedLocations.computeIfAbsent(name, x -> new ConcurrentLinkedQueue<>());
|
||||
return cachedLocations.get(name);
|
||||
}
|
||||
|
||||
// Get a random location; cached if possible. Otherwise on demand.
|
||||
public CompletableFuture<Location> getRandomLocation(final Location center, final double minRange, final double maxRange) {
|
||||
final int findAttempts = this.getFindAttempts();
|
||||
final Queue<Location> cachedLocations = this.getCachedLocations();
|
||||
// Get a named random teleport location; cached if possible, otherwise on demand.
|
||||
public CompletableFuture<Location> getRandomLocation(final String name) {
|
||||
final Queue<Location> cached = this.getCachedLocations(name);
|
||||
// Try to build up the cache if it is below the threshold
|
||||
if (cachedLocations.size() < this.getCacheThreshold()) {
|
||||
cacheRandomLocations(center, minRange, maxRange);
|
||||
if (cached.size() < this.getCacheThreshold()) {
|
||||
cacheRandomLocations(name);
|
||||
}
|
||||
final CompletableFuture<Location> future = new CompletableFuture<>();
|
||||
// Return a random location immediately if one is available, otherwise try to find one now
|
||||
if (cachedLocations.isEmpty()) {
|
||||
if (cached.isEmpty()) {
|
||||
final int findAttempts = this.getFindAttempts();
|
||||
final Location center = this.getCenter(name);
|
||||
final double minRange = this.getMinRange(name);
|
||||
final double maxRange = this.getMaxRange(name);
|
||||
attemptRandomLocation(findAttempts, center, minRange, maxRange).thenAccept(future::complete);
|
||||
} else {
|
||||
future.complete(cachedLocations.poll());
|
||||
future.complete(cached.poll());
|
||||
}
|
||||
return future;
|
||||
}
|
||||
|
||||
// Prompts caching random valid locations, up to a maximum number of attempts
|
||||
public void cacheRandomLocations(final Location center, final double minRange, final double maxRange) {
|
||||
// Get a random location with specific parameters (note: not cached).
|
||||
public CompletableFuture<Location> getRandomLocation(final Location center, final double minRange, final double maxRange) {
|
||||
return attemptRandomLocation(this.getFindAttempts(), center, minRange, maxRange);
|
||||
}
|
||||
|
||||
// Prompts caching random valid locations, up to a maximum number of attempts.
|
||||
public void cacheRandomLocations(final String name) {
|
||||
ess.getServer().getScheduler().scheduleSyncDelayedTask(ess, () -> {
|
||||
for (int i = 0; i < this.getFindAttempts(); ++i) {
|
||||
calculateRandomLocation(center, minRange, maxRange).thenAccept(location -> {
|
||||
calculateRandomLocation(getCenter(name), getMinRange(name), getMaxRange(name)).thenAccept(location -> {
|
||||
if (isValidRandomLocation(location)) {
|
||||
this.getCachedLocations().add(location);
|
||||
this.getCachedLocations(name).add(location);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -188,14 +216,18 @@ public class RandomTeleport implements IConf {
|
||||
return future;
|
||||
}
|
||||
|
||||
// Returns an appropriate elevation for a given location in the nether, or -1 if none is found
|
||||
// Returns an appropriate elevation for a given location in the nether, or MIN_VALUE if none is found
|
||||
private double getNetherYAt(final Location location) {
|
||||
for (int y = 32; y < ess.getWorldInfoProvider().getMaxHeight(location.getWorld()); ++y) {
|
||||
if (!LocationUtil.isBlockUnsafe(ess, location.getWorld(), location.getBlockX(), y, location.getBlockZ())) {
|
||||
final World world = location.getWorld();
|
||||
for (int y = 32; y < ess.getWorldInfoProvider().getMaxHeight(world); ++y) {
|
||||
if (Material.BEDROCK.equals(world.getBlockAt(location.getBlockX(), y, location.getBlockZ()).getType())) {
|
||||
break;
|
||||
}
|
||||
if (!LocationUtil.isBlockUnsafe(ess, world, location.getBlockX(), y, location.getBlockZ())) {
|
||||
return y;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
return Double.MIN_VALUE;
|
||||
}
|
||||
|
||||
private boolean isValidRandomLocation(final Location location) {
|
||||
@ -226,6 +258,10 @@ public class RandomTeleport implements IConf {
|
||||
return excluded.contains(biomeKey);
|
||||
}
|
||||
|
||||
private String locationKey(final String name, final String key) {
|
||||
return "locations." + name + "." + key;
|
||||
}
|
||||
|
||||
public File getFile() {
|
||||
return config.getFile();
|
||||
}
|
||||
|
@ -163,6 +163,16 @@ public class Settings implements net.ess3.api.ISettings {
|
||||
return config.getBoolean("respawn-at-home", false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRandomSpawnLocation() {
|
||||
return config.getString("random-spawn-location", "none");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRandomRespawnLocation() {
|
||||
return config.getString("random-respawn-location", "none");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRespawnAtAnchor() {
|
||||
return config.getBoolean("respawn-at-anchor", false);
|
||||
|
@ -5,7 +5,6 @@ import com.earth2me.essentials.config.EssentialsConfiguration;
|
||||
import com.earth2me.essentials.utils.AdventureUtil;
|
||||
import com.earth2me.essentials.utils.StringUtil;
|
||||
import net.ess3.api.InvalidNameException;
|
||||
import net.ess3.api.InvalidWorldException;
|
||||
import net.ess3.api.TranslatableException;
|
||||
import org.bukkit.Location;
|
||||
|
||||
@ -54,7 +53,7 @@ public class Warps implements IConf, net.ess3.api.IWarps {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getWarp(final String warp) throws WarpNotFoundException, InvalidWorldException {
|
||||
public Location getWarp(final String warp) throws WarpNotFoundException {
|
||||
final EssentialsConfiguration conf = warpPoints.get(new StringIgnoreCase(warp));
|
||||
if (conf == null) {
|
||||
throw new WarpNotFoundException();
|
||||
|
@ -22,9 +22,8 @@ public interface IWarps extends IConf {
|
||||
* @param warp - Warp name
|
||||
* @return - Location the warp is set to
|
||||
* @throws WarpNotFoundException When the warp is not found
|
||||
* @throws net.ess3.api.InvalidWorldException When the world the warp is in is not found
|
||||
*/
|
||||
Location getWarp(String warp) throws WarpNotFoundException, net.ess3.api.InvalidWorldException;
|
||||
Location getWarp(String warp) throws WarpNotFoundException;
|
||||
|
||||
/**
|
||||
* Checks if the provided name is a warp.
|
||||
|
@ -1,20 +0,0 @@
|
||||
package com.earth2me.essentials.api;
|
||||
|
||||
import net.ess3.api.TranslatableException;
|
||||
|
||||
/**
|
||||
* @deprecated This exception is unused. Use {@link net.ess3.api.InvalidWorldException} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public class InvalidWorldException extends TranslatableException {
|
||||
private final String world;
|
||||
|
||||
public InvalidWorldException(final String world) {
|
||||
super("invalidWorld");
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
public String getWorld() {
|
||||
return this.world;
|
||||
}
|
||||
}
|
@ -3,10 +3,12 @@ package com.earth2me.essentials.commands;
|
||||
import com.earth2me.essentials.RandomTeleport;
|
||||
import com.earth2me.essentials.User;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.World;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class Commandsettpr extends EssentialsCommand {
|
||||
public Commandsettpr() {
|
||||
@ -15,22 +17,20 @@ public class Commandsettpr extends EssentialsCommand {
|
||||
|
||||
@Override
|
||||
protected void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
if (args.length == 0) {
|
||||
if (args.length < 2) {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
|
||||
final RandomTeleport randomTeleport = ess.getRandomTeleport();
|
||||
randomTeleport.getCachedLocations().clear();
|
||||
if ("center".equalsIgnoreCase(args[0])) {
|
||||
randomTeleport.setCenter(user.getLocation());
|
||||
if ("center".equalsIgnoreCase(args[1])) {
|
||||
randomTeleport.setCenter(args[0], user.getLocation());
|
||||
user.sendTl("settpr");
|
||||
} else if (args.length > 1) {
|
||||
if ("minrange".equalsIgnoreCase(args[0])) {
|
||||
randomTeleport.setMinRange(Double.parseDouble(args[1]));
|
||||
} else if ("maxrange".equalsIgnoreCase(args[0])) {
|
||||
randomTeleport.setMaxRange(Double.parseDouble(args[1]));
|
||||
} else if (args.length > 2) {
|
||||
if ("minrange".equalsIgnoreCase(args[1])) {
|
||||
randomTeleport.setMinRange(args[0], Double.parseDouble(args[2]));
|
||||
} else if ("maxrange".equalsIgnoreCase(args[1])) {
|
||||
randomTeleport.setMaxRange(args[0], Double.parseDouble(args[2]));
|
||||
}
|
||||
user.sendTl("settprValue", args[0].toLowerCase(), args[1].toLowerCase());
|
||||
user.sendTl("settprValue", args[1].toLowerCase(), args[2].toLowerCase());
|
||||
} else {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
@ -39,6 +39,8 @@ public class Commandsettpr extends EssentialsCommand {
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(final Server server, final User user, final String commandLabel, final String[] args) {
|
||||
if (args.length == 1) {
|
||||
return user.getServer().getWorlds().stream().map(World::getName).collect(Collectors.toList());
|
||||
} else if (args.length == 2) {
|
||||
return Arrays.asList("center", "minrange", "maxrange");
|
||||
}
|
||||
return Collections.emptyList();
|
||||
|
@ -4,7 +4,6 @@ import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.api.IWarps;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import com.earth2me.essentials.utils.StringUtil;
|
||||
import net.ess3.api.InvalidWorldException;
|
||||
import net.ess3.api.TranslatableException;
|
||||
import net.essentialsx.api.v2.events.WarpModifyEvent;
|
||||
import org.bukkit.Bukkit;
|
||||
@ -31,7 +30,7 @@ public class Commandsetwarp extends EssentialsCommand {
|
||||
|
||||
try {
|
||||
warpLoc = warps.getWarp(args[0]);
|
||||
} catch (final WarpNotFoundException | InvalidWorldException ignored) {
|
||||
} catch (final WarpNotFoundException ignored) {
|
||||
}
|
||||
if (warpLoc == null) {
|
||||
final WarpModifyEvent event = new WarpModifyEvent(user, args[0], null, user.getLocation(), WarpModifyEvent.WarpModifyCause.CREATE);
|
||||
|
@ -1,8 +1,10 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.RandomTeleport;
|
||||
import com.earth2me.essentials.Trade;
|
||||
import com.earth2me.essentials.User;
|
||||
import net.ess3.api.TranslatableException;
|
||||
import net.ess3.api.events.UserRandomTeleportEvent;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
@ -10,6 +12,7 @@ import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class Commandtpr extends EssentialsCommand {
|
||||
|
||||
@ -22,25 +25,67 @@ public class Commandtpr extends EssentialsCommand {
|
||||
final Trade charge = new Trade(this.getName(), ess);
|
||||
charge.isAffordableFor(user);
|
||||
final RandomTeleport randomTeleport = ess.getRandomTeleport();
|
||||
final UserRandomTeleportEvent event = new UserRandomTeleportEvent(user, randomTeleport.getCenter(), randomTeleport.getMinRange(), randomTeleport.getMaxRange());
|
||||
final String defaultLocation = randomTeleport.getDefaultLocation().replace("{world}", user.getLocation().getWorld().getName());
|
||||
final String name = args.length > 0 ? args[0] : defaultLocation;
|
||||
final User userToTeleport = args.length > 1 && user.isAuthorized("essentials.tpr.others") ? getPlayer(server, user, args, 1) : user;
|
||||
if (randomTeleport.isPerLocationPermission() && !user.isAuthorized("essentials.tpr.location." + name)) {
|
||||
throw new TranslatableException("warpUsePermission");
|
||||
}
|
||||
final UserRandomTeleportEvent event = new UserRandomTeleportEvent(userToTeleport, name, randomTeleport.getCenter(name), randomTeleport.getMinRange(name), randomTeleport.getMaxRange(name));
|
||||
server.getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
randomTeleport.getRandomLocation(event.getCenter(), event.getMinRange(), event.getMaxRange()).thenAccept(location -> {
|
||||
(event.isModified() ? randomTeleport.getRandomLocation(event.getCenter(), event.getMinRange(), event.getMaxRange()) : randomTeleport.getRandomLocation(name))
|
||||
.thenAccept(location -> {
|
||||
final CompletableFuture<Boolean> future = getNewExceptionFuture(user.getSource(), commandLabel);
|
||||
user.getAsyncTeleport().teleport(location, charge, PlayerTeleportEvent.TeleportCause.COMMAND, future);
|
||||
future.thenAccept(success -> {
|
||||
if (success) {
|
||||
user.sendTl("tprSuccess");
|
||||
userToTeleport.sendTl("tprSuccess");
|
||||
}
|
||||
});
|
||||
userToTeleport.getAsyncTeleport().teleport(location, charge, PlayerTeleportEvent.TeleportCause.COMMAND, future);
|
||||
});
|
||||
throw new NoChargeException();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(final Server server, final User user, final String commandLabel, final String[] args) {
|
||||
protected void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
if (args.length < 2) {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
final RandomTeleport randomTeleport = ess.getRandomTeleport();
|
||||
final User userToTeleport = getPlayer(server, sender, args, 1);
|
||||
final String name = args[0];
|
||||
final UserRandomTeleportEvent event = new UserRandomTeleportEvent(userToTeleport, name, randomTeleport.getCenter(name), randomTeleport.getMinRange(name), randomTeleport.getMaxRange(name));
|
||||
server.getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
(event.isModified() ? randomTeleport.getRandomLocation(event.getCenter(), event.getMinRange(), event.getMaxRange()) : randomTeleport.getRandomLocation(name))
|
||||
.thenAccept(location -> {
|
||||
final CompletableFuture<Boolean> future = getNewExceptionFuture(sender, commandLabel);
|
||||
future.thenAccept(success -> {
|
||||
if (success) {
|
||||
userToTeleport.sendTl("tprSuccess");
|
||||
}
|
||||
});
|
||||
userToTeleport.getAsyncTeleport().now(location, false, PlayerTeleportEvent.TeleportCause.COMMAND, future);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
|
||||
final RandomTeleport randomTeleport = ess.getRandomTeleport();
|
||||
if (args.length == 1) {
|
||||
if (randomTeleport.isPerLocationPermission()) {
|
||||
return randomTeleport.listLocations().stream().filter(name -> sender.isAuthorized("essentials.tpr.location." + name)).collect(Collectors.toList());
|
||||
} else {
|
||||
return randomTeleport.listLocations();
|
||||
}
|
||||
} else if (args.length == 2 && sender.isAuthorized("essentials.tpr.others")) {
|
||||
return getPlayers(server, sender);
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,6 @@ import com.earth2me.essentials.config.serializers.LocationTypeSerializer;
|
||||
import com.earth2me.essentials.config.serializers.MailMessageSerializer;
|
||||
import com.earth2me.essentials.config.serializers.MaterialTypeSerializer;
|
||||
import com.earth2me.essentials.utils.AdventureUtil;
|
||||
import net.ess3.api.InvalidWorldException;
|
||||
import net.essentialsx.api.v2.services.mail.MailMessage;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
@ -123,7 +122,7 @@ public class EssentialsConfiguration {
|
||||
setInternal(path, LazyLocation.fromLocation(location));
|
||||
}
|
||||
|
||||
public LazyLocation getLocation(final String path) throws InvalidWorldException {
|
||||
public LazyLocation getLocation(final String path) {
|
||||
final CommentedConfigurationNode node = path == null ? getRootNode() : getSection(path);
|
||||
if (node == null) {
|
||||
return null;
|
||||
|
@ -0,0 +1,32 @@
|
||||
package com.earth2me.essentials.signs;
|
||||
|
||||
import com.earth2me.essentials.ChargeException;
|
||||
import com.earth2me.essentials.RandomTeleport;
|
||||
import com.earth2me.essentials.User;
|
||||
import net.ess3.api.IEssentials;
|
||||
import net.ess3.api.MaxMoneyException;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class SignRandomTeleport extends EssentialsSign {
|
||||
public SignRandomTeleport() {
|
||||
super("RandomTeleport");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean onSignInteract(ISign sign, User player, String username, IEssentials ess) throws SignException, ChargeException, MaxMoneyException {
|
||||
final String name = sign.getLine(1);
|
||||
final RandomTeleport randomTeleport = ess.getRandomTeleport();
|
||||
randomTeleport.getRandomLocation(name).thenAccept(location -> {
|
||||
final CompletableFuture<Boolean> future = new CompletableFuture<>();
|
||||
future.thenAccept(success -> {
|
||||
if (success) {
|
||||
player.sendTl("tprSuccess");
|
||||
}
|
||||
});
|
||||
player.getAsyncTeleport().now(location, false, PlayerTeleportEvent.TeleportCause.COMMAND, future);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
}
|
@ -25,7 +25,8 @@ public enum Signs {
|
||||
TRADE(new SignTrade()),
|
||||
WARP(new SignWarp()),
|
||||
WEATHER(new SignWeather()),
|
||||
WORKBENCH(new SignWorkbench());
|
||||
WORKBENCH(new SignWorkbench()),
|
||||
RANDOMTELEPORT(new SignRandomTeleport());
|
||||
private final EssentialsSign sign;
|
||||
|
||||
Signs(final EssentialsSign sign) {
|
||||
|
@ -1,18 +0,0 @@
|
||||
package net.ess3.api;
|
||||
|
||||
/**
|
||||
* Fired when trying to teleport a user to an invalid world. This usually only occurs if a world has been removed from
|
||||
* the server and a player tries to teleport to a warp or home in that world.
|
||||
*/
|
||||
public class InvalidWorldException extends TranslatableException {
|
||||
private final String world;
|
||||
|
||||
public InvalidWorldException(final String world) {
|
||||
super("invalidWorld");
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
public String getWorld() {
|
||||
return this.world;
|
||||
}
|
||||
}
|
@ -14,14 +14,17 @@ public class UserRandomTeleportEvent extends Event implements Cancellable {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
||||
private final IUser user;
|
||||
private String name;
|
||||
private Location center;
|
||||
private double minRange;
|
||||
private double maxRange;
|
||||
private boolean cancelled = false;
|
||||
private boolean modified = false;
|
||||
|
||||
public UserRandomTeleportEvent(final IUser user, final Location center, final double minRange, final double maxRange) {
|
||||
public UserRandomTeleportEvent(final IUser user, final String name, final Location center, final double minRange, final double maxRange) {
|
||||
super(!Bukkit.isPrimaryThread());
|
||||
this.user = user;
|
||||
this.name = name;
|
||||
this.center = center;
|
||||
this.minRange = minRange;
|
||||
this.maxRange = maxRange;
|
||||
@ -35,11 +38,23 @@ public class UserRandomTeleportEvent extends Event implements Cancellable {
|
||||
return user;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Location getCenter() {
|
||||
return center;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the center location to teleport from.
|
||||
*
|
||||
* @param center Center location.
|
||||
*/
|
||||
public void setCenter(final Location center) {
|
||||
if (!this.center.equals(center)) {
|
||||
modified = true;
|
||||
}
|
||||
this.center = center;
|
||||
}
|
||||
|
||||
@ -47,7 +62,15 @@ public class UserRandomTeleportEvent extends Event implements Cancellable {
|
||||
return minRange;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the minimum range for the teleport.
|
||||
*
|
||||
* @param minRange Minimum range.
|
||||
*/
|
||||
public void setMinRange(final double minRange) {
|
||||
if (this.minRange != minRange) {
|
||||
modified = true;
|
||||
}
|
||||
this.minRange = minRange;
|
||||
}
|
||||
|
||||
@ -55,7 +78,15 @@ public class UserRandomTeleportEvent extends Event implements Cancellable {
|
||||
return maxRange;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum range for the teleport.
|
||||
*
|
||||
* @param maxRange Maximum range.
|
||||
*/
|
||||
public void setMaxRange(final double maxRange) {
|
||||
if (this.maxRange != maxRange) {
|
||||
modified = true;
|
||||
}
|
||||
this.maxRange = maxRange;
|
||||
}
|
||||
|
||||
@ -69,6 +100,10 @@ public class UserRandomTeleportEvent extends Event implements Cancellable {
|
||||
cancelled = b;
|
||||
}
|
||||
|
||||
public boolean isModified() {
|
||||
return modified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
|
@ -387,6 +387,7 @@ enabledSigns:
|
||||
#- loom
|
||||
#- smithing
|
||||
#- workbench
|
||||
#- randomteleport
|
||||
|
||||
# How many times per second can Essentials signs be interacted with per player.
|
||||
# Values should be between 1-20, 20 being virtually no lag protection.
|
||||
@ -1197,6 +1198,12 @@ respawn-at-home-bed: true
|
||||
# When users die, should EssentialsSpawn respect users' respawn anchors?
|
||||
respawn-at-anchor: false
|
||||
|
||||
# If configured, users will spawn at the random spawn location instead of the newbies spawnpoint.
|
||||
random-spawn-location: "none"
|
||||
|
||||
# If configured, when users die, they will respawn at the random respawn location.
|
||||
random-respawn-location: "none"
|
||||
|
||||
# Teleport all joining players to the spawnpoint
|
||||
spawn-on-join: false
|
||||
# The following value of `guests` states that all players in group `guests` will be teleported to spawn when joining.
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Configuration for the random teleport command.
|
||||
# Some settings may be defaulted, and can be changed via the /settpr command in-game.
|
||||
min-range: 0.0
|
||||
default-location: '{world}'
|
||||
excluded-biomes:
|
||||
- cold_ocean
|
||||
- deep_cold_ocean
|
||||
|
@ -12,6 +12,7 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Listener;
|
||||
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 java.util.List;
|
||||
@ -64,6 +65,9 @@ class EssentialsSpawnPlayerListener implements Listener {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (tryRandomTeleport(user, ess.getSettings().getRandomRespawnLocation())) {
|
||||
return;
|
||||
}
|
||||
final Location spawn = spawns.getSpawn(user.getGroup());
|
||||
if (spawn != null) {
|
||||
event.setRespawnLocation(spawn);
|
||||
@ -102,7 +106,9 @@ class EssentialsSpawnPlayerListener implements Listener {
|
||||
|
||||
final User user = ess.getUser(player);
|
||||
|
||||
if (!"none".equalsIgnoreCase(ess.getSettings().getNewbieSpawn())) {
|
||||
final boolean spawnRandomly = tryRandomTeleport(user, ess.getSettings().getRandomSpawnLocation());
|
||||
|
||||
if (!spawnRandomly && !"none".equalsIgnoreCase(ess.getSettings().getNewbieSpawn())) {
|
||||
ess.scheduleSyncDelayedTask(new NewPlayerTeleport(user), 1L);
|
||||
}
|
||||
|
||||
@ -158,4 +164,15 @@ class EssentialsSpawnPlayerListener implements Listener {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean tryRandomTeleport(final User user, final String name) {
|
||||
if (!ess.getRandomTeleport().hasLocation(name)) {
|
||||
return false;
|
||||
}
|
||||
ess.getRandomTeleport().getRandomLocation(name).thenAccept(location -> {
|
||||
final CompletableFuture<Boolean> future = new CompletableFuture<>();
|
||||
user.getAsyncTeleport().now(location, false, PlayerTeleportEvent.TeleportCause.PLUGIN, future);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user