Skip to content
Draft

V5.5-2 #3410

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ public void onDisable() {
MultiverseCoreApi.shutdown();
shutdownDependencyInjection();
PluginServiceLocatorFactory.get().shutdown();
Logging.info("- Disabled");
Logging.shutdown();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
import org.mvplugins.multiverse.core.world.generators.GeneratorPlugin;
import org.mvplugins.multiverse.core.world.generators.GeneratorProvider;

import static org.mvplugins.multiverse.core.utils.StringFormatter.addonToCommaSeperated;
import static org.mvplugins.multiverse.core.utils.StringFormatter.addOnToCommaSeparated;

@Service
public class MVCommandCompletions extends PaperCommandCompletions {
Expand Down Expand Up @@ -163,7 +163,7 @@ private Collection<String> completeWithPreconditions(
}
}
if (context.hasConfig("multiple")) {
return addonToCommaSeperated(context.getInput(), handler.getCompletions(context));
return addOnToCommaSeparated(context.getInput(), handler.getCompletions(context));
}
return handler.getCompletions(context);
}
Expand Down Expand Up @@ -334,7 +334,7 @@ private Collection<String> suggestPlayersArray(BukkitCommandCompletionContext co
matchedPlayers.add(name);
}
}
return addonToCommaSeperated(context.getInput(), matchedPlayers);
return addOnToCommaSeparated(context.getInput(), matchedPlayers);
}

private Collection<String> suggestSpawnCategoryPropsName(BukkitCommandCompletionContext context) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@

import org.mvplugins.multiverse.core.command.LegacyAliasCommand;
import org.mvplugins.multiverse.core.command.MVCommandIssuer;
import org.mvplugins.multiverse.core.command.MVCommandManager;
import org.mvplugins.multiverse.core.command.flag.CommandFlag;
import org.mvplugins.multiverse.core.command.flag.CommandFlagsManager;
import org.mvplugins.multiverse.core.command.flag.CommandValueFlag;
import org.mvplugins.multiverse.core.command.flag.FlagBuilder;
import org.mvplugins.multiverse.core.command.flag.ParsedCommandFlags;
import org.mvplugins.multiverse.core.locale.MVCorei18n;
import org.mvplugins.multiverse.core.locale.message.MessageReplacement.Replace;
import org.mvplugins.multiverse.core.utils.StringFormatter;
import org.mvplugins.multiverse.core.utils.result.Attempt.Failure;
import org.mvplugins.multiverse.core.world.LoadedMultiverseWorld;
import org.mvplugins.multiverse.core.world.WorldManager;
Expand All @@ -53,7 +53,7 @@ class CreateCommand extends CoreCommand {
@CommandPermission("multiverse.core.create")
@CommandCompletion("@empty @environments @flags:groupName=" + Flags.NAME)
@Syntax("<name> <environment> [--seed <seed> --generator <generator[:id]> --world-type <worldtype> --adjust-spawn "
+ "--no-structures --biome <biome>]")
+ "--no-structures --biome <biome> --properties <prop1=value1,prop2=value2,...>]")
@Description("{@@mv-core.create.description}")
void onCreateCommand(
MVCommandIssuer issuer,
Expand All @@ -68,7 +68,7 @@ void onCreateCommand(

@Optional
@Syntax("[--seed <seed> --generator <generator[:id]> --world-type <worldtype> --adjust-spawn "
+ "--no-structures --biome <biome>]")
+ "--no-structures --biome <biome> --properties <prop1=value1,prop2=value2,...>]")
@Description("{@@mv-core.create.flags.description}")
String[] flagArray) {
ParsedCommandFlags parsedFlags = flags.parse(flagArray);
Expand All @@ -78,14 +78,15 @@ void onCreateCommand(
issuer.sendInfo(MVCorei18n.CREATE_LOADING);

worldManager.createWorld(CreateWorldOptions.worldName(worldName)
.biome(parsedFlags.flagValue(flags.biome, ""))
.environment(environment)
.seed(parsedFlags.flagValue(flags.seed))
.worldType(parsedFlags.flagValue(flags.worldType, WorldType.NORMAL))
.useSpawnAdjust(!parsedFlags.hasFlag(flags.noAdjustSpawn))
.generator(parsedFlags.flagValue(flags.generator, ""))
.generatorSettings(parsedFlags.flagValue(flags.generatorSettings, ""))
.generateStructures(!parsedFlags.hasFlag(flags.noStructures)))
.biome(parsedFlags.flagValue(flags.biome, ""))
.environment(environment)
.seed(parsedFlags.flagValue(flags.seed))
.worldType(parsedFlags.flagValue(flags.worldType, WorldType.NORMAL))
.useSpawnAdjust(!parsedFlags.hasFlag(flags.noAdjustSpawn))
.generator(parsedFlags.flagValue(flags.generator, ""))
.generatorSettings(parsedFlags.flagValue(flags.generatorSettings, ""))
.generateStructures(!parsedFlags.hasFlag(flags.noStructures))
.worldPropertyStrings(StringFormatter.parseCSVMap(parsedFlags.flagValue(flags.properties))))
.onSuccess(newWorld -> messageSuccess(issuer, newWorld))
.onFailure(failure -> messageFailure(issuer, failure));
}
Expand Down Expand Up @@ -180,6 +181,10 @@ private Flags(
.addAlias("-b")
.completion(input -> biomeProviderFactory.suggestBiomeString(input))
.build());

private final CommandValueFlag<String> properties = flag(CommandValueFlag.builder("--properties", String.class)
.addAlias("-p")
.build());
}

@Service
Expand Down
20 changes: 20 additions & 0 deletions src/main/java/org/mvplugins/multiverse/core/config/CoreConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,16 @@
return configHandle.get(configNodes.enforceFlight);
}

@ApiStatus.AvailableSince("5.5")

Check warning on line 189 in src/main/java/org/mvplugins/multiverse/core/config/CoreConfig.java

View workflow job for this annotation

GitHub Actions / checkstyle / checkstyle

[checkstyle] reported by reviewdog 🐶 Missing a Javadoc comment. Raw Output: /github/workspace/./src/main/java/org/mvplugins/multiverse/core/config/CoreConfig.java:189:5: warning: Missing a Javadoc comment. (com.puppycrawl.tools.checkstyle.checks.javadoc.MissingJavadocMethodCheck)
public Try<Void> setGamemodeAndFlightEnforceDelay(int delayTicks) {
return configHandle.set(configNodes.gamemodeAndFlightEnforceDelay, delayTicks);
}

@ApiStatus.AvailableSince("5.5")
public int getGamemodeAndFlightEnforceDelay() {
return configHandle.get(configNodes.gamemodeAndFlightEnforceDelay);
}

@ApiStatus.AvailableSince("5.3")
public Try<Void> setApplyEntitySpawnRate(boolean applyEntitySpawnRate) {
return configHandle.set(configNodes.applyEntitySpawnRate, applyEntitySpawnRate);
Expand Down Expand Up @@ -641,6 +651,16 @@
return configHandle.get(configNodes.eventPriorityPlayerTeleport);
}

@ApiStatus.AvailableSince("5.5")
public Try<Void> setEventPriorityPlayerWorldChange(EventPriority eventPriorityPlayerWorldChange) {
return configHandle.set(configNodes.eventPriorityPlayerWorldChange, eventPriorityPlayerWorldChange);
}

@ApiStatus.AvailableSince("5.5")
public EventPriority getEventPriorityPlayerWorldChange() {
return configHandle.get(configNodes.eventPriorityPlayerWorldChange);
}

public Try<Void> setBukkitYmlPath(String bukkitYmlPath) {
return configHandle.set(configNodes.bukkitYmlPath, bukkitYmlPath);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,16 @@
.name("enforce-flight")
.build());

final ConfigNode<Integer> gamemodeAndFlightEnforceDelay = node(ConfigNode.builder("world.gamemode-and-flight-enforce-delay", Integer.class)

Check warning on line 138 in src/main/java/org/mvplugins/multiverse/core/config/CoreConfigNodes.java

View workflow job for this annotation

GitHub Actions / checkstyle / checkstyle

[checkstyle] reported by reviewdog 🐶 Line is longer than 120 characters (found 143). Raw Output: /github/workspace/./src/main/java/org/mvplugins/multiverse/core/config/CoreConfigNodes.java:138:0: warning: Line is longer than 120 characters (found 143). (com.puppycrawl.tools.checkstyle.checks.sizes.LineLengthCheck)
.comment("")
.comment("Sets the delay in ticks before Multiverse enforces gamemode and flight ability on world change.")
.comment("Increase this value if you are experiencing issues with other plugins overriding gamemode or flight ability.")

Check warning on line 141 in src/main/java/org/mvplugins/multiverse/core/config/CoreConfigNodes.java

View workflow job for this annotation

GitHub Actions / checkstyle / checkstyle

[checkstyle] reported by reviewdog 🐶 Line is longer than 120 characters (found 132). Raw Output: /github/workspace/./src/main/java/org/mvplugins/multiverse/core/config/CoreConfigNodes.java:141:0: warning: Line is longer than 120 characters (found 132). (com.puppycrawl.tools.checkstyle.checks.sizes.LineLengthCheck)
.comment("Or set to 0 to enforce immediately during world change event.")
.defaultValue(1)
.name("gamemode-and-flight-enforce-delay")
.suggester((sender -> List.of("0", "1", "2", "5", "10")))

Check warning on line 145 in src/main/java/org/mvplugins/multiverse/core/config/CoreConfigNodes.java

View workflow job for this annotation

GitHub Actions / checkstyle / checkstyle

[checkstyle] reported by reviewdog 🐶 Unnecessary parentheses around assignment right-hand side. Raw Output: /github/workspace/./src/main/java/org/mvplugins/multiverse/core/config/CoreConfigNodes.java:145:24: warning: Unnecessary parentheses around assignment right-hand side. (com.puppycrawl.tools.checkstyle.checks.coding.UnnecessaryParenthesesCheck)
.build());

final ConfigNode<Boolean> applyEntitySpawnRate = node(ConfigNode.builder("world.apply-entity-spawn-rate", Boolean.class)
.comment("")
.comment("Sets whether Multiverse will apply the world's entity `tick-rate` config in worlds.yml.")
Expand Down Expand Up @@ -545,6 +555,18 @@
"full effect after a server restart."))
.build());

final ConfigNode<EventPriority> eventPriorityPlayerWorldChange = node(ConfigNode.builder("event-priority.player-changed-world", EventPriority.class)

Check warning on line 558 in src/main/java/org/mvplugins/multiverse/core/config/CoreConfigNodes.java

View workflow job for this annotation

GitHub Actions / checkstyle / checkstyle

[checkstyle] reported by reviewdog 🐶 Line is longer than 120 characters (found 152). Raw Output: /github/workspace/./src/main/java/org/mvplugins/multiverse/core/config/CoreConfigNodes.java:558:0: warning: Line is longer than 120 characters (found 152). (com.puppycrawl.tools.checkstyle.checks.sizes.LineLengthCheck)
.defaultValue(EventPriority.NORMAL)
.name("event-priority-player-changed-world")
.comment("")
.comment("This config option defines the priority for the PlayerChangedWorldEvent.")
.onLoadAndChange((oldValue, newValue) ->
eventPriorityMapper.get().setPriority("mvcore-player-changed-world", newValue))
.onChange((sender, oldValue, newValue) ->
sender.sendMessage(ChatColor.YELLOW + "'event-priority.player-changed-world' config option will only take " +

Check warning on line 566 in src/main/java/org/mvplugins/multiverse/core/config/CoreConfigNodes.java

View workflow job for this annotation

GitHub Actions / checkstyle / checkstyle

[checkstyle] reported by reviewdog 🐶 '+' should be on a new line. Raw Output: /github/workspace/./src/main/java/org/mvplugins/multiverse/core/config/CoreConfigNodes.java:566:129: warning: '+' should be on a new line. (com.puppycrawl.tools.checkstyle.checks.whitespace.OperatorWrapCheck)

Check warning on line 566 in src/main/java/org/mvplugins/multiverse/core/config/CoreConfigNodes.java

View workflow job for this annotation

GitHub Actions / checkstyle / checkstyle

[checkstyle] reported by reviewdog 🐶 Line is longer than 120 characters (found 129). Raw Output: /github/workspace/./src/main/java/org/mvplugins/multiverse/core/config/CoreConfigNodes.java:566:0: warning: Line is longer than 120 characters (found 129). (com.puppycrawl.tools.checkstyle.checks.sizes.LineLengthCheck)
"full effect after a server restart."))
.build());

private final ConfigHeaderNode miscHeader = node(ConfigHeaderNode.builder("misc")
.comment("")
.comment("")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,9 @@ private void setDefaults() {
private void setDefaultSuggester() {
if (itemSuggester instanceof SenderNodeSuggester senderItemSuggester) {
this.suggester = (SenderNodeSuggester)(sender, input) ->
StringFormatter.addonToCommaSeperated(input, senderItemSuggester.suggest(sender, input));
StringFormatter.addOnToCommaSeparated(input, senderItemSuggester.suggest(sender, input));
} else {
this.suggester = input -> StringFormatter.addonToCommaSeperated(input, itemSuggester.suggest(input));
this.suggester = input -> StringFormatter.addOnToCommaSeparated(input, itemSuggester.suggest(input));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@

package org.mvplugins.multiverse.core.listeners;

import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

import com.dumptruckman.minecraft.util.Logging;
import io.vavr.control.Option;
Expand Down Expand Up @@ -257,9 +255,9 @@
* @param event The Event that was fired.
*/
@EventMethod
@DefaultEventPriority(EventPriority.MONITOR)
@EventPriorityKey("mvcore-player-changed-world")
@DefaultEventPriority(EventPriority.NORMAL)
void playerChangedWorld(PlayerChangedWorldEvent event) {
// Permissions now determine whether or not to handle a gamemode.
this.handleGameModeAndFlight(event.getPlayer(), event.getPlayer().getWorld());
}

Expand Down Expand Up @@ -402,21 +400,31 @@
}

/**
* Handles the gamemode for the specified {@link Player}.
* Handles the gamemode for the specified {@link Player}. Delays the enforcement if configured to do so
* to ensure multiverse has final say over other plugins changing gamemodes.
*
* @param player The {@link Player}.
* @param world The {@link World} the player is supposed to be in.
*/
private void handleGameModeAndFlight(final Player player, World world) {
// We perform this task one tick later to MAKE SURE that the player actually reaches the
// destination world, otherwise we'd be changing the player mode if they havent moved anywhere.
this.server.getScheduler().runTaskLater(this.plugin, () -> {
if (!player.isOnline() || !player.getWorld().equals(world)) {
return;
}
Logging.finer("Handling gamemode and flight for player %s in world '%s'", player.getName(), world.getName());
enforcementHandler.handleFlightEnforcement(player);
enforcementHandler.handleGameModeEnforcement(player);
}, 1L);
if (config.getGamemodeAndFlightEnforceDelay() <= 0) {
doGameModeAndFlightEnforcement(player, world);
return;
}
server.getScheduler().runTaskLater(
this.plugin,
() -> doGameModeAndFlightEnforcement(player, world),
config.getGamemodeAndFlightEnforceDelay()
);

Check warning on line 418 in src/main/java/org/mvplugins/multiverse/core/listeners/MVPlayerListener.java

View workflow job for this annotation

GitHub Actions / checkstyle / checkstyle

[checkstyle] reported by reviewdog 🐶 ')' should be on the previous line. Raw Output: /github/workspace/./src/main/java/org/mvplugins/multiverse/core/listeners/MVPlayerListener.java:418:9: warning: ')' should be on the previous line. (SeparatorWrapEol)
}

private void doGameModeAndFlightEnforcement(Player player, World world) {
if (!player.isOnline() || !player.getWorld().equals(world)) {
Logging.finer("Player %s is no longer online or not in the expected world '%s'", player.getName(), world.getName());

Check warning on line 423 in src/main/java/org/mvplugins/multiverse/core/listeners/MVPlayerListener.java

View workflow job for this annotation

GitHub Actions / checkstyle / checkstyle

[checkstyle] reported by reviewdog 🐶 Line is longer than 120 characters (found 128). Raw Output: /github/workspace/./src/main/java/org/mvplugins/multiverse/core/listeners/MVPlayerListener.java:423:0: warning: Line is longer than 120 characters (found 128). (com.puppycrawl.tools.checkstyle.checks.sizes.LineLengthCheck)
return;
}
Logging.finer("Handling gamemode and flight for player %s in world '%s'", player.getName(), world.getName());
enforcementHandler.handleFlightEnforcement(player);
enforcementHandler.handleGameModeEnforcement(player);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ public boolean canSpawnAtLocationSafely(@NotNull Location location) {
*/
public boolean canSpawnAtBlockSafely(@NotNull Block block) {
Logging.finest("Checking spawn safety for location: %s, %s, %s", block.getX(), block.getY(), block.getZ());
if (!block.getWorld().getWorldBorder().isInside(block.getLocation())) {
Logging.finest("Location is outside world border.");
return false;
}
if (isUnsafeSpawnBody(block)) {
// Player body will be stuck in solid
Logging.finest("Unsafe location for player's body: " + block);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@

import com.google.common.base.Strings;
import com.google.common.collect.Sets;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.Unmodifiable;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -71,11 +74,30 @@

/**
* Appends a list of suggestions to the end of the input string, separated by commas.
*
* @param input The current input
* @param addons The autocomplete suggestions
* @return A collection of suggestions with the next suggestion appended
*
* @deprecated Method name has a spelling error. Use {@link #addOnToCommaSeparated(String, Collection)} instead.
*/
@Deprecated(forRemoval = true, since = "5.5")
@ApiStatus.ScheduledForRemoval(inVersion = "6.0")
public static Collection<String> addonToCommaSeperated(@Nullable String input, @NotNull Collection<String> addons) {
return addOnToCommaSeparated(input, addons);
}

/**
* Appends a list of suggestions to the end of the input string, separated by commas.
*
* @param input The current input
* @param addons The autocomplete suggestions
* @return A collection of suggestions with the next suggestion appended
*
* @since 5.5
*/
@ApiStatus.AvailableSince("5.5")
public static Collection<String> addOnToCommaSeparated(@Nullable String input, @NotNull Collection<String> addons) {
if (Strings.isNullOrEmpty(input)) {
return addons;
}
Expand Down Expand Up @@ -142,4 +164,24 @@
public static String quoteMultiWordString(String input) {
return input.contains(" ") ? "\"" + input + "\"" : input;
}

/**
* Parses a CSV string of key=value pairs into a map.
* E.g. "key1=value1,key2=value2" -> {key1=value1, key2=value2}
*
* @param input The CSV string to parse
* @return The parsed map
*
* @since 5.5
*/
@ApiStatus.AvailableSince("5.5")
public static @Unmodifiable Map<String, String> parseCSVMap(@Nullable String input) {

Check warning on line 178 in src/main/java/org/mvplugins/multiverse/core/utils/StringFormatter.java

View workflow job for this annotation

GitHub Actions / checkstyle / checkstyle

[checkstyle] reported by reviewdog 🐶 Abbreviation in name 'parseCSVMap' must contain no more than '1' consecutive capital letters. Raw Output: /github/workspace/./src/main/java/org/mvplugins/multiverse/core/utils/StringFormatter.java:178:53: warning: Abbreviation in name 'parseCSVMap' must contain no more than '1' consecutive capital letters. (com.puppycrawl.tools.checkstyle.checks.naming.AbbreviationAsWordInNameCheck)
if (Strings.isNullOrEmpty(input)) {
return Map.of();
}
return REPatterns.COMMA.splitAsStream(input)
.map(s -> REPatterns.EQUALS.split(s, 2))
.filter(parts -> parts.length == 2)
.collect(Collectors.toUnmodifiableMap(parts -> parts[0], parts -> parts[1]));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@
import java.util.Arrays;
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;
Expand Down Expand Up @@ -278,7 +276,16 @@ private Attempt<LoadedMultiverseWorld, CreateFailureReason> doCreateWorld(
generatorString,
options.biome(),
options.useSpawnAdjust()))
.peek(loadedWorld -> pluginManager.callEvent(new MVWorldCreatedEvent(loadedWorld)));
.peek(loadedWorld -> postCreateWorld(loadedWorld, options));
}

private void postCreateWorld(LoadedMultiverseWorld loadedWorld, CreateWorldOptions options) {
options.worldPropertyStrings().forEach((key, value) -> loadedWorld.getStringPropertyHandle()
.setPropertyString(key, value)
.onFailure(failure -> Logging.warning("Failed to set property '%s' to '%s' for world %s: %s",
key, value, loadedWorld.getName(), failure.getMessage())));
pluginManager.callEvent(new MVWorldCreatedEvent(loadedWorld));
saveWorldsConfig();
}

/**
Expand Down
Loading
Loading