diff --git a/src/main/java/org/mvplugins/multiverse/core/api/event/MVWorldPropertyChangeEvent.java b/src/main/java/org/mvplugins/multiverse/core/api/event/MVWorldPropertyChangeEvent.java index d7f87325..dcc1fb1c 100644 --- a/src/main/java/org/mvplugins/multiverse/core/api/event/MVWorldPropertyChangeEvent.java +++ b/src/main/java/org/mvplugins/multiverse/core/api/event/MVWorldPropertyChangeEvent.java @@ -7,39 +7,32 @@ package org.mvplugins.multiverse.core.api.event; -import org.bukkit.command.CommandSender; -import org.bukkit.event.Cancellable; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; import org.mvplugins.multiverse.core.api.world.MultiverseWorld; /** - * This event is fired *before* the property is actually changed. + * This event is fired after the property is changed. *

- * If it is cancelled, no change will happen. - *

- * If you want to get the values of the world before the change, query the world. - * To get the name of the property that was changed, use {@link #getPropertyName()}. - * To get the new value, use {@link #getTheNewValue()}. To change it, use {@link #setTheNewValue(Object)}. + * To get the name of the property that was changed, use {@link #getName()}. + * To get the old value, use {@link #getOldValue()}. + * To get the new value, use {@link #getNewValue()}. * * @param The type of the property that was set. * @since 5.0 */ -// todo: Implement or remove this -@Deprecated -public class MVWorldPropertyChangeEvent extends Event implements Cancellable { - private MultiverseWorld world; - private CommandSender changer; - private boolean isCancelled = false; - private String name; - private T value; +public class MVWorldPropertyChangeEvent extends Event { + private final MultiverseWorld world; + private final String name; + private final T oldValue; + private final T newValue; - public MVWorldPropertyChangeEvent(MultiverseWorld world, CommandSender changer, String name, T value) { + public MVWorldPropertyChangeEvent(MultiverseWorld world, String name, T oldValue, T value) { this.world = world; - this.changer = changer; this.name = name; - this.value = value; + this.oldValue = oldValue; + this.newValue = value; } private static final HandlerList HANDLERS = new HandlerList(); @@ -67,64 +60,37 @@ public class MVWorldPropertyChangeEvent extends Event implements Cancellable * @return The changed world property's name. * @since 5.0 */ - public String getPropertyName() { + public String getName() { return this.name; } + /** + * Gets the old value. + * + * @return The old value. + * @since 5.0 + */ + public T getOldValue() { + return oldValue; + } + /** * Gets the new value. * * @return The new value. * @since 5.0 */ - public T getTheNewValue() { - return this.value; - } - - /** - * Sets the new value. - * - * @param value The new value. - * @since 5.0 - */ - public void setTheNewValue(T value) { - this.value = value; + public T getNewValue() { + return this.newValue; } /** * Get the world targeted because of this change. * * @return A valid MultiverseWorld. + * @since 5.0 */ public MultiverseWorld getWorld() { return this.world; } - - /** - * Gets the person (or console) who was responsible for the change. - *

- * This may be null! - * - * @return The person (or console) who was responsible for the change. - * @since 5.0 - */ - public CommandSender getCommandSender() { - return this.changer; - } - - /** - * {@inheritDoc} - */ - @Override - public boolean isCancelled() { - return this.isCancelled; - } - - /** - * {@inheritDoc} - */ - @Override - public void setCancelled(boolean cancelled) { - this.isCancelled = cancelled; - } } diff --git a/src/main/java/org/mvplugins/multiverse/core/configuration/node/ConfigHeaderNode.java b/src/main/java/org/mvplugins/multiverse/core/configuration/node/ConfigHeaderNode.java index dac5b685..51cf4865 100644 --- a/src/main/java/org/mvplugins/multiverse/core/configuration/node/ConfigHeaderNode.java +++ b/src/main/java/org/mvplugins/multiverse/core/configuration/node/ConfigHeaderNode.java @@ -66,7 +66,7 @@ public class ConfigHeaderNode implements CommentedNode { comment = "# " + comment; } comments.add(comment); - return (B) this; + return self(); } /** @@ -77,5 +77,11 @@ public class ConfigHeaderNode implements CommentedNode { public @NotNull ConfigHeaderNode build() { return new ConfigHeaderNode(path, comments.toArray(new String[0])); } + + + protected @NotNull B self() { + //noinspection unchecked + return (B) this; + } } } diff --git a/src/main/java/org/mvplugins/multiverse/core/configuration/node/ConfigNode.java b/src/main/java/org/mvplugins/multiverse/core/configuration/node/ConfigNode.java index 57a18454..21f631df 100644 --- a/src/main/java/org/mvplugins/multiverse/core/configuration/node/ConfigNode.java +++ b/src/main/java/org/mvplugins/multiverse/core/configuration/node/ConfigNode.java @@ -182,6 +182,15 @@ public class ConfigNode extends ConfigHeaderNode implements ValueNode { this.type = type; } + /** + * Gets the path of this node. + * + * @return The path of this node. + */ + public @NotNull String path() { + return path; + } + /** * Sets the default value for this node. * @@ -215,6 +224,15 @@ public class ConfigNode extends ConfigHeaderNode implements ValueNode { return self(); } + /** + * Gets the name of this node. Used for identifying the node from user input. + * + * @return The name of this node, or {@code null} if the node has no name. + */ + public @Nullable String name() { + return name; + } + /** * Sets the suggester for this node. * @@ -266,7 +284,7 @@ public class ConfigNode extends ConfigHeaderNode implements ValueNode { * @return This builder. */ public @NotNull B onSetValue(@NotNull BiConsumer onSetValue) { - this.onSetValue = onSetValue; + this.onSetValue = this.onSetValue == null ? onSetValue : this.onSetValue.andThen(onSetValue); return self(); } @@ -278,10 +296,5 @@ public class ConfigNode extends ConfigHeaderNode implements ValueNode { return new ConfigNode<>(path, comments.toArray(new String[0]), name, type, defaultValue, suggester, stringParser, serializer, validator, onSetValue); } - - protected @NotNull B self() { - //noinspection unchecked - return (B) this; - } } } diff --git a/src/main/java/org/mvplugins/multiverse/core/configuration/node/ListConfigNode.java b/src/main/java/org/mvplugins/multiverse/core/configuration/node/ListConfigNode.java index 8b50b679..b139f8bb 100644 --- a/src/main/java/org/mvplugins/multiverse/core/configuration/node/ListConfigNode.java +++ b/src/main/java/org/mvplugins/multiverse/core/configuration/node/ListConfigNode.java @@ -32,7 +32,7 @@ public class ListConfigNode extends ConfigNode> implements ListValueN * @param The type of the value. * @return The new builder. */ - public static @NotNull Builder> listBuilder( + public static @NotNull > Builder listBuilder( @NotNull String path, @NotNull Class type) { return new Builder<>(path, type); diff --git a/src/main/java/org/mvplugins/multiverse/core/world/config/WorldConfigNodes.java b/src/main/java/org/mvplugins/multiverse/core/world/config/WorldConfigNodes.java index 64f8fe05..e3b170e1 100644 --- a/src/main/java/org/mvplugins/multiverse/core/world/config/WorldConfigNodes.java +++ b/src/main/java/org/mvplugins/multiverse/core/world/config/WorldConfigNodes.java @@ -2,7 +2,12 @@ package org.mvplugins.multiverse.core.world.config; import java.util.ArrayList; import java.util.Collections; +import java.util.List; +import java.util.Objects; +import com.dumptruckman.minecraft.util.Logging; +import io.vavr.control.Option; +import org.bukkit.Bukkit; import org.bukkit.Difficulty; import org.bukkit.GameMode; import org.bukkit.Material; @@ -11,12 +16,12 @@ import org.bukkit.block.Biome; import org.jetbrains.annotations.NotNull; import org.mvplugins.multiverse.core.MultiverseCore; +import org.mvplugins.multiverse.core.api.event.MVWorldPropertyChangeEvent; import org.mvplugins.multiverse.core.api.world.config.AllowedPortalType; import org.mvplugins.multiverse.core.api.world.LoadedMultiverseWorld; import org.mvplugins.multiverse.core.api.world.config.SpawnLocation; import org.mvplugins.multiverse.core.configuration.node.ConfigNode; import org.mvplugins.multiverse.core.configuration.node.ListConfigNode; -import org.mvplugins.multiverse.core.configuration.node.Node; import org.mvplugins.multiverse.core.configuration.node.NodeGroup; import org.mvplugins.multiverse.core.economy.MVEconomist; import org.mvplugins.multiverse.core.api.world.MultiverseWorld; @@ -52,7 +57,17 @@ public class WorldConfigNodes { return nodes; } - private N node(N node) { + private ConfigNode node(ConfigNode.Builder nodeBuilder) { + nodeBuilder.onSetValue((oldValue, newValue) -> { + if (Objects.equals(oldValue, newValue)) return; + MVWorldPropertyChangeEvent mvWorldPropertyChangeEvent = new MVWorldPropertyChangeEvent<>( + world, Option.of(nodeBuilder.name()).getOrElse(nodeBuilder.path()), oldValue, newValue); + Bukkit.getPluginManager().callEvent(mvWorldPropertyChangeEvent); + Logging.finer("MVWorldPropertyChangeEvent fired for world '%s' with name '%s' and value '%s'", + world.getName(), nodeBuilder.path(), newValue); + }); + + ConfigNode node = nodeBuilder.build(); nodes.add(node); return node; } @@ -63,20 +78,17 @@ public class WorldConfigNodes { // BEGIN CHECKSTYLE-SUPPRESSION: VisibilityModifier final ConfigNode ADJUST_SPAWN = node(ConfigNode.builder("adjust-spawn", Boolean.class) - .defaultValue(false) - .build()); + .defaultValue(false)); final ConfigNode ALIAS = node(ConfigNode.builder("alias", String.class) - .defaultValue("") - .build()); + .defaultValue("")); final ConfigNode ALLOW_FLIGHT = node(ConfigNode.builder("allow-flight", Boolean.class) .defaultValue(false) .onSetValue((oldValue, newValue) -> { if (world == null) return; enforcementHandler.handleAllFlightEnforcement(world); - }) - .build()); + })); final ConfigNode ALLOW_WEATHER = node(ConfigNode.builder("allow-weather", Boolean.class) .defaultValue(true) @@ -88,82 +100,67 @@ public class WorldConfigNodes { world.setStorm(false); } }); - }) - .build()); + })); final ConfigNode ANCHOR_RESPAWN = node(ConfigNode.builder("anchor-respawn", Boolean.class) - .defaultValue(true) - .build()); + .defaultValue(true)); final ConfigNode AUTO_HEAL = node(ConfigNode.builder("auto-heal", Boolean.class) - .defaultValue(true) - .build()); + .defaultValue(true)); final ConfigNode AUTO_LOAD = node(ConfigNode.builder("auto-load", Boolean.class) - .defaultValue(true) - .build()); + .defaultValue(true)); final ConfigNode BED_RESPAWN = node(ConfigNode.builder("bed-respawn", Boolean.class) - .defaultValue(true) - .build()); + .defaultValue(true)); final ConfigNode BIOME = node(ConfigNode.builder("biome", Biome.class) .defaultValue(Biome.CUSTOM) .name(null) - .serializer(new BiomeSerializer()) - .build()); + .serializer(new BiomeSerializer())); final ConfigNode DIFFICULTY = node(ConfigNode.builder("difficulty", Difficulty.class) .defaultValue(Difficulty.NORMAL) .onSetValue((oldValue, newValue) -> { if (world == null) return; world.getBukkitWorld().peek(world -> world.setDifficulty(newValue)); - }) - .build()); + })); final ConfigNode ENTRY_FEE_ENABLED = node(ConfigNode.builder("entry-fee.enabled", Boolean.class) .defaultValue(false) - .name("entryfee-enabled") - .build()); + .name("entryfee-enabled")); final ConfigNode ENTRY_FEE_AMOUNT = node(ConfigNode.builder("entry-fee.amount", Double.class) .defaultValue(0.0) - .name("entryfee-amount") - .build()); + .name("entryfee-amount")); final ConfigNode ENTRY_FEE_CURRENCY = node(ConfigNode.builder("entry-fee.currency", Material.class) .defaultValue(MVEconomist.VAULT_ECONOMY_MATERIAL) .name("entryfee-currency") - .serializer(new CurrencySerializer()) - .build()); + .serializer(new CurrencySerializer())); final ConfigNode ENVIRONMENT = node(ConfigNode .builder("environment", World.Environment.class) .defaultValue(World.Environment.NORMAL) - .name(null) - .build()); + .name(null)); final ConfigNode GAMEMODE = node(ConfigNode.builder("gamemode", GameMode.class) .defaultValue(GameMode.SURVIVAL) .onSetValue((oldValue, newValue) -> { if (world == null) return; enforcementHandler.handleAllGameModeEnforcement(world); - }) - .build()); + })); final ConfigNode GENERATOR = node(ConfigNode.builder("generator", String.class) // this should be set on world creation, if @error is shown in config, something went wrong .defaultValue("@error") - .name(null) - .build()); + .name(null)); final ConfigNode HIDDEN = node(ConfigNode.builder("hidden", Boolean.class) - .defaultValue(false) - .build()); + .defaultValue(false)); final ConfigNode HUNGER = node(ConfigNode.builder("hunger", Boolean.class) - .defaultValue(true) - .build()); + .defaultValue(true)); final ConfigNode KEEP_SPAWN_IN_MEMORY = node(ConfigNode .builder("keep-spawn-in-memory", Boolean.class) @@ -171,33 +168,28 @@ public class WorldConfigNodes { .onSetValue((oldValue, newValue) -> { if (world == null) return; world.getBukkitWorld().peek(world -> world.setKeepSpawnInMemory(newValue)); - }) - .build()); + })); final ConfigNode PLAYER_LIMIT = node(ConfigNode.builder("player-limit", Integer.class) - .defaultValue(-1) - .build()); + .defaultValue(-1)); final ConfigNode PORTAL_FORM = node(ConfigNode .builder("portal-form", AllowedPortalType.class) - .defaultValue(AllowedPortalType.ALL) - .build()); + .defaultValue(AllowedPortalType.ALL)); final ConfigNode PVP = node(ConfigNode.builder("pvp", Boolean.class) .defaultValue(true) .onSetValue((oldValue, newValue) -> { if (world == null) return; world.getBukkitWorld().peek(world -> world.setPVP(newValue)); - }) - .build()); + })); final ConfigNode RESPAWN_WORLD = node(ConfigNode.builder("respawn-world", String.class) .defaultValue("") .suggester(input -> { if (worldManager == null) return Collections.emptyList(); return worldManager.getWorlds().stream().map(MultiverseWorld::getName).toList(); - }) - .build()); + })); final ConfigNode SCALE = node(ConfigNode.builder("scale", Double.class) .defaultValue(() -> { @@ -207,13 +199,11 @@ public class WorldConfigNodes { case THE_END -> 16.0; default -> 1.0; }; - }) - .build()); + })); final ConfigNode SEED = node(ConfigNode.builder("seed", Long.class) .defaultValue(Long.MIN_VALUE) - .name(null) - .build()); + .name(null)); final ConfigNode SPAWN_LOCATION = node(ConfigNode.builder("spawn-location", SpawnLocation.class) .defaultValue(NullLocation.get()) @@ -225,8 +215,7 @@ public class WorldConfigNodes { bukkitWorld.setSpawnLocation(newValue.getBlockX(), newValue.getBlockY(), newValue.getBlockZ()); newValue.setWorld(bukkitWorld); }); - }) - .build()); + })); final ConfigNode SPAWNING_ANIMALS = node(ConfigNode.builder("spawning.animals.spawn", Boolean.class) .defaultValue(true) @@ -234,8 +223,7 @@ public class WorldConfigNodes { .onSetValue((oldValue, newValue) -> { if (world == null) return; world.getBukkitWorld().peek(world -> world.setSpawnFlags(world.getAllowMonsters(), newValue)); - }) - .build()); + })); final ConfigNode SPAWNING_ANIMALS_TICKS = node(ConfigNode .builder("spawning.animals.tick-rate", Integer.class) @@ -244,14 +232,12 @@ public class WorldConfigNodes { .onSetValue((oldValue, newValue) -> { if (world == null) return; world.getBukkitWorld().peek(world -> world.setTicksPerAnimalSpawns(newValue)); - }) - .build()); + })); - final ListConfigNode SPAWNING_ANIMALS_EXCEPTIONS = node(ListConfigNode + final ConfigNode> SPAWNING_ANIMALS_EXCEPTIONS = node(ListConfigNode .listBuilder("spawning.animals.exceptions", String.class) .defaultValue(new ArrayList<>()) - .name("spawning-animals-exceptions") - .build()); + .name("spawning-animals-exceptions")); final ConfigNode SPAWNING_MONSTERS = node(ConfigNode .builder("spawning.monsters.spawn", Boolean.class) @@ -260,8 +246,7 @@ public class WorldConfigNodes { .onSetValue((oldValue, newValue) -> { if (world == null) return; world.getBukkitWorld().peek(world -> world.setSpawnFlags(newValue, world.getAllowAnimals())); - }) - .build()); + })); final ConfigNode SPAWNING_MONSTERS_TICKS = node(ConfigNode .builder("spawning.monsters.tick-rate", Integer.class) @@ -270,22 +255,18 @@ public class WorldConfigNodes { .onSetValue((oldValue, newValue) -> { if (world == null) return; world.getBukkitWorld().peek(world -> world.setTicksPerMonsterSpawns(newValue)); - }) - .build()); + })); - final ListConfigNode SPAWNING_MONSTERS_EXCEPTIONS = node(ListConfigNode + final ConfigNode> SPAWNING_MONSTERS_EXCEPTIONS = node(ListConfigNode .listBuilder("spawning.monsters.exceptions", String.class) .defaultValue(new ArrayList<>()) - .name("spawning-monsters-exceptions") - .build()); + .name("spawning-monsters-exceptions")); - final ListConfigNode WORLD_BLACKLIST = node(ListConfigNode.listBuilder("world-blacklist", String.class) - .build()); + final ConfigNode> WORLD_BLACKLIST = node(ListConfigNode.listBuilder("world-blacklist", String.class)); final ConfigNode VERSION = node(ConfigNode.builder("version", Double.class) .defaultValue(CONFIG_VERSION) - .name(null) - .build()); + .name(null)); // END CHECKSTYLE-SUPPRESSION: Javadoc // END CHECKSTYLE-SUPPRESSION: MemberName