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.command; 020 021import com.google.inject.Inject; 022import com.plotsquared.core.configuration.Settings; 023import com.plotsquared.core.configuration.caption.StaticCaption; 024import com.plotsquared.core.configuration.caption.TranslatableCaption; 025import com.plotsquared.core.permissions.Permission; 026import com.plotsquared.core.player.MetaDataAccess; 027import com.plotsquared.core.player.PlayerMetaDataKeys; 028import com.plotsquared.core.player.PlotPlayer; 029import com.plotsquared.core.plot.Plot; 030import com.plotsquared.core.plot.PlotArea; 031import com.plotsquared.core.plot.PlotId; 032import com.plotsquared.core.plot.schematic.Schematic; 033import com.plotsquared.core.plot.world.PlotAreaManager; 034import com.plotsquared.core.util.SchematicHandler; 035import com.plotsquared.core.util.TimeUtil; 036import com.plotsquared.core.util.task.RunnableVal; 037import com.plotsquared.core.util.task.TaskManager; 038import net.kyori.adventure.text.minimessage.Template; 039import org.checkerframework.checker.nullness.qual.NonNull; 040 041import java.net.MalformedURLException; 042import java.net.URL; 043import java.util.Collections; 044import java.util.List; 045 046@CommandDeclaration(command = "load", 047 aliases = "restore", 048 category = CommandCategory.SCHEMATIC, 049 requiredType = RequiredType.NONE, 050 permission = "plots.load", 051 usage = "/plot load") 052public class Load extends SubCommand { 053 054 private final PlotAreaManager plotAreaManager; 055 private final SchematicHandler schematicHandler; 056 057 @Inject 058 public Load( 059 final @NonNull PlotAreaManager plotAreaManager, 060 final @NonNull SchematicHandler schematicHandler 061 ) { 062 this.plotAreaManager = plotAreaManager; 063 this.schematicHandler = schematicHandler; 064 } 065 066 @Override 067 public boolean onCommand(final PlotPlayer<?> player, final String[] args) { 068 final String world = player.getLocation().getWorldName(); 069 if (!this.plotAreaManager.hasPlotArea(world)) { 070 player.sendMessage(TranslatableCaption.of("errors.not_in_plot_world")); 071 return false; 072 } 073 final Plot plot = player.getCurrentPlot(); 074 if (plot == null) { 075 player.sendMessage(TranslatableCaption.of("errors.not_in_plot")); 076 return false; 077 } 078 if (!plot.hasOwner()) { 079 player.sendMessage(TranslatableCaption.of("info.plot_unowned")); 080 return false; 081 } 082 if (!plot.isOwner(player.getUUID()) && !player.hasPermission(Permission.PERMISSION_ADMIN_COMMAND_LOAD)) { 083 player.sendMessage(TranslatableCaption.of("permission.no_plot_perms")); 084 return false; 085 } 086 if (plot.getRunning() > 0) { 087 player.sendMessage(TranslatableCaption.of("errors.wait_for_timer")); 088 return false; 089 } 090 091 try (final MetaDataAccess<List<String>> metaDataAccess = 092 player.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_SCHEMATICS)) { 093 if (args.length != 0) { 094 if (args.length == 1) { 095 List<String> schematics = metaDataAccess.get().orElse(null); 096 if (schematics == null) { 097 // No schematics found: 098 player.sendMessage( 099 TranslatableCaption.of("web.load_null"), 100 Template.of("command", "/plot load") 101 ); 102 return false; 103 } 104 String schematic; 105 try { 106 schematic = schematics.get(Integer.parseInt(args[0]) - 1); 107 } catch (Exception ignored) { 108 // use /plot load <index> 109 player.sendMessage( 110 TranslatableCaption.of("invalid.not_valid_number"), 111 Template.of("value", "(1, " + schematics.size() + ')') 112 ); 113 return false; 114 } 115 final URL url; 116 try { 117 url = new URL(Settings.Web.URL + "saves/" + player.getUUID() + '/' + schematic); 118 } catch (MalformedURLException e) { 119 e.printStackTrace(); 120 player.sendMessage(TranslatableCaption.of("web.load_failed")); 121 return false; 122 } 123 plot.addRunning(); 124 player.sendMessage(TranslatableCaption.of("working.generating_component")); 125 TaskManager.runTaskAsync(() -> { 126 Schematic taskSchematic = this.schematicHandler.getSchematic(url); 127 if (taskSchematic == null) { 128 plot.removeRunning(); 129 player.sendMessage( 130 TranslatableCaption.of("schematics.schematic_invalid"), 131 Template.of("reason", "non-existent or not in gzip format") 132 ); 133 return; 134 } 135 PlotArea area = plot.getArea(); 136 this.schematicHandler.paste( 137 taskSchematic, 138 plot, 139 0, 140 area.getMinBuildHeight(), 141 0, 142 false, 143 player, 144 new RunnableVal<>() { 145 @Override 146 public void run(Boolean value) { 147 plot.removeRunning(); 148 if (value) { 149 player.sendMessage(TranslatableCaption.of("schematics.schematic_paste_success")); 150 } else { 151 player.sendMessage(TranslatableCaption.of("schematics.schematic_paste_failed")); 152 } 153 } 154 } 155 ); 156 }); 157 return true; 158 } 159 plot.removeRunning(); 160 player.sendMessage( 161 TranslatableCaption.of("commandconfig.command_syntax"), 162 Template.of("value", "/plot load <index>") 163 ); 164 return false; 165 } 166 167 // list schematics 168 169 List<String> schematics = metaDataAccess.get().orElse(null); 170 if (schematics == null) { 171 plot.addRunning(); 172 TaskManager.runTaskAsync(() -> { 173 List<String> schematics1 = this.schematicHandler.getSaves(player.getUUID()); 174 plot.removeRunning(); 175 if ((schematics1 == null) || schematics1.isEmpty()) { 176 player.sendMessage(TranslatableCaption.of("web.load_failed")); 177 return; 178 } 179 metaDataAccess.set(schematics1); 180 displaySaves(player); 181 }); 182 } else { 183 displaySaves(player); 184 } 185 } 186 return true; 187 } 188 189 public void displaySaves(PlotPlayer<?> player) { 190 try (final MetaDataAccess<List<String>> metaDataAccess = 191 player.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_SCHEMATICS)) { 192 List<String> schematics = metaDataAccess.get().orElse(Collections.emptyList()); 193 for (int i = 0; i < Math.min(schematics.size(), 32); i++) { 194 try { 195 String schematic = schematics.get(i).split("\\.")[0]; 196 String[] split = schematic.split("_"); 197 if (split.length < 5) { 198 continue; 199 } 200 String time = TimeUtil.secToTime((System.currentTimeMillis() / 1000) - Long.parseLong(split[0])); 201 String world = split[1]; 202 PlotId id = PlotId.fromString(split[2] + ';' + split[3]); 203 String size = split[4]; 204 String color = "<dark_aqua>"; 205 player.sendMessage(StaticCaption.of("<dark_gray>[</dark_gray><gray>" + (i + 1) + "</gray><dark_aqua>] </dark_aqua>" + color + time + "<dark_gray> | </dark_gray>" + color + world + ';' + id 206 + "<dark_gray> | </dark_gray>" + color + size + 'x' + size)); 207 } catch (Exception e) { 208 e.printStackTrace(); 209 } 210 } 211 player.sendMessage( 212 TranslatableCaption.of("web.load_list"), 213 Template.of("command", "/plot load #") 214 ); 215 } 216 } 217 218 /** 219 * @deprecated Use {@link TimeUtil#secToTime(long)} 220 */ 221 @Deprecated(forRemoval = true, since = "6.6.2") 222 public String secToTime(long time) { 223 StringBuilder toreturn = new StringBuilder(); 224 if (time >= 33868800) { 225 int years = (int) (time / 33868800); 226 time -= years * 33868800; 227 toreturn.append(years).append("y "); 228 } 229 if (time >= 604800) { 230 int weeks = (int) (time / 604800); 231 time -= weeks * 604800; 232 toreturn.append(weeks).append("w "); 233 } 234 if (time >= 86400) { 235 int days = (int) (time / 86400); 236 time -= days * 86400; 237 toreturn.append(days).append("d "); 238 } 239 if (time >= 3600) { 240 int hours = (int) (time / 3600); 241 time -= hours * 3600; 242 toreturn.append(hours).append("h "); 243 } 244 if (time >= 60) { 245 int minutes = (int) (time / 60); 246 time -= minutes * 60; 247 toreturn.append(minutes).append("m "); 248 } 249 if (toreturn.length() == 0 || (time > 0)) { 250 toreturn.append(time).append("s "); 251 } 252 return toreturn.toString().trim(); 253 } 254 255}