Make world name matching case-insensitive to follow papermc behvaiour
This commit is contained in:
1 parent
2b41c1367e
commit
13b949c692
4 files changed
+95
-29
No files matched your search
@@ -8,6 +8,7 @@ import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
@@ -344,7 +345,7 @@ public final class WorldManager {
|
||||
|
||||
private MultiverseWorld newMultiverseWorld(String worldName, WorldConfig worldConfig) {
|
||||
MultiverseWorld mvWorld = new MultiverseWorld(worldName, worldConfig, config);
|
||||
worldsMap.put(mvWorld.getName(), mvWorld);
|
||||
worldsMap.put(mvWorld.getName().toLowerCase(Locale.ENGLISH), mvWorld);
|
||||
corePermissions.addWorldPermissions(mvWorld);
|
||||
return mvWorld;
|
||||
}
|
||||
@@ -381,7 +382,7 @@ public final class WorldManager {
|
||||
locationManipulation,
|
||||
entityPurger
|
||||
);
|
||||
loadedWorldsMap.put(loadedWorld.getName(), loadedWorld);
|
||||
loadedWorldsMap.put(loadedWorld.getName().toLowerCase(Locale.ENGLISH), loadedWorld);
|
||||
saveWorldsConfig();
|
||||
pluginManager.callEvent(new MVWorldLoadedEvent(loadedWorld));
|
||||
return loadedWorld;
|
||||
@@ -500,7 +501,7 @@ public final class WorldManager {
|
||||
locationManipulation,
|
||||
entityPurger
|
||||
);
|
||||
loadedWorldsMap.put(loadedWorld.getName(), loadedWorld);
|
||||
loadedWorldsMap.put(loadedWorld.getName().toLowerCase(Locale.ENGLISH), loadedWorld);
|
||||
saveWorldsConfig();
|
||||
pluginManager.callEvent(new MVWorldLoadedEvent(loadedWorld));
|
||||
return Attempt.success(loadedWorld);
|
||||
@@ -967,7 +968,9 @@ public final class WorldManager {
|
||||
* @return The world if it exists.
|
||||
*/
|
||||
public Option<MultiverseWorld> getWorld(@Nullable String worldName) {
|
||||
return getLoadedWorld(worldName).fold(() -> getUnloadedWorld(worldName), Option::of);
|
||||
return getLoadedWorld(worldName)
|
||||
.map(world -> (MultiverseWorld) world)
|
||||
.orElse(() -> getUnloadedWorld(worldName));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -979,7 +982,8 @@ public final class WorldManager {
|
||||
*/
|
||||
public Option<MultiverseWorld> getWorldByNameOrAlias(@Nullable String worldNameOrAlias) {
|
||||
return getLoadedWorldByNameOrAlias(worldNameOrAlias)
|
||||
.fold(() -> getUnloadedWorldByNameOrAlias(worldNameOrAlias), Option::of);
|
||||
.map(world -> (MultiverseWorld) world)
|
||||
.orElse(() -> getUnloadedWorldByNameOrAlias(worldNameOrAlias));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -994,7 +998,8 @@ public final class WorldManager {
|
||||
public Collection<MultiverseWorld> getWorlds() {
|
||||
return worldsMap.values().stream()
|
||||
.map(world -> getLoadedWorld(world)
|
||||
.fold(() -> world, loadedWorld -> loadedWorld))
|
||||
.map(loadedWorld -> (MultiverseWorld) loadedWorld)
|
||||
.getOrElse(world))
|
||||
.toList();
|
||||
}
|
||||
|
||||
@@ -1005,7 +1010,7 @@ public final class WorldManager {
|
||||
* @return True if the world is a world is known to multiverse, but may or may not be loaded.
|
||||
*/
|
||||
public boolean isWorld(@Nullable String worldName) {
|
||||
return worldsMap.containsKey(worldName);
|
||||
return worldName != null && worldsMap.containsKey(worldName.toLowerCase(Locale.ENGLISH));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1015,7 +1020,9 @@ public final class WorldManager {
|
||||
* @return The world if it exists.
|
||||
*/
|
||||
public Option<MultiverseWorld> getUnloadedWorld(@Nullable String worldName) {
|
||||
return isLoadedWorld(worldName) ? Option.none() : Option.of(worldsMap.get(worldName));
|
||||
return isLoadedWorld(worldName)
|
||||
? Option.none()
|
||||
: Option.of(worldName).flatMap(name -> Option.of(worldsMap.get(name.toLowerCase(Locale.ENGLISH))));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1067,7 +1074,7 @@ public final class WorldManager {
|
||||
* @return The multiverse world if it exists.
|
||||
*/
|
||||
public Option<LoadedMultiverseWorld> getLoadedWorld(@Nullable World world) {
|
||||
return world == null ? Option.none() : Option.of(loadedWorldsMap.get(world.getName()));
|
||||
return Option.of(world).flatMap(notNullWorld -> getLoadedWorld(notNullWorld.getName()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1077,7 +1084,7 @@ public final class WorldManager {
|
||||
* @return The multiverse world if it exists.
|
||||
*/
|
||||
public Option<LoadedMultiverseWorld> getLoadedWorld(@Nullable MultiverseWorld world) {
|
||||
return world == null ? Option.none() : Option.of(loadedWorldsMap.get(world.getName()));
|
||||
return Option.of(world).flatMap(notNullWorld -> getLoadedWorld(notNullWorld.getName()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1087,7 +1094,8 @@ public final class WorldManager {
|
||||
* @return The multiverse world if it exists.
|
||||
*/
|
||||
public Option<LoadedMultiverseWorld> getLoadedWorld(@Nullable String worldName) {
|
||||
return Option.of(loadedWorldsMap.get(worldName));
|
||||
return Option.of(worldName)
|
||||
.flatMap(name -> Option.of(loadedWorldsMap.get(name.toLowerCase(Locale.ENGLISH))));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1148,7 +1156,7 @@ public final class WorldManager {
|
||||
* @return True if the world is a multiverse world that is loaded.
|
||||
*/
|
||||
public boolean isLoadedWorld(@Nullable String worldName) {
|
||||
return loadedWorldsMap.containsKey(worldName);
|
||||
return worldName != null && loadedWorldsMap.containsKey(worldName.toLowerCase(Locale.ENGLISH));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,13 +3,13 @@ package org.mvplugins.multiverse.core.world.helpers;
|
||||
import java.io.File;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import io.vavr.control.Option;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jvnet.hk2.annotations.Service;
|
||||
import org.mvplugins.multiverse.core.utils.REPatterns;
|
||||
|
||||
/**
|
||||
* <p>Utility class in helping to check the status of a world name and it's associated world folder.</p>
|
||||
@@ -20,11 +20,11 @@ import org.jvnet.hk2.annotations.Service;
|
||||
@Service
|
||||
public final class WorldNameChecker {
|
||||
|
||||
private static final Pattern WORLD_NAME_PATTERN = Pattern.compile("[a-zA-Z0-9/._-]+");
|
||||
private static final Set<String> BLACKLIST_NAMES = Set.of(
|
||||
"cache",
|
||||
"config",
|
||||
"crash-reports",
|
||||
"libraries",
|
||||
"logs",
|
||||
"plugins",
|
||||
"versions");
|
||||
@@ -47,18 +47,21 @@ public final class WorldNameChecker {
|
||||
*/
|
||||
@NotNull
|
||||
public NameStatus checkName(@Nullable String worldName) {
|
||||
return Option.of(worldName).map(name -> {
|
||||
if (name.isEmpty()) {
|
||||
return NameStatus.EMPTY;
|
||||
}
|
||||
if (BLACKLIST_NAMES.contains(name)) {
|
||||
return NameStatus.BLACKLISTED;
|
||||
}
|
||||
if (!WORLD_NAME_PATTERN.matcher(name).matches()) {
|
||||
return NameStatus.INVALID_CHARS;
|
||||
}
|
||||
return NameStatus.VALID;
|
||||
}).getOrElse(NameStatus.EMPTY);
|
||||
return Option.of(worldName)
|
||||
.map(name -> name.toLowerCase(Locale.ENGLISH))
|
||||
.map(name -> {
|
||||
if (name.isEmpty()) {
|
||||
return NameStatus.EMPTY;
|
||||
}
|
||||
if (BLACKLIST_NAMES.contains(name)) {
|
||||
return NameStatus.BLACKLISTED;
|
||||
}
|
||||
if (!REPatterns.NAMESPACE_KEY.matcher(name).matches()) {
|
||||
return NameStatus.INVALID_CHARS;
|
||||
}
|
||||
return NameStatus.VALID;
|
||||
})
|
||||
.getOrElse(NameStatus.EMPTY);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -43,7 +43,7 @@ class WorldManagerTest : TestWithMockBukkit() {
|
||||
@Test
|
||||
fun `Create world with custom options`() {
|
||||
assertTrue(worldManager.createWorld(
|
||||
CreateWorldOptions.worldName("world_nether")
|
||||
CreateWorldOptions.worldName("Section/my-nether_world")
|
||||
.environment(World.Environment.NETHER)
|
||||
.generateStructures(false)
|
||||
.seed(1234L)
|
||||
@@ -51,11 +51,11 @@ class WorldManagerTest : TestWithMockBukkit() {
|
||||
.worldType(WorldType.FLAT)
|
||||
).isSuccess)
|
||||
|
||||
val getWorld = worldManager.getLoadedWorld("world_nether")
|
||||
val getWorld = worldManager.getLoadedWorld("Section/my-nether_world")
|
||||
assertTrue(getWorld.isDefined)
|
||||
val world = getWorld.get()
|
||||
assertNotNull(world)
|
||||
assertEquals("world_nether", world.name)
|
||||
assertEquals("Section/my-nether_world", world.name)
|
||||
assertEquals(World.Environment.NETHER, world.environment)
|
||||
assertFalse(world.canGenerateStructures().get())
|
||||
assertEquals(1234L, world.seed)
|
||||
@@ -84,6 +84,18 @@ class WorldManagerTest : TestWithMockBukkit() {
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Create world failed - world exists and loaded (case insensitive)`() {
|
||||
assertEquals(
|
||||
CreateFailureReason.WORLD_EXIST_LOADED,
|
||||
worldManager.createWorld(CreateWorldOptions.worldName("WoRld2")).failureReason
|
||||
)
|
||||
assertEquals(
|
||||
CreateFailureReason.WORLD_EXIST_LOADED,
|
||||
worldManager.createWorld(CreateWorldOptions.worldName("WORLD2")).failureReason
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Create world failed - world exists but unloaded`() {
|
||||
assertTrue(worldManager.unloadWorld(UnloadWorldOptions.world(world)).isSuccess)
|
||||
@@ -255,4 +267,46 @@ class WorldManagerTest : TestWithMockBukkit() {
|
||||
assertEquals(world, worldManager.getWorldByNameOrAlias("testalias").orNull)
|
||||
assertNull(worldManager.getUnloadedWorldByNameOrAlias("testalias").orNull)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get world`() {
|
||||
assertEquals(world, worldManager.getLoadedWorld("world").orNull)
|
||||
assertNull(worldManager.getUnloadedWorld("world").orNull)
|
||||
assertEquals(world, worldManager.getWorld("world").orNull)
|
||||
|
||||
assertTrue(worldManager.isLoadedWorld("world"))
|
||||
assertFalse(worldManager.isUnloadedWorld("world"))
|
||||
assertTrue(worldManager.isWorld("world"))
|
||||
|
||||
val unloadedWorld = worldManager.unloadWorld(UnloadWorldOptions.world(world)).get()
|
||||
|
||||
assertNull(worldManager.getLoadedWorld("world").orNull)
|
||||
assertEquals(unloadedWorld, worldManager.getUnloadedWorld("world").orNull)
|
||||
assertEquals(unloadedWorld, worldManager.getWorld("world").orNull)
|
||||
|
||||
assertFalse(worldManager.isLoadedWorld("world"))
|
||||
assertTrue(worldManager.isUnloadedWorld("world"))
|
||||
assertTrue(worldManager.isWorld("world"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get world is case insensitive`() {
|
||||
assertEquals(world2, worldManager.getLoadedWorld("WORLD2").orNull)
|
||||
assertNull(worldManager.getUnloadedWorld("wOrld2").orNull)
|
||||
assertEquals(world2, worldManager.getWorld("wOrld2").orNull)
|
||||
|
||||
assertTrue(worldManager.isLoadedWorld("WoRlD2"))
|
||||
assertFalse(worldManager.isUnloadedWorld("WoRlD2"))
|
||||
assertTrue(worldManager.isWorld("wORLD2"))
|
||||
|
||||
val unloadedWorld2 = worldManager.unloadWorld(UnloadWorldOptions.world(world2)).get()
|
||||
|
||||
assertNull(worldManager.getLoadedWorld("wOrld2").orNull)
|
||||
assertEquals(unloadedWorld2, worldManager.getUnloadedWorld("wOrld2").orNull)
|
||||
assertEquals(unloadedWorld2, worldManager.getWorld("wORLD2").orNull)
|
||||
|
||||
assertFalse(worldManager.isLoadedWorld("WoRlD2"))
|
||||
assertTrue(worldManager.isUnloadedWorld("WoRlD2"))
|
||||
assertTrue(worldManager.isWorld("wORLD2"))
|
||||
}
|
||||
}
|
||||
@@ -38,6 +38,7 @@ class WorldNameCheckerTest : TestWithMockBukkit() {
|
||||
fun `Blacklisted world name`() {
|
||||
assertEquals(WorldNameChecker.NameStatus.BLACKLISTED, worldNameChecker.checkName("logs"))
|
||||
assertEquals(WorldNameChecker.NameStatus.BLACKLISTED, worldNameChecker.checkName("plugins"))
|
||||
assertEquals(WorldNameChecker.NameStatus.BLACKLISTED, worldNameChecker.checkName("CACHE"))
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in new issue
Block a user