001/* 002 * PlotSquared, a land and world management plugin for Minecraft. 003 * Copyright (C) IntellectualSites <https://intellectualsites.com> 004 * Copyright (C) IntellectualSites team and contributors 005 * 006 * This program is free software: you can redistribute it and/or modify 007 * it under the terms of the GNU General Public License as published by 008 * the Free Software Foundation, either version 3 of the License, or 009 * (at your option) any later version. 010 * 011 * This program is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 014 * GNU General Public License for more details. 015 * 016 * You should have received a copy of the GNU General Public License 017 * along with this program. If not, see <https://www.gnu.org/licenses/>. 018 */ 019package com.plotsquared.core.setup; 020 021import com.plotsquared.core.PlotSquared; 022import com.plotsquared.core.configuration.caption.Caption; 023import com.plotsquared.core.configuration.caption.TranslatableCaption; 024import com.plotsquared.core.events.TeleportCause; 025import com.plotsquared.core.generator.GeneratorWrapper; 026import com.plotsquared.core.player.MetaDataAccess; 027import com.plotsquared.core.player.PlayerMetaDataKeys; 028import com.plotsquared.core.player.PlotPlayer; 029import com.plotsquared.core.plot.PlotArea; 030import com.plotsquared.core.plot.PlotAreaTerrainType; 031import com.plotsquared.core.plot.PlotAreaType; 032import com.plotsquared.core.plot.PlotId; 033import com.plotsquared.core.util.SetupUtils; 034import com.plotsquared.core.util.StringMan; 035import net.kyori.adventure.text.minimessage.Template; 036import org.checkerframework.checker.nullness.qual.NonNull; 037import org.checkerframework.checker.nullness.qual.Nullable; 038 039import java.util.Arrays; 040import java.util.Collection; 041import java.util.Collections; 042import java.util.Optional; 043import java.util.stream.Collectors; 044 045public enum CommonSetupSteps implements SetupStep { 046 CHOOSE_GENERATOR(TranslatableCaption.of("setup.setup_init")) { 047 @Override 048 public SetupStep handleInput(PlotPlayer<?> plotPlayer, PlotAreaBuilder builder, String arg) { 049 if (!SetupUtils.generators.containsKey(arg)) { 050 plotPlayer.sendMessage(TranslatableCaption.of("setup.setup_world_generator_error")); 051 return this; // invalid input -> same setup step 052 } 053 builder.generatorName(arg); 054 return CommonSetupSteps.CHOOSE_PLOT_AREA_TYPE; // proceed with next step 055 } 056 057 058 @Override 059 public Collection<String> getSuggestions() { 060 return Collections.unmodifiableSet(SetupUtils.generators.keySet()); 061 } 062 063 @Nullable 064 @Override 065 public String getDefaultValue() { 066 return PlotSquared.platform().pluginName(); 067 } 068 }, 069 CHOOSE_PLOT_AREA_TYPE(PlotAreaType.class, TranslatableCaption.of("setup.setup_world_type")) { 070 @Override 071 public SetupStep handleInput(PlotPlayer<?> plotPlayer, PlotAreaBuilder builder, String arg) { 072 Optional<PlotAreaType> plotAreaType = PlotAreaType.fromString(arg); 073 if (!plotAreaType.isPresent()) { 074 plotPlayer.sendMessage(TranslatableCaption.of("setup.setup_world_type_error")); 075 return this; 076 } 077 builder.plotAreaType(plotAreaType.get()); 078 GeneratorWrapper<?> gen = SetupUtils.generators.get(builder.generatorName()); 079 if (builder.plotAreaType() == PlotAreaType.NORMAL) { 080 if (builder.settingsNodesWrapper() == null) { 081 builder.plotManager(builder.generatorName()); 082 builder.settingsNodesWrapper(CommonSetupSteps.wrap(builder.plotManager())); 083 SetupUtils.generators.get(builder.plotManager()).getPlotGenerator() 084 .processAreaSetup(builder); 085 } 086 return builder.settingsNodesWrapper().getFirstStep(); 087 } else { 088 if (gen.isFull()) { 089 builder.plotManager(builder.generatorName()); 090 builder.generatorName(null); 091 builder.settingsNodesWrapper(CommonSetupSteps.wrap(builder.plotManager())); 092 SetupUtils.generators.get(builder.plotManager()).getPlotGenerator() 093 .processAreaSetup(builder); 094 } else { 095 builder.plotManager(PlotSquared.platform().pluginName()); 096 plotPlayer.sendMessage(TranslatableCaption.of("setup.setup_world_generator_error")); 097 builder.settingsNodesWrapper(CommonSetupSteps.wrap(builder.plotManager())); 098 // TODO why is processSetup not called here? 099 } 100 if (builder.plotAreaType() == PlotAreaType.PARTIAL) { 101 return CHOOSE_AREA_ID; 102 } else { 103 return CHOOSE_TERRAIN_TYPE; 104 } 105 } 106 } 107 108 @Nullable 109 @Override 110 public String getDefaultValue() { 111 return PlotAreaType.NORMAL.toString(); 112 } 113 }, 114 CHOOSE_AREA_ID(TranslatableCaption.of("setup.setup_area_name")) { 115 @Override 116 public SetupStep handleInput(PlotPlayer<?> plotPlayer, PlotAreaBuilder builder, String argument) { 117 if (!StringMan.isAlphanumericUnd(argument)) { 118 plotPlayer.sendMessage(TranslatableCaption.of("setup.setup_area_non_alphanumerical")); 119 return this; 120 } 121 for (PlotArea area : PlotSquared.get().getPlotAreaManager().getAllPlotAreas()) { 122 if (area.getId() != null && area.getId().equalsIgnoreCase(argument)) { 123 plotPlayer.sendMessage(TranslatableCaption.of("setup.setup_area_invalid_id")); 124 return this; 125 } 126 } 127 builder.areaName(argument); 128 return CHOOSE_MINIMUM_PLOT_ID; 129 } 130 131 @Nullable 132 @Override 133 public String getDefaultValue() { 134 return null; 135 } 136 }, 137 CHOOSE_MINIMUM_PLOT_ID(TranslatableCaption.of("setup.setup_area_min_plot_id")) { 138 @Override 139 public SetupStep handleInput(PlotPlayer<?> plotPlayer, PlotAreaBuilder builder, String argument) { 140 try { 141 builder.minimumId(PlotId.fromString(argument)); 142 } catch (IllegalArgumentException ignored) { 143 plotPlayer.sendMessage(TranslatableCaption.of("setup.setup_area_min_plot_id_error")); 144 return this; 145 } catch (IllegalStateException ignored) { 146 plotPlayer.sendMessage(TranslatableCaption.of("setup.setup_area_plot_id_greater_than_minimum")); 147 return this; 148 } 149 return CHOOSE_MAXIMUM_PLOT_ID; 150 } 151 152 @Override 153 public String getDefaultValue() { 154 return "0;0"; 155 } 156 }, 157 CHOOSE_MAXIMUM_PLOT_ID(TranslatableCaption.of("setup.setup_area_max_plot_id")) { 158 @Override 159 public SetupStep handleInput(PlotPlayer<?> plotPlayer, PlotAreaBuilder builder, String argument) { 160 try { 161 builder.maximumId(PlotId.fromString(argument)); 162 } catch (IllegalArgumentException ignored) { 163 plotPlayer.sendMessage(TranslatableCaption.of("setup.setup_area_max_plot_id_error")); 164 return this; 165 } catch (IllegalStateException ignored) { 166 plotPlayer.sendMessage(TranslatableCaption.of("setup.setup_area_plot_id_greater_than_minimum")); 167 return this; 168 } 169 return CHOOSE_TERRAIN_TYPE; 170 } 171 172 @Override 173 public String getDefaultValue() { 174 return "0;0"; 175 } 176 }, 177 CHOOSE_TERRAIN_TYPE(PlotAreaTerrainType.class, TranslatableCaption.of("setup.setup_partial_area")) { 178 @Override 179 public SetupStep handleInput(PlotPlayer<?> plotPlayer, PlotAreaBuilder builder, String argument) { 180 Optional<PlotAreaTerrainType> optTerrain; 181 if (!(optTerrain = PlotAreaTerrainType.fromString(argument)) 182 .isPresent()) { 183 plotPlayer.sendMessage(TranslatableCaption.of("setup.setup_partial_area_error")); 184 return this; 185 } 186 builder.terrainType(optTerrain.get()); 187 if (builder.settingsNodesWrapper() == null) { 188 builder.settingsNodesWrapper(CommonSetupSteps.wrap(builder.plotManager())); 189 } 190 SettingsNodesWrapper wrapper = builder.settingsNodesWrapper(); 191 return wrapper.getFirstStep(); 192 } 193 194 @Nullable 195 @Override 196 public String getDefaultValue() { 197 return PlotAreaTerrainType.NONE.toString(); 198 } 199 }, 200 CHOOSE_WORLD_NAME(TranslatableCaption.of("setup.setup_world_name")) { 201 @Override 202 public SetupStep handleInput(PlotPlayer<?> plotPlayer, PlotAreaBuilder builder, String argument) { 203 if (!isValidWorldName(argument)) { 204 plotPlayer.sendMessage(TranslatableCaption.of("setup.setup_world_name_format")); 205 return this; 206 } 207 if (PlotSquared.platform().worldUtil().isWorld(argument)) { 208 if (PlotSquared.get().getPlotAreaManager().hasPlotArea(argument)) { 209 plotPlayer.sendMessage(TranslatableCaption.of("setup.setup_world_taken"), Template.of("value", argument)); 210 return this; 211 } 212 plotPlayer.sendMessage(TranslatableCaption.of("setup.setup_world_apply_plotsquared")); 213 } 214 builder.worldName(argument); 215 try (final MetaDataAccess<SetupProcess> setupAccess = plotPlayer.accessTemporaryMetaData( 216 PlayerMetaDataKeys.TEMPORARY_SETUP)) { 217 setupAccess.remove(); 218 } 219 String world; 220 if (builder.setupManager() == null) { 221 world = PlotSquared.platform().injector().getInstance(SetupUtils.class).setupWorld(builder); 222 } else { 223 world = builder.setupManager().setupWorld(builder); 224 } 225 try { 226 plotPlayer.teleport(PlotSquared.platform().worldUtil().getSpawn(world), TeleportCause.COMMAND_SETUP); 227 } catch (Exception e) { 228 plotPlayer.sendMessage(TranslatableCaption.of("errors.error_console")); 229 e.printStackTrace(); 230 } 231 plotPlayer.sendMessage(TranslatableCaption.of("setup.setup_finished")); 232 return null; 233 } 234 235 @Nullable 236 @Override 237 public String getDefaultValue() { 238 return null; 239 } 240 }; 241 242 @NonNull 243 private final Collection<String> suggestions; 244 private final Caption description; 245 246 /** 247 * @param suggestions the input suggestions for this step 248 * @param description the caption describing this step 249 */ 250 CommonSetupSteps(@NonNull Collection<String> suggestions, @NonNull Caption description) { 251 this.suggestions = suggestions; 252 this.description = description; 253 } 254 255 CommonSetupSteps(@NonNull Caption description) { 256 this.description = description; 257 this.suggestions = Collections.emptyList(); 258 } 259 260 <E extends Enum<E>> CommonSetupSteps(@NonNull Class<E> argumentType, Caption description) { 261 this(enumToStrings(argumentType), description); 262 } 263 264 private static <E extends Enum<E>> Collection<String> enumToStrings(Class<E> type) { 265 return Arrays.stream(type.getEnumConstants()).map(e -> e.toString().toLowerCase()).collect(Collectors.toList()); 266 } 267 268 private static SettingsNodesWrapper wrap(String plotManager) { 269 return new SettingsNodesWrapper(SetupUtils.generators.get(plotManager).getPlotGenerator() 270 .getNewPlotArea("CheckingPlotSquaredGenerator", null, null, null) 271 .getSettingNodes(), CHOOSE_WORLD_NAME); 272 } 273 274 private static boolean isValidWorldName(String s) { 275 return s 276 .chars() 277 .allMatch((i) -> i == 95 || i == 45 || i >= 97 && i <= 122 || i >= 65 && i <= 90 || i >= 48 && i <= 57 || i == 46); 278 } 279 280 @Override 281 public void announce(PlotPlayer<?> plotPlayer) { 282 plotPlayer.sendMessage(this.description); 283 } 284 285 public @NonNull Collection<String> getSuggestions() { 286 return this.suggestions; 287 } 288}