Implement setup steps

This commit is contained in:
Hannes Greule 2020-06-02 18:28:14 +02:00 committed by Alexander Söderberg
parent c5bfde330f
commit b15c48e074
9 changed files with 216 additions and 34 deletions

View File

@ -29,6 +29,7 @@ import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.Captions;
import com.plotsquared.core.configuration.ConfigurationNode;
import com.plotsquared.core.configuration.ConfigurationUtil;
import com.plotsquared.core.configuration.StaticCaption;
import com.plotsquared.core.events.TeleportCause;
import com.plotsquared.core.generator.GeneratorWrapper;
import com.plotsquared.core.player.PlotPlayer;
@ -38,6 +39,8 @@ import com.plotsquared.core.plot.PlotAreaType;
import com.plotsquared.core.plot.PlotId;
import com.plotsquared.core.plot.SetupObject;
import com.plotsquared.core.plot.message.PlotMessage;
import com.plotsquared.core.setup.SetupProcess;
import com.plotsquared.core.setup.SetupStep;
import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.SetupUtils;
import com.plotsquared.core.util.StringMan;
@ -91,6 +94,42 @@ public class Setup extends SubCommand {
}
@Override public boolean onCommand(PlotPlayer<?> player, String[] args) {
SetupProcess process = player.getMeta("setup");
if (process == null) {
if (args.length > 0) {
// TODO use old behaviour?
MainUtil.sendMessage(player, "Use /plot setup to start the setup");
return true;
}
process = new SetupProcess();
player.setMeta("setup", process);
SetupUtils.manager.updateGenerators();
com.plotsquared.core.setup.SetupStep step = process.getCurrentStep();
// TODO generalize?
step.announce(player);
displayGenerators(player);
return true;
}
if (args.length == 1) {
if ("back".equalsIgnoreCase(args[0])) {
process.back();
process.getCurrentStep().announce(player);
} else if ("cancel".equalsIgnoreCase(args[0])) {
player.deleteMeta("setup");
} else {
process.handleInput(player, args[0]);
}
return true;
} else {
process.getCurrentStep().announce(player);
// TODO return only
if (true) {
return true;
}
}
// going through setup
SetupObject object = player.getMeta("setup");
if (object == null) {
@ -354,7 +393,7 @@ public class Setup extends SubCommand {
}
private static final class StepPickGenerator extends SetupStep {
/*private static final class StepPickGenerator extends SetupStep {
@Getter private String generator;
@ -481,6 +520,6 @@ public class Setup extends SubCommand {
}
}
}
}*/
}

View File

@ -319,6 +319,7 @@ public enum Captions implements Caption {
REMOVED_GRANTED_PLOT("$2You used %s0 plot grant(s), you've got $1%s1 $2left", "Economy"),
//</editor-fold>
//<editor-fold desc="Setup">
SETUP_NOT_STARTED("$7No setup started. Use $2/plot setup $7to start a setup process.", "Setup"),
SETUP_INIT("$1Usage: $2/plot setup <value>", "Setup"),
SETUP_STEP("$3[$1Step %s0$3] $1%s1 $2- $1Expecting: $2%s2 $1Default: $2%s3", "Setup"),
SETUP_INVALID_ARG("$2%s0 is not a valid argument for step %s1. To cancel setup use: $1/plot setup cancel", "Setup"),
@ -357,6 +358,11 @@ public enum Captions implements Caption {
SETUP_AREA_MAX_PLOT_ID_ERROR("$7You must choose a valid maximum Plot Id!", "Setup"),
SETUP_AREA_PLOT_ID_GREATER_THAN_MINIMUM("$7The max PlotId must be greater than the minimum!", "Setup"),
//</editor-fold>
//<editor-fold desc=PlotAreaType>
PLOT_AREA_TYPE_NORMAL("Standard plot generation", "PlotAreaType"),
PLOT_AREA_TYPE_AUGMENTED("Plot generation with vanilla terrain", "PlotAreaType"),
PLOT_AREA_TYPE_PARTIAL("Vanilla with clusters of plots", "PlotAreaType"),
//</editor-fold>
//<editor-fold desc="Schematic">
SCHEMATIC_TOO_LARGE("$2The plot is too large for this action!", "Schematics"),
SCHEMATIC_MISSING_ARG("$2You need to specify an argument. Possible values: $1save$2, $1paste $2, $1exportall$2, $1list", "Schematics"),

View File

@ -4,13 +4,17 @@ import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.Caption;
import com.plotsquared.core.configuration.Captions;
import com.plotsquared.core.configuration.ConfigurationNode;
import com.plotsquared.core.events.TeleportCause;
import com.plotsquared.core.generator.GeneratorWrapper;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.PlotArea;
import com.plotsquared.core.plot.PlotAreaTerrainType;
import com.plotsquared.core.plot.PlotAreaType;
import com.plotsquared.core.plot.PlotId;
import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.SetupUtils;
import com.plotsquared.core.util.StringMan;
import com.plotsquared.core.util.WorldUtil;
import lombok.Getter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -24,7 +28,7 @@ import java.util.stream.Collectors;
import static com.plotsquared.core.util.MainUtil.sendMessage;
public enum CommonSetupSteps implements SetupStep {
GENERATOR(Captions.SETUP_INIT) {
CHOOSE_GENERATOR(Captions.SETUP_INIT) {
@Override public SetupStep handleInput(PlotPlayer plotPlayer, PlotAreaBuilder builder, String arg) {
if (!SetupUtils.generators.containsKey(arg)) {
@ -38,18 +42,19 @@ public enum CommonSetupSteps implements SetupStep {
}
builder.generatorName(arg);
sendMessage(plotPlayer, Captions.SETUP_WORLD_TYPE);
return CommonSetupSteps.PLOT_AREA_TYPE; // proceed with next step
return CommonSetupSteps.CHOOSE_PLOT_AREA_TYPE; // proceed with next step
}
@Override public @NotNull Collection<String> getSuggestions() {
@NotNull @Override public Collection<String> getSuggestions() {
return Collections.unmodifiableSet(SetupUtils.generators.keySet());
}
@Override @Nullable public String getDefaultValue() {
@Nullable @Override public String getDefaultValue() {
return PlotSquared.imp().getPluginName();
}
},
PLOT_AREA_TYPE(PlotAreaType.class, Captions.SETUP_WORLD_TYPE) {
CHOOSE_PLOT_AREA_TYPE(PlotAreaType.class, Captions.SETUP_WORLD_TYPE) {
@Override public SetupStep handleInput(PlotPlayer plotPlayer, PlotAreaBuilder builder, String arg) {
boolean withNormal = SetupUtils.generators.get(builder.generatorName()).isFull();
Optional<PlotAreaType> plotAreaType = PlotAreaType.fromString(arg);
@ -78,7 +83,7 @@ public enum CommonSetupSteps implements SetupStep {
if (!builder.settingsNodesWrapper().hasNext()) {
// MainUtil.sendMessage(plotPlayer, Captions.SETUP_WORLD_NAME);
// object.setup_index = 0; TODO what did that do?
return WORLD_NAME; // skip
return CHOOSE_WORLD_NAME; // skip
}
SettingsNodeStep next = builder.settingsNodesWrapper().next();
ConfigurationNode step = next.getConfigurationNode();
@ -105,7 +110,7 @@ public enum CommonSetupSteps implements SetupStep {
return null;
} else {
// MainUtil.sendMessage(plotPlayer, Captions.SETUP_PARTIAL_AREA);
return TERRAIN_TYPE;
return CHOOSE_TERRAIN_TYPE;
}
}
}
@ -114,19 +119,116 @@ public enum CommonSetupSteps implements SetupStep {
return PlotAreaType.NORMAL.toString(); // TODO toLowerCase here?
}
},
TERRAIN_TYPE(PlotAreaTerrainType.class, Captions.SETUP_PARTIAL_AREA) {
@Override
public SetupStep handleInput(PlotPlayer plotPlayer, PlotAreaBuilder builder, String argument) {
return null;
CHOOSE_AREA_ID(Captions.SETUP_AREA_NAME) {
@Override public SetupStep handleInput(PlotPlayer plotPlayer, PlotAreaBuilder builder, String argument) {
if (!StringMan.isAlphanumericUnd(argument)) {
MainUtil.sendMessage(plotPlayer, Captions.SETUP_AREA_NON_ALPHANUMERICAL);
return this;
}
for (PlotArea area : PlotSquared.get().getPlotAreas()) {
if (area.getId() != null && area.getId().equalsIgnoreCase(argument)) {
MainUtil.sendMessage(plotPlayer, Captions.SETUP_AREA_INVALID_ID);
return this;
}
}
builder.areaName(argument);
return CHOOSE_MINIMUM_PLOT_ID;
}
@Override
public @Nullable String getDefaultValue() {
@Nullable @Override public String getDefaultValue() {
return null;
}
},
CHOOSE_MINIMUM_PLOT_ID(Captions.SETUP_AREA_MIN_PLOT_ID) {
@Override public SetupStep handleInput(PlotPlayer plotPlayer, PlotAreaBuilder builder, String argument) {
try {
builder.minimumId(PlotId.fromString(argument));
} catch (IllegalArgumentException ignored) {
MainUtil.sendMessage(plotPlayer, Captions.SETUP_AREA_MIN_PLOT_ID_ERROR);
return this;
} catch (IllegalStateException ignored) {
MainUtil.sendMessage(plotPlayer, Captions.SETUP_AREA_PLOT_ID_GREATER_THAN_MINIMUM);
return this;
}
return CHOOSE_MAXIMUM_PLOT_ID;
}
@Override public String getDefaultValue() {
return "0;0";
}
},
CHOOSE_MAXIMUM_PLOT_ID(Captions.SETUP_AREA_MAX_PLOT_ID) {
@Override public SetupStep handleInput(PlotPlayer plotPlayer, PlotAreaBuilder builder, String argument) {
try {
builder.maximumId(PlotId.fromString(argument));
} catch (IllegalArgumentException ignored) {
MainUtil.sendMessage(plotPlayer, Captions.SETUP_AREA_MAX_PLOT_ID_ERROR);
return this;
} catch (IllegalStateException ignored) {
MainUtil.sendMessage(plotPlayer, Captions.SETUP_AREA_PLOT_ID_GREATER_THAN_MINIMUM);
return this;
}
return CHOOSE_TERRAIN_TYPE;
}
@Override public String getDefaultValue() {
return "0;0";
}
},
CHOOSE_TERRAIN_TYPE(PlotAreaTerrainType.class, Captions.SETUP_PARTIAL_AREA) {
@Override public SetupStep handleInput(PlotPlayer plotPlayer, PlotAreaBuilder builder, String argument) {
Optional<PlotAreaTerrainType> optTerrain;
if (!(optTerrain = PlotAreaTerrainType.fromString(argument))
.isPresent()) {
MainUtil.sendMessage(plotPlayer, Captions.SETUP_PARTIAL_AREA_ERROR, Captions.SETUP_PARTIAL_AREA);
return this;
}
builder.terrainType(optTerrain.get());
if (builder.settingsNodesWrapper() == null) {
builder.settingsNodesWrapper(CommonSetupSteps.wrap(builder.plotManager()));
}
SettingsNodesWrapper wrapper = builder.settingsNodesWrapper();
// TODO return CHOOSE_WORLD_NAME if !hasNext
return wrapper.hasNext() ? wrapper.next() : wrapper.getAfterwards();
}
@Nullable @Override public String getDefaultValue() {
return PlotAreaTerrainType.NONE.toString(); // TODO toLowerCase here?
}
},
WORLD_NAME(Captions.SETUP_WORLD_NAME) {
CHOOSE_WORLD_NAME(Captions.SETUP_WORLD_NAME) {
@Override public SetupStep handleInput(PlotPlayer plotPlayer, PlotAreaBuilder builder, String argument) {
if (!isValidWorldName(argument)) {
MainUtil.sendMessage(plotPlayer, Captions.SETUP_WORLD_NAME_FORMAT + argument);
return this;
}
if (WorldUtil.IMP.isWorld(argument)) {
if (PlotSquared.get().hasPlotArea(argument)) {
MainUtil.sendMessage(plotPlayer, Captions.SETUP_WORLD_NAME_TAKEN);
return this;
}
MainUtil.sendMessage(plotPlayer, Captions.SETUP_WORLD_APPLY_PLOTSQUARED);
}
builder.worldName(argument);
plotPlayer.deleteMeta("setup");
String world;
if (builder.setupManager() == null) {
world = SetupUtils.manager.setupWorld(builder);
} else {
world = builder.setupManager().setupWorld(builder);
}
try {
plotPlayer.teleport(WorldUtil.IMP.getSpawn(world), TeleportCause.COMMAND);
} catch (Exception e) {
plotPlayer.sendMessage("&cAn error occurred. See console for more information");
e.printStackTrace();
}
sendMessage(plotPlayer, Captions.SETUP_FINISHED, builder.worldName());
return null;
}
@ -143,21 +245,24 @@ public enum CommonSetupSteps implements SetupStep {
* @param suggestions the input suggestions for this step
* @param description the caption describing this step
*/
CommonSetupSteps(@NotNull Collection<String> suggestions, Caption description) {
CommonSetupSteps(@NotNull Collection<String> suggestions, @NotNull Caption description) {
this.suggestions = suggestions;
this.description = description;
}
CommonSetupSteps(Caption description) {
CommonSetupSteps(@NotNull Caption description) {
this.description = description;
this.suggestions = Collections.emptyList();
}
<E extends Enum<E>> CommonSetupSteps(Class<E> argumentType, Caption description) {
<E extends Enum<E>> CommonSetupSteps(@NotNull Class<E> argumentType, Caption description) {
this(enumToStrings(argumentType), description);
}
@Override
public void announce(PlotPlayer plotPlayer) {
MainUtil.sendMessage(plotPlayer, this.description);
}
private static <E extends Enum<E>> Collection<String> enumToStrings(Class<E> type) {
return Arrays.stream(type.getEnumConstants()).map(e -> e.toString().toLowerCase()).collect(Collectors.toList());
@ -166,11 +271,12 @@ public enum CommonSetupSteps implements SetupStep {
private static SettingsNodesWrapper wrap(String plotManager) {
return new SettingsNodesWrapper(SetupUtils.generators.get(plotManager).getPlotGenerator()
.getNewPlotArea("CheckingPlotSquaredGenerator", null, null, null)
.getSettingNodes());
.getSettingNodes(), CHOOSE_WORLD_NAME);
}
@Override
public void announce(PlotPlayer plotPlayer) {
MainUtil.sendMessage(plotPlayer, this.description);
private static boolean isValidWorldName(String s) {
return s.chars().allMatch((i) -> {
return i == 95 || i == 45 || i >= 97 && i <= 122 || i >= 48 && i <= 57 || i == 46;
});
}
}

View File

@ -3,6 +3,8 @@ package com.plotsquared.core.setup;
import com.plotsquared.core.plot.PlotAreaTerrainType;
import com.plotsquared.core.plot.PlotAreaType;
import com.plotsquared.core.plot.PlotId;
import com.plotsquared.core.util.SetupUtils;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
@ -15,6 +17,25 @@ public class PlotAreaBuilder {
@Getter @Setter private PlotAreaTerrainType terrainType;
@Getter @Setter private String worldName;
@Getter @Setter private String areaName;
@Getter private PlotId minimumId;
@Getter private PlotId maximumId;
@Getter @Setter private SettingsNodesWrapper settingsNodesWrapper;
@Getter @Setter private SetupUtils setupManager;
public void minimumId(PlotId minimumId) {
if (this.maximumId != null
&& (minimumId.getX() >= this.maximumId.getX() || minimumId.getY() >= this.maximumId.getY())) {
throw new IllegalStateException("minId >= maxId");
}
this.minimumId = minimumId;
}
public void maximumId(PlotId maximumId) {
if (this.minimumId != null
&& (this.minimumId.getX() <= maximumId.getX() || this.minimumId.getY() <= maximumId.getY())) {
throw new IllegalStateException("maxId <= minId");
}
this.maximumId = maximumId;
}
}

View File

@ -25,7 +25,7 @@ public class SettingsNodeStep implements SetupStep {
if (this.configurationNode.isValid(argument)) {
this.configurationNode.setValue(argument);
}
return wrapper.next();
return this.wrapper.hasNext() ? wrapper.next() : wrapper.getAfterwards();
}
@NotNull @Override public Collection<String> getSuggestions() {

View File

@ -1,13 +1,16 @@
package com.plotsquared.core.setup;
import com.plotsquared.core.configuration.ConfigurationNode;
import lombok.Getter;
public class SettingsNodesWrapper {
private final ConfigurationNode[] settingsNodes;
@Getter private final ConfigurationNode[] settingsNodes;
@Getter private final SetupStep afterwards;
private int current;
public SettingsNodesWrapper(ConfigurationNode[] settingsNodes) {
public SettingsNodesWrapper(ConfigurationNode[] settingsNodes, SetupStep afterwards) {
this.settingsNodes = settingsNodes;
this.afterwards = afterwards;
this.current = 0;
}

View File

@ -2,18 +2,17 @@ package com.plotsquared.core.setup;
import com.plotsquared.core.player.PlotPlayer;
import java.util.ArrayDeque;
import java.util.Queue;
import java.util.Stack;
public class SetupProcess {
private final PlotAreaBuilder builder;
private final Queue<SetupStep> history;
private final Stack<SetupStep> history;
private SetupStep current;
public SetupProcess() {
this.builder = new PlotAreaBuilder();
this.history = new ArrayDeque<>();
this.current = CommonSetupSteps.GENERATOR;
this.history = new Stack<>();
this.current = CommonSetupSteps.CHOOSE_GENERATOR;
}
public SetupStep getCurrentStep() {
@ -21,14 +20,19 @@ public class SetupProcess {
}
public void handleInput(PlotPlayer plotPlayer, String argument) {
SetupStep previous = this.current;
// TODO null check?
this.current = this.current.handleInput(plotPlayer, this.builder, argument);
// push previous step into history
if (this.current != previous && this.current != null) {
this.history.push(previous);
}
}
public void back() {
if (!this.history.isEmpty()) {
this.current.onBack(this.builder);
this.current = this.history.poll();
this.current = this.history.pop();
}
}
}

View File

@ -16,7 +16,7 @@ public interface SetupStep {
* @param argument the argument given as input
* @return the next step if input was valid, this setup step otherwise
*/
SetupStep handleInput(PlotPlayer plotPlayer, PlotAreaBuilder builder, String argument);
SetupStep handleInput(final PlotPlayer plotPlayer, PlotAreaBuilder builder, String argument);
@NotNull Collection<String> getSuggestions();

View File

@ -28,6 +28,7 @@ package com.plotsquared.core.util;
import com.plotsquared.core.generator.GeneratorWrapper;
import com.plotsquared.core.plot.PlotArea;
import com.plotsquared.core.plot.SetupObject;
import com.plotsquared.core.setup.PlotAreaBuilder;
import java.util.HashMap;
@ -43,5 +44,7 @@ public abstract class SetupUtils {
public abstract String setupWorld(final SetupObject object);
public abstract String setupWorld(final PlotAreaBuilder builder);
public abstract void unload(String world, boolean save);
}