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.plot.world; 020 021import com.plotsquared.core.PlotSquared; 022import com.plotsquared.core.configuration.ConfigurationNode; 023import com.plotsquared.core.configuration.ConfigurationSection; 024import com.plotsquared.core.configuration.ConfigurationUtil; 025import com.plotsquared.core.configuration.caption.TranslatableCaption; 026import com.plotsquared.core.configuration.file.YamlConfiguration; 027import com.plotsquared.core.generator.GridPlotWorld; 028import com.plotsquared.core.generator.SingleWorldGenerator; 029import com.plotsquared.core.inject.annotations.WorldConfig; 030import com.plotsquared.core.listener.PlotListener; 031import com.plotsquared.core.location.BlockLoc; 032import com.plotsquared.core.location.Location; 033import com.plotsquared.core.plot.Plot; 034import com.plotsquared.core.plot.PlotAreaType; 035import com.plotsquared.core.plot.PlotId; 036import com.plotsquared.core.plot.PlotManager; 037import com.plotsquared.core.plot.PlotSettings; 038import com.plotsquared.core.plot.flag.FlagContainer; 039import com.plotsquared.core.queue.GlobalBlockQueue; 040import com.plotsquared.core.setup.PlotAreaBuilder; 041import com.plotsquared.core.setup.SettingsNodesWrapper; 042import com.plotsquared.core.util.EventDispatcher; 043import com.plotsquared.core.util.task.TaskManager; 044import org.checkerframework.checker.nullness.qual.NonNull; 045import org.checkerframework.checker.nullness.qual.Nullable; 046 047import java.io.File; 048import java.io.IOException; 049import java.nio.file.Files; 050 051public class SinglePlotArea extends GridPlotWorld { 052 053 @SuppressWarnings({"unused", "FieldCanBeLocal"}) 054 private final EventDispatcher eventDispatcher; 055 @SuppressWarnings({"unused", "FieldCanBeLocal"}) 056 private final PlotListener plotListener; 057 public boolean VOID = false; 058 059 public SinglePlotArea( 060 final @NonNull PlotAreaManager plotAreaManager, 061 final @NonNull EventDispatcher eventDispatcher, 062 final @NonNull PlotListener plotListener, 063 @WorldConfig final @NonNull YamlConfiguration worldConfiguration, 064 final @NonNull GlobalBlockQueue globalBlockQueue 065 ) { 066 super("*", null, new SingleWorldGenerator(plotAreaManager), null, null, 067 worldConfiguration, globalBlockQueue 068 ); 069 this.eventDispatcher = eventDispatcher; 070 this.plotListener = plotListener; 071 this.setAllowSigns(false); 072 this.setDefaultHome(new BlockLoc(Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE)); 073 } 074 075 /** 076 * Returns true if the given string matches the naming system used to identify single plot worlds 077 * e.g. -1_5 represents plot id *;-1;5. "*" being the plot area name given to single plot world 078 * {@link com.plotsquared.core.plot.PlotArea}. 079 * @since 6.1.4 080 */ 081 public static boolean isSinglePlotWorld(String worldName) { 082 int len = worldName.length(); 083 int separator = 0; 084 for (int i = 0; i < len; i++) { 085 switch (worldName.charAt(i)) { 086 case '_': 087 separator++; 088 break; 089 case '-': 090 case '0': 091 case '1': 092 case '2': 093 case '3': 094 case '4': 095 case '5': 096 case '6': 097 case '7': 098 case '8': 099 case '9': 100 break; 101 default: 102 return false; 103 } 104 } 105 return separator == 1; 106 } 107 108 @NonNull 109 @Override 110 protected PlotManager createManager() { 111 return new SinglePlotManager(this); 112 } 113 114 @Override 115 public void loadConfiguration(ConfigurationSection config) { 116 VOID = config.getBoolean("void", false); 117 } 118 119 @Override 120 public void saveConfiguration(ConfigurationSection config) { 121 super.saveConfiguration(config); 122 } 123 124 public void loadWorld(final PlotId id) { 125 String worldName = id.toUnderscoreSeparatedString(); 126 if (PlotSquared.platform().worldUtil().isWorld(worldName)) { 127 return; 128 } 129 PlotAreaBuilder builder = PlotAreaBuilder.newBuilder() 130 .plotManager("PlotSquared:single") 131 .generatorName("PlotSquared:single") 132 .plotAreaType(getType()) 133 .terrainType(getTerrain()) 134 .settingsNodesWrapper(new SettingsNodesWrapper(new ConfigurationNode[0], null)) 135 .worldName(worldName); 136 137 File container = PlotSquared.platform().worldContainer(); 138 File destination = new File(container, worldName); 139 140 {// convert old 141 File oldFile = new File(container, id.toCommaSeparatedString()); 142 if (oldFile.exists()) { 143 oldFile.renameTo(destination); 144 } else { 145 oldFile = new File(container, id.toSeparatedString(".")); 146 if (oldFile.exists()) { 147 oldFile.renameTo(destination); 148 } 149 } 150 } 151 // Duplicate 0;0 152 if (builder.plotAreaType() != PlotAreaType.NORMAL) { 153 if (!destination.exists()) { 154 File src = new File(container, "0_0"); 155 if (src.exists()) { 156 if (!destination.exists()) { 157 destination.mkdirs(); 158 } 159 File levelDat = new File(src, "level.dat"); 160 if (levelDat.exists()) { 161 try { 162 Files.copy( 163 levelDat.toPath(), 164 new File(destination, levelDat.getName()).toPath() 165 ); 166 File data = new File(src, "data"); 167 if (data.exists()) { 168 File dataDest = new File(destination, "data"); 169 dataDest.mkdirs(); 170 for (File file : data.listFiles()) { 171 Files.copy( 172 file.toPath(), 173 new File(dataDest, file.getName()).toPath() 174 ); 175 } 176 } 177 } catch (IOException exception) { 178 exception.printStackTrace(); 179 } 180 } 181 } 182 } 183 } 184 185 try { 186 TaskManager.getPlatformImplementation().sync(() -> { 187 final String name = id.toUnderscoreSeparatedString(); 188 if (!PlotSquared.platform().worldUtil().isWorld(name)) { 189 PlotSquared.platform().setupUtils().setupWorld(builder); 190 } 191 return null; 192 }); 193 } catch (final Exception e) { 194 e.printStackTrace(); 195 } 196 197 // String worldName = plot.getWorldName(); 198 // World world = Bukkit.getWorld(worldName); 199 // if (world != null) { 200 // return world; 201 // } 202 // WorldCreator wc = new WorldCreator(worldName); 203 // wc.generator("PlotSquared:single"); 204 // wc.environment(World.Environment.NORMAL); 205 // wc.type(WorldType.FLAT); 206 // return AsyncWorld.create(wc); 207 } 208 209 210 @Override 211 public ConfigurationNode[] getSettingNodes() { 212 return new ConfigurationNode[]{ 213 new ConfigurationNode( 214 "void", 215 this.VOID, 216 TranslatableCaption.of("setup.singleplotarea_void_world"), 217 ConfigurationUtil.BOOLEAN 218 )}; 219 } 220 221 @Nullable 222 @Override 223 public Plot getOwnedPlot(final @NonNull Location location) { 224 PlotId pid = PlotId.fromStringOrNull(location.getWorldName()); 225 Plot plot = pid == null ? null : this.plots.get(pid); 226 return plot == null ? null : plot.getBasePlot(false); 227 } 228 229 @Nullable 230 @Override 231 public Plot getOwnedPlotAbs(@NonNull Location location) { 232 PlotId pid = PlotId.fromStringOrNull(location.getWorldName()); 233 return pid == null ? null : plots.get(pid); 234 } 235 236 @Nullable 237 @Override 238 public Plot getPlot(final @NonNull Location location) { 239 PlotId pid = PlotId.fromStringOrNull(location.getWorldName()); 240 return pid == null ? null : getPlot(pid); 241 } 242 243 @Nullable 244 @Override 245 public Plot getPlotAbs(final @NonNull Location location) { 246 final PlotId pid = PlotId.fromStringOrNull(location.getWorldName()); 247 return pid == null ? null : getPlotAbs(pid); 248 } 249 250 public boolean addPlot(@NonNull Plot plot) { 251 plot = adapt(plot); 252 return super.addPlot(plot); 253 } 254 255 @Override 256 public boolean addPlotAbs(@NonNull Plot plot) { 257 plot = adapt(plot); 258 return super.addPlotAbs(plot); 259 } 260 261 @Override 262 public boolean addPlotIfAbsent(@NonNull Plot plot) { 263 plot = adapt(plot); 264 return super.addPlotIfAbsent(plot); 265 } 266 267 @Override 268 public boolean allowSigns() { 269 return false; // do not create signs for single plots 270 } 271 272 @SuppressWarnings("deprecation") 273 protected Plot adapt(Plot p) { 274 if (p instanceof SinglePlot) { 275 return p; 276 } 277 PlotSettings s = p.getSettings(); 278 279 final FlagContainer oldContainer = p.getFlagContainer(); 280 p = new SinglePlot(p.getId(), p.getOwnerAbs(), p.getTrusted(), p.getMembers(), 281 p.getDenied(), s.getAlias(), s.getPosition(), null, this, s.getMerged(), 282 p.getTimestamp(), p.temp 283 ); 284 p.getFlagContainer().addAll(oldContainer); 285 286 return p; 287 } 288 289 public @Nullable Plot getPlotAbs(final @NonNull PlotId id) { 290 Plot plot = getOwnedPlotAbs(id); 291 if (plot == null) { 292 return new SinglePlot(this, id); 293 } 294 return plot; 295 } 296 297 public @Nullable Plot getPlot(@NonNull PlotId id) { 298 // TODO 299 Plot plot = getOwnedPlotAbs(id); 300 if (plot == null) { 301 return new SinglePlot(this, id); 302 } 303 return plot.getBasePlot(false); 304 } 305 306}