Skip to content

Commit 77382da

Browse files
committed
Add support for customising world properties during world creation
1 parent 588a8e1 commit 77382da

5 files changed

Lines changed: 109 additions & 12 deletions

File tree

src/main/java/org/mvplugins/multiverse/core/commands/CreateCommand.java

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@
1919

2020
import org.mvplugins.multiverse.core.command.LegacyAliasCommand;
2121
import org.mvplugins.multiverse.core.command.MVCommandIssuer;
22-
import org.mvplugins.multiverse.core.command.MVCommandManager;
2322
import org.mvplugins.multiverse.core.command.flag.CommandFlag;
2423
import org.mvplugins.multiverse.core.command.flag.CommandFlagsManager;
2524
import org.mvplugins.multiverse.core.command.flag.CommandValueFlag;
2625
import org.mvplugins.multiverse.core.command.flag.FlagBuilder;
2726
import org.mvplugins.multiverse.core.command.flag.ParsedCommandFlags;
2827
import org.mvplugins.multiverse.core.locale.MVCorei18n;
2928
import org.mvplugins.multiverse.core.locale.message.MessageReplacement.Replace;
29+
import org.mvplugins.multiverse.core.utils.StringFormatter;
3030
import org.mvplugins.multiverse.core.utils.result.Attempt.Failure;
3131
import org.mvplugins.multiverse.core.world.LoadedMultiverseWorld;
3232
import org.mvplugins.multiverse.core.world.WorldManager;
@@ -78,14 +78,15 @@ void onCreateCommand(
7878
issuer.sendInfo(MVCorei18n.CREATE_LOADING);
7979

8080
worldManager.createWorld(CreateWorldOptions.worldName(worldName)
81-
.biome(parsedFlags.flagValue(flags.biome, ""))
82-
.environment(environment)
83-
.seed(parsedFlags.flagValue(flags.seed))
84-
.worldType(parsedFlags.flagValue(flags.worldType, WorldType.NORMAL))
85-
.useSpawnAdjust(!parsedFlags.hasFlag(flags.noAdjustSpawn))
86-
.generator(parsedFlags.flagValue(flags.generator, ""))
87-
.generatorSettings(parsedFlags.flagValue(flags.generatorSettings, ""))
88-
.generateStructures(!parsedFlags.hasFlag(flags.noStructures)))
81+
.biome(parsedFlags.flagValue(flags.biome, ""))
82+
.environment(environment)
83+
.seed(parsedFlags.flagValue(flags.seed))
84+
.worldType(parsedFlags.flagValue(flags.worldType, WorldType.NORMAL))
85+
.useSpawnAdjust(!parsedFlags.hasFlag(flags.noAdjustSpawn))
86+
.generator(parsedFlags.flagValue(flags.generator, ""))
87+
.generatorSettings(parsedFlags.flagValue(flags.generatorSettings, ""))
88+
.generateStructures(!parsedFlags.hasFlag(flags.noStructures))
89+
.worldPropertyStrings(StringFormatter.parseCSVMap(parsedFlags.flagValue(flags.properties))))
8990
.onSuccess(newWorld -> messageSuccess(issuer, newWorld))
9091
.onFailure(failure -> messageFailure(issuer, failure));
9192
}
@@ -180,6 +181,10 @@ private Flags(
180181
.addAlias("-b")
181182
.completion(input -> biomeProviderFactory.suggestBiomeString(input))
182183
.build());
184+
185+
private final CommandValueFlag<String> properties = flag(CommandValueFlag.builder("--properties", String.class)
186+
.addAlias("-p")
187+
.build());
183188
}
184189

185190
@Service

src/main/java/org/mvplugins/multiverse/core/utils/StringFormatter.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@
55
import org.jetbrains.annotations.ApiStatus;
66
import org.jetbrains.annotations.NotNull;
77
import org.jetbrains.annotations.Nullable;
8+
import org.jetbrains.annotations.Unmodifiable;
89

910
import java.util.ArrayList;
1011
import java.util.Arrays;
1112
import java.util.Collection;
1213
import java.util.List;
14+
import java.util.Map;
1315
import java.util.Set;
1416
import java.util.stream.Collectors;
1517

@@ -162,4 +164,24 @@ public static Collection<String> parseQuotesInArgs(String[] args) {
162164
public static String quoteMultiWordString(String input) {
163165
return input.contains(" ") ? "\"" + input + "\"" : input;
164166
}
167+
168+
/**
169+
* Parses a CSV string of key=value pairs into a map.
170+
* E.g. "key1=value1,key2=value2" -> {key1=value1, key2=value2}
171+
*
172+
* @param input The CSV string to parse
173+
* @return The parsed map
174+
*
175+
* @since 5.5
176+
*/
177+
@ApiStatus.AvailableSince("5.5")
178+
public static @Unmodifiable Map<String, String> parseCSVMap(@Nullable String input) {
179+
if (Strings.isNullOrEmpty(input)) {
180+
return Map.of();
181+
}
182+
return REPatterns.COMMA.splitAsStream(input)
183+
.map(s -> REPatterns.EQUALS.split(s, 2))
184+
.filter(parts -> parts.length == 2)
185+
.collect(Collectors.toUnmodifiableMap(parts -> parts[0], parts -> parts[1]));
186+
}
165187
}

src/main/java/org/mvplugins/multiverse/core/world/WorldManager.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,7 @@
66
import java.util.Arrays;
77
import java.util.Collection;
88
import java.util.Collections;
9-
import java.util.HashMap;
109
import java.util.List;
11-
import java.util.Locale;
1210
import java.util.Map;
1311
import java.util.Objects;
1412
import java.util.concurrent.atomic.AtomicReference;
@@ -278,7 +276,16 @@ private Attempt<LoadedMultiverseWorld, CreateFailureReason> doCreateWorld(
278276
generatorString,
279277
options.biome(),
280278
options.useSpawnAdjust()))
281-
.peek(loadedWorld -> pluginManager.callEvent(new MVWorldCreatedEvent(loadedWorld)));
279+
.peek(loadedWorld -> postCreateWorld(loadedWorld, options));
280+
}
281+
282+
private void postCreateWorld(LoadedMultiverseWorld loadedWorld, CreateWorldOptions options) {
283+
options.worldPropertyStrings().forEach((key, value) -> loadedWorld.getStringPropertyHandle()
284+
.setPropertyString(key, value)
285+
.onFailure(failure -> Logging.warning("Failed to set property '%s' to '%s' for world %s: %s",
286+
key, value, loadedWorld.getName(), failure.getMessage())));
287+
pluginManager.callEvent(new MVWorldCreatedEvent(loadedWorld));
288+
saveWorldsConfig();
282289
}
283290

284291
/**

src/main/java/org/mvplugins/multiverse/core/world/options/CreateWorldOptions.java

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,14 @@
33
import co.aikar.commands.ACFUtil;
44
import org.bukkit.World;
55
import org.bukkit.WorldType;
6+
import org.jetbrains.annotations.ApiStatus;
67
import org.jetbrains.annotations.NotNull;
78
import org.jetbrains.annotations.Nullable;
9+
import org.jetbrains.annotations.UnmodifiableView;
10+
11+
import java.util.Collections;
12+
import java.util.HashMap;
13+
import java.util.Map;
814

915
/**
1016
* Options for customizing the creation of a new world.
@@ -31,6 +37,7 @@ public final class CreateWorldOptions {
3137
private boolean useSpawnAdjust = true;
3238
private WorldType worldType = WorldType.NORMAL;
3339
private boolean doFolderCheck = true;
40+
private final Map<String, String> worldPropertyStrings = new HashMap<>();
3441

3542
/**
3643
* Creates a new {@link CreateWorldOptions} instance with the given world name.
@@ -260,4 +267,44 @@ public boolean useSpawnAdjust() {
260267
public boolean doFolderCheck() {
261268
return doFolderCheck;
262269
}
270+
271+
/**
272+
* Sets a world property string key-value pair. Overwrites any existing key.
273+
*
274+
* @param key The key of the world property string.
275+
* @param value The value of the world property string.
276+
* @return This {@link CreateWorldOptions} instance.
277+
*
278+
* @since 5.5
279+
*/
280+
@ApiStatus.AvailableSince("5.5")
281+
public @NotNull CreateWorldOptions worldPropertyString(@NotNull String key, @Nullable String value) {
282+
this.worldPropertyStrings.put(key, value);
283+
return this;
284+
}
285+
286+
/**
287+
* Sets multiple world property string key-value pairs. Overwrites any existing keys.
288+
*
289+
* @param worldProperties A map of world property string key-value pairs.
290+
* @return This {@link CreateWorldOptions} instance.
291+
*/
292+
@ApiStatus.AvailableSince("5.5")
293+
public @NotNull CreateWorldOptions worldPropertyStrings(@NotNull Map<@NotNull String, @Nullable String> worldProperties) {
294+
this.worldPropertyStrings.putAll(worldProperties);
295+
return this;
296+
}
297+
298+
/**
299+
* Gets an unmodifiable view of the world property strings. Use {@link #worldPropertyString(String, String)} and
300+
* {@link #worldPropertyStrings(Map)} to modify the world property strings.
301+
*
302+
* @return An unmodifiable view of the world property strings.
303+
*
304+
* @since 5.5
305+
*/
306+
@ApiStatus.AvailableSince("5.5")
307+
public @UnmodifiableView @NotNull Map<String, String> worldPropertyStrings() {
308+
return Collections.unmodifiableMap(worldPropertyStrings);
309+
}
263310
}

src/test/java/org/mvplugins/multiverse/core/utils/StringFormatterTest.kt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,20 @@ class StringFormatterTest {
4343
StringFormatter.quoteMultiWordString("test")
4444
)
4545
}
46+
47+
@Test
48+
fun `StringFormatter parseCSVMap`() {
49+
assertEquals(
50+
emptyMap<String, String>(),
51+
StringFormatter.parseCSVMap("")
52+
)
53+
assertEquals(
54+
mapOf("key" to "value"),
55+
StringFormatter.parseCSVMap("key=value")
56+
)
57+
assertEquals(
58+
mapOf("key1" to "value1", "key2" to "value2", "key3" to "value3"),
59+
StringFormatter.parseCSVMap("key1=value1,key2=value2,key3=value3")
60+
)
61+
}
4662
}

0 commit comments

Comments
 (0)