Lazy load locations in Configurate (#4203)

This commit is contained in:
Josh Roy 2021-06-07 15:52:12 -04:00 committed by GitHub
parent 7653da0e4f
commit 300daea4f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 146 additions and 84 deletions

View File

@ -3,6 +3,7 @@ package com.earth2me.essentials;
import com.earth2me.essentials.config.ConfigurateUtil;
import com.earth2me.essentials.config.EssentialsUserConfiguration;
import com.earth2me.essentials.config.entities.CommandCooldown;
import com.earth2me.essentials.config.entities.LazyLocation;
import com.earth2me.essentials.config.holders.UserConfigHolder;
import com.earth2me.essentials.utils.NumberUtil;
import com.earth2me.essentials.utils.StringUtil;
@ -154,23 +155,21 @@ public abstract class UserData extends PlayerExtension implements IConf {
public Location getHome(final String name) throws Exception {
final String search = getHomeName(name);
return holder.homes().get(search);
return holder.homes().get(search).location();
}
public Location getHome(final Location world) {
if (getHomes().isEmpty()) {
return null;
}
Location loc;
for (final String home : getHomes()) {
loc = holder.homes().get(home);
if (world.getWorld() == loc.getWorld()) {
final Location loc = holder.homes().get(home).location();
if (loc != null && world.getWorld() == loc.getWorld()) {
return loc;
}
}
loc = holder.homes().get(getHomes().get(0));
return loc;
return holder.homes().get(getHomes().get(0)).location();
}
public List<String> getHomes() {
@ -180,7 +179,7 @@ public abstract class UserData extends PlayerExtension implements IConf {
public void setHome(String name, final Location loc) {
//Invalid names will corrupt the yaml
name = StringUtil.safeString(name);
holder.homes().put(name, loc);
holder.homes().put(name, LazyLocation.fromLocation(loc));
config.save();
}
@ -262,7 +261,7 @@ public abstract class UserData extends PlayerExtension implements IConf {
}
public Location getLastLocation() {
return holder.lastLocation();
return holder.lastLocation().location();
}
public void setLastLocation(final Location loc) {
@ -274,7 +273,7 @@ public abstract class UserData extends PlayerExtension implements IConf {
}
public Location getLogoutLocation() {
return holder.logoutLocation();
return holder.logoutLocation().location();
}
public void setLogoutLocation(final Location loc) {

View File

@ -1,6 +1,7 @@
package com.earth2me.essentials.config;
import com.earth2me.essentials.config.annotations.DeleteOnEmpty;
import com.earth2me.essentials.config.entities.LazyLocation;
import com.earth2me.essentials.config.processors.DeleteOnEmptyProcessor;
import com.earth2me.essentials.config.serializers.BigDecimalTypeSerializer;
import com.earth2me.essentials.config.serializers.LocationTypeSerializer;
@ -49,7 +50,7 @@ public class EssentialsConfiguration {
private static final TypeSerializerCollection SERIALIZERS = TypeSerializerCollection.defaults().childBuilder()
.registerAnnotatedObjects(MAPPER_FACTORY)
.register(BigDecimal.class, new BigDecimalTypeSerializer())
.register(Location.class, new LocationTypeSerializer())
.register(LazyLocation.class, new LocationTypeSerializer())
.register(Material.class, new MaterialTypeSerializer())
.build();

View File

@ -0,0 +1,80 @@
package com.earth2me.essentials.config.entities;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import java.util.UUID;
/**
* Represents a Location but doesn't parse the location until it is requested via {@link LazyLocation#location()}.
*/
public class LazyLocation {
private final String world;
private final double x;
private final double y;
private final double z;
private final float yaw;
private final float pitch;
public LazyLocation(String world, double x, double y, double z, float yaw, float pitch) {
this.world = world;
this.x = x;
this.y = y;
this.z = z;
this.yaw = yaw;
this.pitch = pitch;
}
public String world() {
return world;
}
public double x() {
return x;
}
public double y() {
return y;
}
public double z() {
return z;
}
public float yaw() {
return yaw;
}
public float pitch() {
return pitch;
}
public Location location() {
if (this.world == null || this.world.isEmpty()) {
return null;
}
World world = null;
try {
final UUID worldId = UUID.fromString(this.world);
world = Bukkit.getWorld(worldId);
} catch (IllegalArgumentException ignored) {
}
if (world == null) {
world = Bukkit.getWorld(this.world);
}
if (world == null) {
return null;
}
return new Location(world, x, y, z, yaw, pitch);
}
public static LazyLocation fromLocation(final Location location) {
return new LazyLocation(location.getWorld().getUID().toString(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
}
}

View File

@ -2,6 +2,7 @@ package com.earth2me.essentials.config.holders;
import com.earth2me.essentials.config.annotations.DeleteOnEmpty;
import com.earth2me.essentials.config.entities.CommandCooldown;
import com.earth2me.essentials.config.entities.LazyLocation;
import org.bukkit.Location;
import org.bukkit.Material;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
@ -31,16 +32,16 @@ public class UserConfigHolder {
}
@DeleteOnEmpty
private @MonotonicNonNull Map<String, Location> homes;
private @MonotonicNonNull Map<String, LazyLocation> homes;
public Map<String, Location> homes() {
public Map<String, LazyLocation> homes() {
if (this.homes == null) {
this.homes = new HashMap<>();
}
return this.homes;
}
public void homes(final Map<String, Location> value) {
public void homes(final Map<String, LazyLocation> value) {
this.homes = value;
}
@ -74,9 +75,9 @@ public class UserConfigHolder {
return this.powertools;
}
private @MonotonicNonNull Location lastlocation;
private @MonotonicNonNull LazyLocation lastlocation;
public Location lastLocation() {
public LazyLocation lastLocation() {
return this.lastlocation;
}
@ -84,12 +85,12 @@ public class UserConfigHolder {
if (value == null || value.getWorld() == null) {
return;
}
this.lastlocation = value;
this.lastlocation = LazyLocation.fromLocation(value);
}
private @MonotonicNonNull Location logoutlocation;
private @MonotonicNonNull LazyLocation logoutlocation;
public Location logoutLocation() {
public LazyLocation logoutLocation() {
return this.logoutlocation;
}
@ -97,7 +98,7 @@ public class UserConfigHolder {
if (value == null || value.getWorld() == null) {
return;
}
this.logoutlocation = value;
this.logoutlocation = LazyLocation.fromLocation(value);
}
private @Nullable String jail;

View File

@ -1,47 +1,26 @@
package com.earth2me.essentials.config.serializers;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import com.earth2me.essentials.config.entities.LazyLocation;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.serialize.SerializationException;
import org.spongepowered.configurate.serialize.TypeSerializer;
import java.lang.reflect.Type;
import java.util.UUID;
/**
* A Configurate type serializer for {@link Location}s.
*
* Locations with a null or empty world will be considered invalid.
* A Configurate type serializer for {@link LazyLocation}s.
*/
public class LocationTypeSerializer implements TypeSerializer<Location> {
public class LocationTypeSerializer implements TypeSerializer<LazyLocation> {
@Override
public Location deserialize(Type type, ConfigurationNode node) throws SerializationException {
public LazyLocation deserialize(Type type, ConfigurationNode node) throws SerializationException {
final String worldValue = node.node("world").getString();
if (worldValue == null || worldValue.isEmpty()) {
throw new SerializationException("No world value present!");
}
World world = null;
try {
final UUID worldId = UUID.fromString(worldValue);
world = Bukkit.getWorld(worldId);
} catch (IllegalArgumentException ignored) {
}
if (world == null) {
world = Bukkit.getWorld(worldValue);
}
if (world == null) {
throw new SerializationException("No world value present!");
}
return new Location(
world,
return new LazyLocation(
worldValue,
node.node("x").getDouble(),
node.node("y").getDouble(),
node.node("z").getDouble(),
@ -50,17 +29,17 @@ public class LocationTypeSerializer implements TypeSerializer<Location> {
}
@Override
public void serialize(Type type, @Nullable Location value, ConfigurationNode node) throws SerializationException {
if (value == null || value.getWorld() == null) {
public void serialize(Type type, @Nullable LazyLocation value, ConfigurationNode node) throws SerializationException {
if (value == null || value.world() == null) {
node.raw(null);
return;
}
node.node("world").set(String.class, value.getWorld().getName());
node.node("x").set(Double.class, value.getX());
node.node("y").set(Double.class, value.getY());
node.node("z").set(Double.class, value.getZ());
node.node("yaw").set(Float.class, value.getYaw());
node.node("pitch").set(Float.class, value.getPitch());
node.node("world").set(String.class, value.world());
node.node("x").set(Double.class, value.x());
node.node("y").set(Double.class, value.y());
node.node("z").set(Double.class, value.z());
node.node("yaw").set(Float.class, value.yaw());
node.node("pitch").set(Float.class, value.pitch());
}
}

View File

@ -6,7 +6,6 @@ import com.earth2me.essentials.commands.IEssentialsCommand;
import com.earth2me.essentials.commands.NoChargeException;
import net.ess3.api.Economy;
import net.ess3.api.MaxMoneyException;
import org.bukkit.World.Environment;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.InvalidDescriptionException;
import org.junit.Assert;
@ -22,8 +21,7 @@ public class EconomyTest {
private final FakeServer server;
public EconomyTest() {
this.server = new FakeServer();
server.createWorld("testWorld", Environment.NORMAL);
this.server = FakeServer.getServer();
ess = new Essentials(server);
try {
ess.setupForTesting(server);

View File

@ -81,16 +81,21 @@ import java.util.concurrent.Future;
import java.util.function.Consumer;
import java.util.logging.Logger;
@SuppressWarnings({"NullableProblems", "ConstantConditions", "Contract"})
public class FakeServer implements Server {
@SuppressWarnings({"NullableProblems", "ConstantConditions"})
public final class FakeServer implements Server {
private final List<World> worlds = new ArrayList<>();
private final PluginManager pluginManager = new FakePluginManager();
private final List<Player> players = new ArrayList<>();
FakeServer() {
private FakeServer() {
createWorld("testWorld", Environment.NORMAL);
}
public static FakeServer getServer() {
if (Bukkit.getServer() == null) {
Bukkit.setServer(this);
Bukkit.setServer(new FakeServer());
}
return (FakeServer) Bukkit.getServer();
}
@Override
@ -427,6 +432,16 @@ public class FakeServer implements Server {
return null;
}
@Override
public World getWorld(final UUID uuid) {
for (final World world : worlds) {
if (world.getUID().equals(uuid)) {
return world;
}
}
return null;
}
@Override
public void reload() {
}
@ -501,11 +516,6 @@ public class FakeServer implements Server {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public World getWorld(final UUID uuid) {
throw new UnsupportedOperationException("Not supported yet.");
}
public MapView getMap(final int id) {
throw new UnsupportedOperationException("Not supported yet.");
}

View File

@ -2,16 +2,15 @@ package com.earth2me.essentials;
import com.earth2me.essentials.commands.IEssentialsCommand;
import com.earth2me.essentials.commands.NoChargeException;
import org.bukkit.World.Environment;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.InvalidDescriptionException;
import org.junit.Test;
import java.io.IOException;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertEquals;
public class MessagingTest {
@ -20,8 +19,7 @@ public class MessagingTest {
private final FakeServer server;
public MessagingTest() {
server = new FakeServer();
server.createWorld("testWorld", Environment.NORMAL);
server = FakeServer.getServer();
ess = new Essentials(server);
try {
ess.setupForTesting(server);

View File

@ -2,7 +2,6 @@ package com.earth2me.essentials;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.World.Environment;
import org.bukkit.plugin.InvalidDescriptionException;
import org.junit.Assert;
import org.junit.Test;
@ -15,8 +14,8 @@ public class StorageTest {
private final World world;
public StorageTest() {
server = new FakeServer();
world = server.createWorld("testWorld", Environment.NORMAL);
server = FakeServer.getServer();
world = server.getWorld("testWorld");
ess = new Essentials(server);
try {
ess.setupForTesting(server);

View File

@ -3,7 +3,6 @@ package com.earth2me.essentials;
import com.earth2me.essentials.commands.IEssentialsCommand;
import com.earth2me.essentials.commands.NoChargeException;
import junit.framework.TestCase;
import org.bukkit.World.Environment;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.InvalidDescriptionException;
@ -16,8 +15,7 @@ public class ToggleTest extends TestCase {
public ToggleTest(final String testName) {
super(testName);
server = new FakeServer();
server.createWorld("testWorld", Environment.NORMAL);
server = FakeServer.getServer();
ess = new Essentials(server);
try {
ess.setupForTesting(server);

View File

@ -3,7 +3,6 @@ package com.earth2me.essentials;
import junit.framework.TestCase;
import net.ess3.api.MaxMoneyException;
import org.bukkit.Location;
import org.bukkit.World.Environment;
import org.bukkit.plugin.InvalidDescriptionException;
import java.io.IOException;
@ -16,8 +15,7 @@ public class UserTest extends TestCase {
public UserTest(final String testName) {
super(testName);
server = new FakeServer();
server.createWorld("testWorld", Environment.NORMAL);
server = FakeServer.getServer();
ess = new Essentials(server);
try {
ess.setupForTesting(server);
@ -43,6 +41,7 @@ public class UserTest extends TestCase {
public void testHome() {
final User user = ess.getUser(base1);
final Location loc = base1.getLocation();
loc.setWorld(server.getWorlds().get(0));
user.setHome("home", loc);
final OfflinePlayer base2 = server.createPlayer(base1.getName());
final User user2 = ess.getUser(base2);

View File

@ -4,7 +4,6 @@ import com.earth2me.essentials.utils.DateUtil;
import com.earth2me.essentials.utils.LocationUtil;
import com.earth2me.essentials.utils.VersionUtil;
import junit.framework.TestCase;
import org.bukkit.World.Environment;
import org.bukkit.plugin.InvalidDescriptionException;
import java.io.IOException;
@ -16,8 +15,7 @@ import java.util.Set;
public class UtilTest extends TestCase {
public UtilTest() {
final FakeServer server = new FakeServer();
server.createWorld("testWorld", Environment.NORMAL);
final FakeServer server = FakeServer.getServer();
final Essentials ess = new Essentials(server);
try {
ess.setupForTesting(server);

View File

@ -42,10 +42,12 @@ import java.util.UUID;
public class FakeWorld implements World {
private final String name;
private final Environment env;
private final UUID uid;
public FakeWorld(final String string, final Environment environment) {
this.name = string;
this.env = environment;
this.uid = UUID.randomUUID();
}
@Override
@ -266,7 +268,7 @@ public class FakeWorld implements World {
@Override
public UUID getUID() {
throw new UnsupportedOperationException("Not supported yet.");
return uid;
}
@Override