mirror of
https://github.com/Multiverse/Multiverse-Core.git
synced 2025-02-10 17:41:52 +01:00
Move entrycheck, playerlistener and worldnamechecker to api
This commit is contained in:
parent
d77d7032dd
commit
dc75e87223
@ -19,7 +19,7 @@ import com.onarandombox.MultiverseCore.display.filters.DefaultContentFilter;
|
||||
import com.onarandombox.MultiverseCore.display.filters.RegexContentFilter;
|
||||
import com.onarandombox.MultiverseCore.display.handlers.PagedSendHandler;
|
||||
import com.onarandombox.MultiverseCore.display.parsers.ListContentProvider;
|
||||
import com.onarandombox.MultiverseCore.world.entrycheck.WorldEntryCheckerProvider;
|
||||
import com.onarandombox.MultiverseCore.worldnew.entrycheck.WorldEntryCheckerProvider;
|
||||
import com.onarandombox.MultiverseCore.worldnew.MVWorld;
|
||||
import com.onarandombox.MultiverseCore.worldnew.WorldManager;
|
||||
import jakarta.inject.Inject;
|
||||
|
@ -1,6 +1,6 @@
|
||||
package com.onarandombox.MultiverseCore.economy;
|
||||
|
||||
import com.onarandombox.MultiverseCore.api.MVWorld;
|
||||
import com.onarandombox.MultiverseCore.worldnew.MVWorld;
|
||||
import jakarta.inject.Inject;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
|
@ -7,25 +7,24 @@
|
||||
|
||||
package com.onarandombox.MultiverseCore.listeners;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.api.MVWorld;
|
||||
import com.onarandombox.MultiverseCore.api.MVWorldManager;
|
||||
import com.onarandombox.MultiverseCore.api.SafeTTeleporter;
|
||||
import com.onarandombox.MultiverseCore.commandtools.MVCommandManager;
|
||||
import com.onarandombox.MultiverseCore.config.MVCoreConfig;
|
||||
import com.onarandombox.MultiverseCore.destination.DestinationsProvider;
|
||||
import com.onarandombox.MultiverseCore.destination.ParsedDestination;
|
||||
import com.onarandombox.MultiverseCore.economy.MVEconomist;
|
||||
import com.onarandombox.MultiverseCore.event.MVRespawnEvent;
|
||||
import com.onarandombox.MultiverseCore.inject.InjectableListener;
|
||||
import com.onarandombox.MultiverseCore.permissions.CorePermissionsChecker;
|
||||
import com.onarandombox.MultiverseCore.teleportation.TeleportQueue;
|
||||
import com.onarandombox.MultiverseCore.utils.result.ResultChain;
|
||||
import com.onarandombox.MultiverseCore.world.entrycheck.EntryFeeResult;
|
||||
import com.onarandombox.MultiverseCore.world.entrycheck.WorldEntryCheckerProvider;
|
||||
import com.onarandombox.MultiverseCore.worldnew.MVWorld;
|
||||
import com.onarandombox.MultiverseCore.worldnew.WorldManager;
|
||||
import com.onarandombox.MultiverseCore.worldnew.entrycheck.EntryFeeResult;
|
||||
import com.onarandombox.MultiverseCore.worldnew.entrycheck.WorldEntryCheckerProvider;
|
||||
import io.vavr.control.Option;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Provider;
|
||||
import org.bukkit.GameMode;
|
||||
@ -45,6 +44,10 @@ import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.jvnet.hk2.annotations.Service;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Multiverse's Listener for players.
|
||||
*/
|
||||
@ -52,7 +55,7 @@ import org.jvnet.hk2.annotations.Service;
|
||||
public class MVPlayerListener implements InjectableListener {
|
||||
private final Plugin plugin;
|
||||
private final MVCoreConfig config;
|
||||
private final Provider<MVWorldManager> worldManagerProvider;
|
||||
private final Provider<WorldManager> worldManagerProvider;
|
||||
private final SafeTTeleporter safeTTeleporter;
|
||||
private final Server server;
|
||||
private final TeleportQueue teleportQueue;
|
||||
@ -60,6 +63,7 @@ public class MVPlayerListener implements InjectableListener {
|
||||
private final WorldEntryCheckerProvider worldEntryCheckerProvider;
|
||||
private final Provider<MVCommandManager> commandManagerProvider;
|
||||
private final CorePermissionsChecker permissionsChecker;
|
||||
private final DestinationsProvider destinationsProvider;
|
||||
|
||||
private final Map<String, String> playerWorld = new ConcurrentHashMap<String, String>();
|
||||
|
||||
@ -67,14 +71,15 @@ public class MVPlayerListener implements InjectableListener {
|
||||
public MVPlayerListener(
|
||||
MultiverseCore plugin,
|
||||
MVCoreConfig config,
|
||||
Provider<MVWorldManager> worldManagerProvider,
|
||||
Provider<WorldManager> worldManagerProvider,
|
||||
SafeTTeleporter safeTTeleporter,
|
||||
Server server,
|
||||
TeleportQueue teleportQueue,
|
||||
MVEconomist economist,
|
||||
WorldEntryCheckerProvider worldEntryCheckerProvider,
|
||||
Provider<MVCommandManager> commandManagerProvider,
|
||||
CorePermissionsChecker permissionsChecker
|
||||
CorePermissionsChecker permissionsChecker,
|
||||
DestinationsProvider destinationsProvider
|
||||
) {
|
||||
this.plugin = plugin;
|
||||
this.config = config;
|
||||
@ -86,9 +91,10 @@ public class MVPlayerListener implements InjectableListener {
|
||||
this.worldEntryCheckerProvider = worldEntryCheckerProvider;
|
||||
this.commandManagerProvider = commandManagerProvider;
|
||||
this.permissionsChecker = permissionsChecker;
|
||||
this.destinationsProvider = destinationsProvider;
|
||||
}
|
||||
|
||||
private MVWorldManager getWorldManager() {
|
||||
private WorldManager getWorldManager() {
|
||||
return worldManagerProvider.get();
|
||||
}
|
||||
|
||||
@ -110,7 +116,7 @@ public class MVPlayerListener implements InjectableListener {
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void playerRespawn(PlayerRespawnEvent event) {
|
||||
World world = event.getPlayer().getWorld();
|
||||
MVWorld mvWorld = getWorldManager().getMVWorld(world.getName());
|
||||
MVWorld mvWorld = getWorldManager().getMVWorld(world.getName()).getOrNull();
|
||||
// If it's not a World MV manages we stop.
|
||||
if (mvWorld == null) {
|
||||
return;
|
||||
@ -123,14 +129,14 @@ public class MVPlayerListener implements InjectableListener {
|
||||
|
||||
// Get the instance of the World the player should respawn at.
|
||||
MVWorld respawnWorld = null;
|
||||
if (getWorldManager().isMVWorld(mvWorld.getRespawnToWorld())) {
|
||||
respawnWorld = getWorldManager().getMVWorld(mvWorld.getRespawnToWorld());
|
||||
if (getWorldManager().isMVWorld(mvWorld.getRespawnWorld())) {
|
||||
respawnWorld = getWorldManager().getMVWorld(mvWorld.getRespawnWorld()).getOrNull();
|
||||
}
|
||||
|
||||
// If it's null then it either means the World doesn't exist or the value is blank, so we don't handle it.
|
||||
// NOW: We'll always handle it to get more accurate spawns
|
||||
if (respawnWorld != null) {
|
||||
world = respawnWorld.getCBWorld();
|
||||
world = respawnWorld.getBukkitWorld().getOrNull();
|
||||
}
|
||||
// World has been set to the appropriate world
|
||||
Location respawnLocation = getMostAccurateRespawnLocation(world);
|
||||
@ -141,7 +147,7 @@ public class MVPlayerListener implements InjectableListener {
|
||||
}
|
||||
|
||||
private Location getMostAccurateRespawnLocation(World w) {
|
||||
MVWorld mvw = getWorldManager().getMVWorld(w.getName());
|
||||
MVWorld mvw = getWorldManager().getMVWorld(w.getName()).getOrNull();
|
||||
if (mvw != null) {
|
||||
return mvw.getSpawnLocation();
|
||||
}
|
||||
@ -154,26 +160,33 @@ public class MVPlayerListener implements InjectableListener {
|
||||
*/
|
||||
@EventHandler
|
||||
public void playerJoin(PlayerJoinEvent event) {
|
||||
Player p = event.getPlayer();
|
||||
if (!p.hasPlayedBefore()) {
|
||||
Logging.finer("Player joined for the FIRST time!");
|
||||
if (config.getFirstSpawnOverride()) {
|
||||
Logging.fine("Moving NEW player to(firstspawnoverride): "
|
||||
+ getWorldManager().getFirstSpawnWorld().getSpawnLocation());
|
||||
this.sendPlayerToDefaultWorld(p);
|
||||
}
|
||||
Player player = event.getPlayer();
|
||||
MVWorld world = getWorldManager().getMVWorld(player.getWorld()).getOrNull();
|
||||
if (world == null) {
|
||||
Logging.finer("Player joined in a world that is not managed by Multiverse.");
|
||||
return;
|
||||
} else {
|
||||
Logging.finer("Player joined AGAIN!");
|
||||
if (config.getEnforceAccess() // check this only if we're enforcing access!
|
||||
&& !permissionsChecker.hasWorldAccessPermission(p, getWorldManager().getFirstSpawnWorld())) {
|
||||
p.sendMessage("[MV] - Sorry you can't be in this world anymore!");
|
||||
this.sendPlayerToDefaultWorld(p);
|
||||
}
|
||||
}
|
||||
|
||||
Option.of(destinationsProvider.parseDestination(config.getFirstSpawnLocation()))
|
||||
.peek(parsedDestination -> {
|
||||
if (!player.hasPlayedBefore()) {
|
||||
Logging.finer("Player joined for the FIRST time!");
|
||||
if (config.getFirstSpawnOverride()) {
|
||||
Logging.fine("Moving NEW player to(firstspawnoverride): %s", config.getFirstSpawnLocation());
|
||||
this.sendPlayerToDefaultWorld(player, parsedDestination);
|
||||
}
|
||||
} else {
|
||||
Logging.finer("Player joined AGAIN!");
|
||||
if (worldEntryCheckerProvider.forSender(player).canAccessWorld(world).isFailure()) {
|
||||
player.sendMessage("[MV] - Sorry you can't be in this world anymore!");
|
||||
this.sendPlayerToDefaultWorld(player, parsedDestination);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Handle the Players GameMode setting for the new world.
|
||||
this.handleGameModeAndFlight(event.getPlayer(), event.getPlayer().getWorld());
|
||||
playerWorld.put(p.getName(), p.getWorld().getName());
|
||||
playerWorld.put(player.getName(), player.getWorld().getName());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -213,8 +226,8 @@ public class MVPlayerListener implements InjectableListener {
|
||||
}
|
||||
Logging.finer("Inferred sender '" + teleporter + "' from name '"
|
||||
+ teleporterName + "', fetched from name '" + teleportee.getName() + "'");
|
||||
MVWorld fromWorld = getWorldManager().getMVWorld(event.getFrom().getWorld().getName());
|
||||
MVWorld toWorld = getWorldManager().getMVWorld(event.getTo().getWorld().getName());
|
||||
MVWorld fromWorld = getWorldManager().getMVWorld(event.getFrom().getWorld().getName()).getOrNull();
|
||||
MVWorld toWorld = getWorldManager().getMVWorld(event.getTo().getWorld().getName()).getOrNull();
|
||||
if (toWorld == null) {
|
||||
Logging.fine("Player '" + teleportee.getName() + "' is teleporting to world '"
|
||||
+ event.getTo().getWorld().getName() + "' which is not managed by Multiverse-Core. No further "
|
||||
@ -291,8 +304,8 @@ public class MVPlayerListener implements InjectableListener {
|
||||
event.setSearchRadius(config.getCustomPortalSearchRadius());
|
||||
}
|
||||
|
||||
MVWorld fromWorld = getWorldManager().getMVWorld(event.getFrom().getWorld().getName());
|
||||
MVWorld toWorld = getWorldManager().getMVWorld(event.getTo().getWorld().getName());
|
||||
MVWorld fromWorld = getWorldManager().getMVWorld(event.getFrom().getWorld().getName()).getOrNull();
|
||||
MVWorld toWorld = getWorldManager().getMVWorld(event.getTo().getWorld().getName()).getOrNull();
|
||||
if (event.getFrom().getWorld().equals(event.getTo().getWorld())) {
|
||||
// The player is Portaling to the same world.
|
||||
Logging.finer("Player '" + event.getPlayer().getName() + "' is portaling to the same world.");
|
||||
@ -308,13 +321,13 @@ public class MVPlayerListener implements InjectableListener {
|
||||
Logging.fine("Teleport result: %s", entryResult);
|
||||
}
|
||||
|
||||
private void sendPlayerToDefaultWorld(final Player player) {
|
||||
private void sendPlayerToDefaultWorld(final Player player, ParsedDestination parsedDestination) {
|
||||
// Remove the player 1 tick after the login. I'm sure there's GOT to be a better way to do this...
|
||||
this.server.getScheduler().scheduleSyncDelayedTask(this.plugin,
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
player.teleport(getWorldManager().getFirstSpawnWorld().getSpawnLocation());
|
||||
safeTTeleporter.safelyTeleportAsync(getCommandManager().getCommandIssuer(player), player, parsedDestination);
|
||||
}
|
||||
}, 1L);
|
||||
}
|
||||
@ -322,7 +335,7 @@ public class MVPlayerListener implements InjectableListener {
|
||||
// FOLLOWING 2 Methods and Private class handle Per Player GameModes.
|
||||
private void handleGameModeAndFlight(Player player, World world) {
|
||||
|
||||
MVWorld mvWorld = getWorldManager().getMVWorld(world.getName());
|
||||
MVWorld mvWorld = getWorldManager().getMVWorld(world.getName()).getOrNull();
|
||||
if (mvWorld != null) {
|
||||
this.handleGameModeAndFlight(player, mvWorld);
|
||||
} else {
|
||||
@ -345,7 +358,7 @@ public class MVPlayerListener implements InjectableListener {
|
||||
public void run() {
|
||||
if (!permissionsChecker.hasGameModeBypassPermission(player, world)) {
|
||||
// Check that the player is in the new world and they haven't been teleported elsewhere or the event cancelled.
|
||||
if (player.getWorld() == world.getCBWorld()) {
|
||||
if (player.getWorld() == world.getBukkitWorld().getOrNull()) {
|
||||
Logging.fine("Handling gamemode for player: %s, Changing to %s", player.getName(), world.getGameMode().toString());
|
||||
Logging.finest("From World: %s", player.getWorld());
|
||||
Logging.finest("To World: %s", world);
|
||||
|
@ -1,7 +1,7 @@
|
||||
package com.onarandombox.MultiverseCore.permissions;
|
||||
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
import com.onarandombox.MultiverseCore.api.MVWorld;
|
||||
import com.onarandombox.MultiverseCore.worldnew.MVWorld;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jvnet.hk2.annotations.Service;
|
||||
@ -12,6 +12,11 @@ public class CorePermissionsChecker {
|
||||
return hasPermission(sender, concatPermission(CorePermissions.WORLD_ACCESS, world.getName()));
|
||||
}
|
||||
|
||||
@Deprecated // TODO: Remove old MVWorld
|
||||
public boolean hasWorldAccessPermission(@NotNull CommandSender sender, @NotNull com.onarandombox.MultiverseCore.api.MVWorld world) {
|
||||
return hasPermission(sender, concatPermission(CorePermissions.WORLD_ACCESS, world.getName()));
|
||||
}
|
||||
|
||||
public boolean hasWorldExemptPermission(@NotNull CommandSender sender, @NotNull MVWorld world) {
|
||||
return hasPermission(sender, concatPermission(CorePermissions.WORLD_EXEMPT, world.getName()));
|
||||
}
|
||||
@ -24,6 +29,11 @@ public class CorePermissionsChecker {
|
||||
return hasPermission(sender, concatPermission(CorePermissions.GAMEMODE_BYPASS, world.getName()));
|
||||
}
|
||||
|
||||
@Deprecated // TODO: Remove old MVWorld
|
||||
public boolean hasGameModeBypassPermission(@NotNull CommandSender sender, @NotNull com.onarandombox.MultiverseCore.api.MVWorld world) {
|
||||
return hasPermission(sender, concatPermission(CorePermissions.GAMEMODE_BYPASS, world.getName()));
|
||||
}
|
||||
|
||||
private String concatPermission(String permission, String...child) {
|
||||
return permission + "." + String.join(".", child);
|
||||
}
|
||||
|
@ -342,7 +342,7 @@ public class SimpleMVWorld implements MVWorld {
|
||||
for (Player p : server.getWorld(getName()).getPlayers()) {
|
||||
Logging.finer(String.format("Setting %s's GameMode to %s",
|
||||
p.getName(), newValue.toString()));
|
||||
playerListener.handleGameModeAndFlight(p, SimpleMVWorld.this);
|
||||
//playerListener.handleGameModeAndFlight(p, SimpleMVWorld.this);
|
||||
}
|
||||
return super.validateChange(property, newValue, oldValue, object);
|
||||
}
|
||||
|
@ -7,6 +7,8 @@ import io.vavr.control.Try;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Difficulty;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@ -86,6 +88,22 @@ public class OfflineWorld {
|
||||
return worldConfig.setAutoLoad(autoLoad);
|
||||
}
|
||||
|
||||
public boolean getBedRespawn() {
|
||||
return worldConfig.getBedRespawn();
|
||||
}
|
||||
|
||||
public Try<Void> setBedRespawn(boolean bedRespawn) {
|
||||
return worldConfig.setBedRespawn(bedRespawn);
|
||||
}
|
||||
|
||||
public Material getCurrency() {
|
||||
return worldConfig.getEntryFeeCurrency();
|
||||
}
|
||||
|
||||
public Try<Void> setCurrency(Material currency) {
|
||||
return worldConfig.setEntryFeeCurrency(currency);
|
||||
}
|
||||
|
||||
public Difficulty getDifficulty() {
|
||||
return worldConfig.getDifficulty();
|
||||
}
|
||||
@ -150,6 +168,14 @@ public class OfflineWorld {
|
||||
return worldConfig.setPortalForm(portalForm);
|
||||
}
|
||||
|
||||
public double getPrice() {
|
||||
return worldConfig.getEntryFeeAmount();
|
||||
}
|
||||
|
||||
public Try<Void> setPrice(double price) {
|
||||
return worldConfig.setEntryFeeAmount(price);
|
||||
}
|
||||
|
||||
public boolean getPvp() {
|
||||
return worldConfig.getPvp();
|
||||
}
|
||||
@ -190,6 +216,14 @@ public class OfflineWorld {
|
||||
return worldConfig.getSeed();
|
||||
}
|
||||
|
||||
public Location getSpawnLocation() {
|
||||
return worldConfig.getSpawnLocation();
|
||||
}
|
||||
|
||||
public Try<Void> setSpawnLocation(Location spawnLocation) {
|
||||
return worldConfig.setSpawnLocation(spawnLocation);
|
||||
}
|
||||
|
||||
public List<String> getWorldBlacklist() {
|
||||
return worldConfig.getWorldBlacklist();
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import com.dumptruckman.minecraft.util.Logging;
|
||||
import com.google.common.base.Strings;
|
||||
import com.onarandombox.MultiverseCore.utils.file.FileUtils;
|
||||
import com.onarandombox.MultiverseCore.utils.result.Result;
|
||||
import com.onarandombox.MultiverseCore.world.WorldNameChecker;
|
||||
import com.onarandombox.MultiverseCore.worldnew.config.WorldConfig;
|
||||
import com.onarandombox.MultiverseCore.worldnew.config.WorldsConfigManager;
|
||||
import com.onarandombox.MultiverseCore.worldnew.options.CreateWorldOptions;
|
||||
@ -34,12 +33,14 @@ public class WorldManager {
|
||||
private final Map<String, OfflineWorld> offlineWorldsMap;
|
||||
private final Map<String, MVWorld> worldsMap;
|
||||
private final WorldsConfigManager worldsConfigManager;
|
||||
private final WorldNameChecker worldNameChecker;
|
||||
|
||||
@Inject
|
||||
WorldManager(@NotNull WorldsConfigManager worldsConfigManager) {
|
||||
WorldManager(@NotNull WorldsConfigManager worldsConfigManager, @NotNull WorldNameChecker worldNameChecker) {
|
||||
this.offlineWorldsMap = new HashMap<>();
|
||||
this.worldsMap = new HashMap<>();
|
||||
this.worldsConfigManager = worldsConfigManager;
|
||||
this.worldNameChecker = worldNameChecker;
|
||||
}
|
||||
|
||||
public void initAllWorlds() {
|
||||
@ -88,7 +89,7 @@ public class WorldManager {
|
||||
* @param options The options for customizing the creation of a new world.
|
||||
*/
|
||||
public Result<CreateWorldResult.Success, CreateWorldResult.Failure> createWorld(CreateWorldOptions options) {
|
||||
if (!WorldNameChecker.isValidWorldName(options.worldName())) {
|
||||
if (!worldNameChecker.isValidWorldName(options.worldName())) {
|
||||
return Result.failure(CreateWorldResult.Failure.INVALID_WORLDNAME);
|
||||
}
|
||||
|
||||
@ -127,7 +128,7 @@ public class WorldManager {
|
||||
}
|
||||
|
||||
public Result<CreateWorldResult.Success, CreateWorldResult.Failure> importWorld(ImportWorldOptions options) {
|
||||
if (!WorldNameChecker.isValidWorldName(options.worldName())) {
|
||||
if (!worldNameChecker.isValidWorldName(options.worldName())) {
|
||||
return Result.failure(CreateWorldResult.Failure.INVALID_WORLDNAME);
|
||||
}
|
||||
|
||||
@ -258,7 +259,7 @@ public class WorldManager {
|
||||
|
||||
public Result<DeleteWorldResult.Success, UnloadWorldResult.Failure> deleteWorld(@NotNull MVWorld world) {
|
||||
File worldFolder = world.getBukkitWorld().map(World::getWorldFolder).getOrNull();
|
||||
if (worldFolder == null || !WorldNameChecker.isValidWorldFolder(worldFolder)) {
|
||||
if (worldFolder == null || !worldNameChecker.isValidWorldFolder(worldFolder)) {
|
||||
Logging.severe("Failed to get world folder for world: " + world.getName());
|
||||
return Result.failure(DeleteWorldResult.Failure.WORLD_FOLDER_NOT_FOUND);
|
||||
}
|
||||
@ -314,6 +315,10 @@ public class WorldManager {
|
||||
return worldsMap.values();
|
||||
}
|
||||
|
||||
public boolean isMVWorld(@Nullable World world) {
|
||||
return world != null && isMVWorld(world.getName());
|
||||
}
|
||||
|
||||
public boolean isMVWorld(@Nullable OfflineWorld world) {
|
||||
return world != null && isMVWorld(world.getName());
|
||||
}
|
||||
|
@ -0,0 +1,154 @@
|
||||
package com.onarandombox.MultiverseCore.worldnew;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jvnet.hk2.annotations.Service;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* <p>Utility class in helping to check the status of a world name and it's associated world folder.</p>
|
||||
*
|
||||
* <p>Note this is for preliminary checks and better command output. A valid result will suggest but not
|
||||
* 100% determine that a world name can be created, loaded or imported.</p>
|
||||
*/
|
||||
@Service
|
||||
public class WorldNameChecker {
|
||||
|
||||
private static final Pattern WORLD_NAME_PATTERN = Pattern.compile("[a-zA-Z0-9/._-]+");
|
||||
private static final Set<String> BLACKLIST_NAMES = Set.of("plugins", "logs", "cache", "crash-reports"); // TODO: Configurable blacklist names
|
||||
|
||||
/**
|
||||
* Checks if a world name is valid.
|
||||
*
|
||||
* @param worldName The world name to check on.
|
||||
* @return True if check result is valid, else false.
|
||||
*/
|
||||
public boolean isValidWorldName(@Nullable String worldName) {
|
||||
return checkName(worldName) == NameStatus.VALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the current validity status of a world name.
|
||||
*
|
||||
* @param worldName The world name to check on.
|
||||
* @return The resulting name status.
|
||||
*/
|
||||
@NotNull
|
||||
public NameStatus checkName(@Nullable String worldName) {
|
||||
if (BLACKLIST_NAMES.contains(worldName)) {
|
||||
return NameStatus.BLACKLISTED;
|
||||
}
|
||||
if (worldName == null || !WORLD_NAME_PATTERN.matcher(worldName).matches()) {
|
||||
return NameStatus.INVALID_CHARS;
|
||||
}
|
||||
return NameStatus.VALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a world name has a valid world folder.
|
||||
*
|
||||
* @param worldName The world name to check on.
|
||||
* @return True if check result is valid, else false.
|
||||
*/
|
||||
public boolean isValidWorldFolder(@Nullable String worldName) {
|
||||
return checkFolder(worldName) == FolderStatus.VALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a world folder is valid.
|
||||
*
|
||||
* @param worldFolder The world folder to check on.
|
||||
* @return True if check result is valid, else false.
|
||||
*/
|
||||
public boolean isValidWorldFolder(@Nullable File worldFolder) {
|
||||
return checkFolder(worldFolder) == FolderStatus.VALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the current folder status for a world name.
|
||||
*
|
||||
* @param worldName The world name to check on.
|
||||
* @return The resulting folder status.
|
||||
*/
|
||||
@NotNull
|
||||
public FolderStatus checkFolder(@Nullable String worldName) {
|
||||
if (worldName == null) {
|
||||
return FolderStatus.DOES_NOT_EXIST;
|
||||
}
|
||||
File worldFolder = new File(Bukkit.getWorldContainer(), worldName);
|
||||
return checkFolder(worldFolder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the current folder status.
|
||||
*
|
||||
* @param worldFolder The world folder to check on.
|
||||
* @return The resulting folder status.
|
||||
*/
|
||||
@NotNull
|
||||
public FolderStatus checkFolder(@Nullable File worldFolder) {
|
||||
if (worldFolder == null || !worldFolder.exists() || !worldFolder.isDirectory()) {
|
||||
return FolderStatus.DOES_NOT_EXIST;
|
||||
}
|
||||
if (!folderHasDat(worldFolder)) {
|
||||
return FolderStatus.NOT_A_WORLD;
|
||||
}
|
||||
return FolderStatus.VALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* A very basic check to see if a folder has a level.dat file. If it does, we can safely assume
|
||||
* it's a world folder.
|
||||
*
|
||||
* @param worldFolder The File that may be a world.
|
||||
* @return True if it looks like a world, else false.
|
||||
*/
|
||||
private boolean folderHasDat(@NotNull File worldFolder) {
|
||||
File[] files = worldFolder.listFiles((file, name) -> name.toLowerCase().endsWith(".dat"));
|
||||
return files != null && files.length > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Result after checking validity of world name.
|
||||
*/
|
||||
public enum NameStatus {
|
||||
/**
|
||||
* Name is valid.
|
||||
*/
|
||||
VALID,
|
||||
|
||||
/**
|
||||
* Name not valid as it contains invalid characters.
|
||||
*/
|
||||
INVALID_CHARS,
|
||||
|
||||
/**
|
||||
* Name not valid as it is deemed blacklisted.
|
||||
*/
|
||||
BLACKLISTED
|
||||
}
|
||||
|
||||
/**
|
||||
* Result after checking validity of world folder.
|
||||
*/
|
||||
public enum FolderStatus {
|
||||
/**
|
||||
* Folder is valid.
|
||||
*/
|
||||
VALID,
|
||||
|
||||
/**
|
||||
* Folder exist, but contents in it doesnt look like a world.
|
||||
*/
|
||||
NOT_A_WORLD,
|
||||
|
||||
/**
|
||||
* Folder does not exist.
|
||||
*/
|
||||
DOES_NOT_EXIST
|
||||
}
|
||||
}
|
@ -97,6 +97,14 @@ public class WorldConfig {
|
||||
return configHandle.set(configNodes.AUTO_LOAD, autoLoad);
|
||||
}
|
||||
|
||||
public boolean getBedRespawn() {
|
||||
return configHandle.get(configNodes.BED_RESPAWN);
|
||||
}
|
||||
|
||||
public Try<Void> setBedRespawn(boolean bedRespawn) {
|
||||
return configHandle.set(configNodes.BED_RESPAWN, bedRespawn);
|
||||
}
|
||||
|
||||
public Difficulty getDifficulty() {
|
||||
return configHandle.get(configNodes.DIFFICULTY);
|
||||
}
|
||||
|
@ -61,6 +61,11 @@ public class WorldConfigNodes {
|
||||
.name("auto-load")
|
||||
.build());
|
||||
|
||||
public final ConfigNode<Boolean> BED_RESPAWN = node(ConfigNode.builder("bed-respawn", Boolean.class)
|
||||
.defaultValue(true)
|
||||
.name("bed-respawn")
|
||||
.build());
|
||||
|
||||
public final ConfigNode<Difficulty> DIFFICULTY = node(ConfigNode.builder("difficulty", Difficulty.class)
|
||||
.defaultValue(Difficulty.NORMAL)
|
||||
.name("difficulty")
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.onarandombox.MultiverseCore.world.entrycheck;
|
||||
package com.onarandombox.MultiverseCore.worldnew.entrycheck;
|
||||
|
||||
import co.aikar.locales.MessageKey;
|
||||
import co.aikar.locales.MessageKeyProvider;
|
@ -1,4 +1,4 @@
|
||||
package com.onarandombox.MultiverseCore.world.entrycheck;
|
||||
package com.onarandombox.MultiverseCore.worldnew.entrycheck;
|
||||
|
||||
|
||||
import co.aikar.locales.MessageKey;
|
@ -1,4 +1,4 @@
|
||||
package com.onarandombox.MultiverseCore.world.entrycheck;
|
||||
package com.onarandombox.MultiverseCore.worldnew.entrycheck;
|
||||
|
||||
import co.aikar.locales.MessageKey;
|
||||
import co.aikar.locales.MessageKeyProvider;
|
@ -1,4 +1,4 @@
|
||||
package com.onarandombox.MultiverseCore.world.entrycheck;
|
||||
package com.onarandombox.MultiverseCore.worldnew.entrycheck;
|
||||
|
||||
import co.aikar.locales.MessageKey;
|
||||
import co.aikar.locales.MessageKeyProvider;
|
@ -1,12 +1,12 @@
|
||||
package com.onarandombox.MultiverseCore.world.entrycheck;
|
||||
package com.onarandombox.MultiverseCore.worldnew.entrycheck;
|
||||
|
||||
import com.onarandombox.MultiverseCore.api.MVWorld;
|
||||
import com.onarandombox.MultiverseCore.config.MVCoreConfig;
|
||||
import com.onarandombox.MultiverseCore.economy.MVEconomist;
|
||||
import com.onarandombox.MultiverseCore.permissions.CorePermissionsChecker;
|
||||
import com.onarandombox.MultiverseCore.utils.result.Result;
|
||||
import com.onarandombox.MultiverseCore.utils.result.ResultChain;
|
||||
import com.onarandombox.MultiverseCore.world.configuration.EntryFee;
|
||||
import com.onarandombox.MultiverseCore.worldnew.MVWorld;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.command.BlockCommandSender;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@ -66,7 +66,7 @@ public class WorldEntryChecker {
|
||||
if (permissionsChecker.hasPlayerLimitBypassPermission(sender, world)) {
|
||||
return Result.success(PlayerLimitResult.Success.BYPASS_PLAYERLIMIT);
|
||||
}
|
||||
return playerLimit > world.getCBWorld().getPlayers().size()
|
||||
return playerLimit > world.getBukkitWorld().map(org.bukkit.World::getPlayers).map(java.util.Collection::size).getOrElse(0)
|
||||
? Result.success(PlayerLimitResult.Success.WITHIN_PLAYERLIMIT)
|
||||
: Result.failure(PlayerLimitResult.Failure.EXCEED_PLAYERLIMIT);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.onarandombox.MultiverseCore.world.entrycheck;
|
||||
package com.onarandombox.MultiverseCore.worldnew.entrycheck;
|
||||
|
||||
import com.onarandombox.MultiverseCore.config.MVCoreConfig;
|
||||
import com.onarandombox.MultiverseCore.economy.MVEconomist;
|
@ -5,6 +5,7 @@ world:
|
||||
allow-weather: true
|
||||
auto-heal: true
|
||||
auto-load: true
|
||||
bed-respawn: true
|
||||
difficulty: NORMAL
|
||||
entry-fee:
|
||||
amount: 0.0
|
||||
@ -38,6 +39,7 @@ world_nether:
|
||||
allow-weather: true
|
||||
auto-heal: true
|
||||
auto-load: true
|
||||
bed-respawn: true
|
||||
difficulty: NORMAL
|
||||
entry-fee:
|
||||
amount: 0.0
|
||||
|
@ -5,6 +5,7 @@ world_nether:
|
||||
allow-weather: true
|
||||
auto-heal: true
|
||||
auto-load: true
|
||||
bed-respawn: true
|
||||
difficulty: NORMAL
|
||||
entry-fee:
|
||||
amount: 0.0
|
||||
|
@ -5,6 +5,7 @@ world:
|
||||
allow-weather: true
|
||||
auto-heal: true
|
||||
auto-load: true
|
||||
bed-respawn: true
|
||||
difficulty: NORMAL
|
||||
entry-fee:
|
||||
amount: 0.0
|
||||
@ -38,6 +39,7 @@ world_nether:
|
||||
allow-weather: true
|
||||
auto-heal: true
|
||||
auto-load: true
|
||||
bed-respawn: true
|
||||
difficulty: NORMAL
|
||||
entry-fee:
|
||||
amount: 0.0
|
||||
@ -71,6 +73,7 @@ newworld:
|
||||
allow-weather: true
|
||||
auto-heal: true
|
||||
auto-load: true
|
||||
bed-respawn: true
|
||||
difficulty: NORMAL
|
||||
entry-fee:
|
||||
amount: 0.0
|
||||
|
@ -5,6 +5,7 @@ world:
|
||||
allow-weather: true
|
||||
auto-heal: true
|
||||
auto-load: true
|
||||
bed-respawn: true
|
||||
difficulty: NORMAL
|
||||
entry-fee:
|
||||
amount: 0.0
|
||||
@ -38,6 +39,7 @@ world_nether:
|
||||
allow-weather: true
|
||||
auto-heal: true
|
||||
auto-load: true
|
||||
bed-respawn: true
|
||||
difficulty: NORMAL
|
||||
entry-fee:
|
||||
amount: 0.0
|
||||
|
Loading…
Reference in New Issue
Block a user