PlotSquared/Core/src/main/java/com/plotsquared/core/command/Backup.java

348 lines
17 KiB
Java
Raw Normal View History

2020-05-10 15:36:20 +02:00
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
2020-05-10 15:36:20 +02:00
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
2020-05-10 15:36:20 +02:00
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
2020-05-10 15:36:20 +02:00
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
2020-05-10 15:36:20 +02:00
*/
package com.plotsquared.core.command;
2020-07-10 22:12:37 +02:00
import com.google.inject.Inject;
import com.plotsquared.core.backup.BackupManager;
2020-05-10 15:36:20 +02:00
import com.plotsquared.core.backup.BackupProfile;
2020-05-10 15:51:27 +02:00
import com.plotsquared.core.backup.NullBackupProfile;
2020-05-10 15:36:20 +02:00
import com.plotsquared.core.backup.PlayerBackupProfile;
2020-07-18 15:06:51 +02:00
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.permissions.Permission;
2020-05-10 15:36:20 +02:00
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.util.task.RunnableVal2;
import com.plotsquared.core.util.task.RunnableVal3;
2020-07-21 21:39:52 +02:00
import net.kyori.adventure.text.minimessage.Template;
import org.checkerframework.checker.nullness.qual.NonNull;
2020-05-10 15:36:20 +02:00
import java.nio.file.Files;
2020-05-10 19:20:11 +02:00
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
2020-05-10 15:36:20 +02:00
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
@CommandDeclaration(command = "backup",
usage = "/plot backup <save | list | load>",
category = CommandCategory.SETTINGS,
requiredType = RequiredType.PLAYER,
permission = "plots.backup")
2020-05-10 15:36:20 +02:00
public final class Backup extends Command {
2020-07-10 22:12:37 +02:00
private final BackupManager backupManager;
@Inject
public Backup(final @NonNull BackupManager backupManager) {
2020-05-10 15:36:20 +02:00
super(MainCommand.getInstance(), true);
2020-07-10 22:12:37 +02:00
this.backupManager = backupManager;
2020-05-10 15:36:20 +02:00
}
private static boolean sendMessage(PlotPlayer<?> player) {
player.sendMessage(
TranslatableCaption.of("commandconfig.command_syntax"),
Template.of("value", "/plot backup <save | list | load>")
);
2020-05-10 15:36:20 +02:00
return true;
}
@Override
public CompletableFuture<Boolean> execute(
PlotPlayer<?> player, String[] args,
RunnableVal3<Command, Runnable, Runnable> confirm,
RunnableVal2<Command, CommandResult> whenDone
) throws CommandException {
2020-05-10 15:36:20 +02:00
if (args.length == 0 || !Arrays.asList("save", "list", "load")
.contains(args[0].toLowerCase(Locale.ENGLISH))) {
return CompletableFuture.completedFuture(sendMessage(player));
2020-05-10 15:36:20 +02:00
}
return super.execute(player, args, confirm, whenDone);
}
@Override
public Collection<Command> tab(PlotPlayer<?> player, String[] args, boolean space) {
2020-05-10 15:36:20 +02:00
if (args.length == 1) {
2020-05-10 19:20:11 +02:00
return Stream.of("save", "list", "load")
.filter(value -> value.startsWith(args[0].toLowerCase(Locale.ENGLISH)))
.map(value -> new Command(null, false, value, "", RequiredType.NONE, null) {
}).collect(Collectors.toList());
2020-05-10 19:20:11 +02:00
} else if (args[0].equalsIgnoreCase("load")) {
2020-05-10 15:36:20 +02:00
final Plot plot = player.getCurrentPlot();
if (plot != null) {
2020-07-10 22:12:37 +02:00
final BackupProfile backupProfile = Objects.requireNonNull(this.backupManager.getProfile(plot));
if (backupProfile instanceof PlayerBackupProfile) {
final CompletableFuture<List<com.plotsquared.core.backup.Backup>> backupList =
backupProfile.listBackups();
2020-05-10 15:36:20 +02:00
if (backupList.isDone()) {
final List<com.plotsquared.core.backup.Backup> backups =
backupList.getNow(new ArrayList<>());
2020-05-10 15:36:20 +02:00
if (backups.isEmpty()) {
return new ArrayList<>();
}
return IntStream.range(1, 1 + backups.size()).mapToObj(
i -> new Command(null, false, Integer.toString(i), "",
RequiredType.NONE, null
) {
}).collect(Collectors.toList());
2020-05-10 15:36:20 +02:00
}
}
}
}
return tabOf(player, args, space);
}
@CommandDeclaration(command = "save",
usage = "/plot backup save",
category = CommandCategory.SETTINGS,
requiredType = RequiredType.PLAYER,
permission = "plots.backup.save")
public void save(
final Command command, final PlotPlayer<?> player, final String[] args,
final RunnableVal3<Command, Runnable, Runnable> confirm,
final RunnableVal2<Command, CommandResult> whenDone
) {
2020-05-10 15:51:27 +02:00
final Plot plot = player.getCurrentPlot();
if (plot == null) {
2020-07-18 15:06:51 +02:00
player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
2020-05-10 15:51:27 +02:00
} else if (!plot.hasOwner()) {
2020-07-21 21:39:52 +02:00
player.sendMessage(
TranslatableCaption.of("backups.backup_impossible"),
Template.of("plot", TranslatableCaption.of("generic.generic_unowned").getComponent(player))
2020-07-21 21:39:52 +02:00
);
} else if (plot.getVolume() > Integer.MAX_VALUE) {
player.sendMessage(TranslatableCaption.of("schematics.schematic_too_large"));
2020-05-10 15:51:27 +02:00
} else if (plot.isMerged()) {
2020-07-21 21:39:52 +02:00
player.sendMessage(
TranslatableCaption.of("backups.backup_impossible"),
Template.of("plot", TranslatableCaption.of("generic.generic_merged").getComponent(player))
2020-07-21 21:39:52 +02:00
);
} else if (!plot.isOwner(player.getUUID()) && !player.hasPermission(Permission.PERMISSION_ADMIN_BACKUP_OTHER)) {
2020-07-21 21:39:52 +02:00
player.sendMessage(
TranslatableCaption.of("permission.no_permission"),
Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_BACKUP_OTHER))
2020-07-21 21:39:52 +02:00
);
2020-05-10 15:51:27 +02:00
} else {
2020-07-10 22:12:37 +02:00
final BackupProfile backupProfile = Objects.requireNonNull(this.backupManager.getProfile(plot));
2020-05-10 15:51:27 +02:00
if (backupProfile instanceof NullBackupProfile) {
2020-07-21 21:39:52 +02:00
player.sendMessage(
TranslatableCaption.of("backups.backup_impossible"),
Template.of("plot", TranslatableCaption.of("generic.generic_other").getComponent(player))
2020-07-21 21:39:52 +02:00
);
2020-05-10 15:51:27 +02:00
} else {
backupProfile.createBackup().whenComplete((backup, throwable) -> {
if (throwable != null) {
player.sendMessage(
TranslatableCaption.of("backups.backup_save_failed"),
Template.of("reason", throwable.getMessage())
);
2020-05-10 19:20:11 +02:00
throwable.printStackTrace();
2020-05-10 15:51:27 +02:00
} else {
2020-07-21 21:39:52 +02:00
player.sendMessage(TranslatableCaption.of("backups.backup_save_success"));
2020-05-10 15:51:27 +02:00
}
});
}
}
2020-05-10 15:36:20 +02:00
}
@CommandDeclaration(command = "list",
usage = "/plot backup list",
category = CommandCategory.SETTINGS,
requiredType = RequiredType.PLAYER,
permission = "plots.backup.list")
public void list(
final Command command, final PlotPlayer<?> player, final String[] args,
final RunnableVal3<Command, Runnable, Runnable> confirm,
final RunnableVal2<Command, CommandResult> whenDone
) {
final Plot plot = player.getCurrentPlot();
if (plot == null) {
2020-07-18 15:06:51 +02:00
player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
} else if (!plot.hasOwner()) {
2020-07-21 21:39:52 +02:00
player.sendMessage(
TranslatableCaption.of("backups.backup_impossible"),
Template.of("plot", TranslatableCaption.of("generic.generic_unowned").getComponent(player))
2020-07-21 21:39:52 +02:00
);
} else if (plot.isMerged()) {
2020-07-21 21:39:52 +02:00
player.sendMessage(
TranslatableCaption.of("backups.backup_impossible"),
Template.of("plot", TranslatableCaption.of("generic.generic_merged").getComponent(player))
2020-07-21 21:39:52 +02:00
);
} else if (plot.getVolume() > Integer.MAX_VALUE) {
player.sendMessage(TranslatableCaption.of("schematics.schematic_too_large"));
} else if (!plot.isOwner(player.getUUID()) && !player.hasPermission(Permission.PERMISSION_ADMIN_BACKUP_OTHER)) {
2020-07-21 21:39:52 +02:00
player.sendMessage(
TranslatableCaption.of("permission.no_permission"),
Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_BACKUP_OTHER))
2020-07-21 21:39:52 +02:00
);
} else {
2020-07-10 22:12:37 +02:00
final BackupProfile backupProfile = Objects.requireNonNull(this.backupManager.getProfile(plot));
if (backupProfile instanceof NullBackupProfile) {
2020-07-21 21:39:52 +02:00
player.sendMessage(
TranslatableCaption.of("backups.backup_impossible"),
Template.of("plot", TranslatableCaption.of("generic.generic_other").getComponent(player))
2020-07-21 21:39:52 +02:00
);
2020-05-10 15:51:27 +02:00
} else {
backupProfile.listBackups().whenComplete((backups, throwable) -> {
if (throwable != null) {
2020-07-21 21:39:52 +02:00
player.sendMessage(
TranslatableCaption.of("backups.backup_list_failed"),
Template.of("reason", throwable.getMessage())
2020-07-21 21:39:52 +02:00
);
throwable.printStackTrace();
} else {
2020-07-21 21:39:52 +02:00
player.sendMessage(
TranslatableCaption.of("backups.backup_list_header"),
Template.of("plot", plot.getId().toCommaSeparatedString())
2020-07-21 21:39:52 +02:00
);
try {
for (int i = 0; i < backups.size(); i++) {
2020-07-21 21:39:52 +02:00
player.sendMessage(
TranslatableCaption.of("backups.backup_list_entry"),
Template.of("number", Integer.toString(i + 1)),
Template.of("value", DateTimeFormatter.RFC_1123_DATE_TIME.format(ZonedDateTime.ofInstant(
2020-07-21 21:39:52 +02:00
Instant.ofEpochMilli(backups.get(i).getCreationTime()),
ZoneId.systemDefault()
)))
2020-07-21 21:39:52 +02:00
);
2020-05-10 19:20:11 +02:00
}
} catch (final Exception e) {
e.printStackTrace();
2020-05-10 19:20:11 +02:00
}
}
});
2020-05-10 15:51:27 +02:00
}
}
2020-05-10 15:36:20 +02:00
}
@CommandDeclaration(command = "load",
usage = "/plot backup load <#>",
category = CommandCategory.SETTINGS,
requiredType = RequiredType.PLAYER,
permission = "plots.backup.load")
public void load(
final Command command, final PlotPlayer<?> player, final String[] args,
final RunnableVal3<Command, Runnable, Runnable> confirm,
final RunnableVal2<Command, CommandResult> whenDone
) {
2020-05-10 15:51:27 +02:00
final Plot plot = player.getCurrentPlot();
if (plot == null) {
2020-07-18 15:06:51 +02:00
player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
2020-05-10 15:51:27 +02:00
} else if (!plot.hasOwner()) {
2020-07-21 21:39:52 +02:00
player.sendMessage(
TranslatableCaption.of("backups.backup_impossible"),
Template.of("plot", TranslatableCaption.of("generic.generic_unowned").getComponent(player))
2020-07-21 21:39:52 +02:00
);
2020-05-10 15:51:27 +02:00
} else if (plot.isMerged()) {
2020-07-21 21:39:52 +02:00
player.sendMessage(
TranslatableCaption.of("backups.backup_impossible"),
Template.of("plot", TranslatableCaption.of("generic.generic_merged").getComponent(player))
2020-07-21 21:39:52 +02:00
);
} else if (plot.getVolume() > Integer.MAX_VALUE) {
player.sendMessage(TranslatableCaption.of("schematics.schematic_too_large"));
} else if (!plot.isOwner(player.getUUID()) && !player.hasPermission(Permission.PERMISSION_ADMIN_BACKUP_OTHER)) {
2020-07-21 21:39:52 +02:00
player.sendMessage(
TranslatableCaption.of("permission.no_permission"),
Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_BACKUP_OTHER))
2020-07-21 21:39:52 +02:00
);
2020-05-10 15:51:27 +02:00
} else if (args.length == 0) {
2020-07-21 21:39:52 +02:00
player.sendMessage(
TranslatableCaption.of("commandconfig.command_syntax"),
Template.of("value", "Usage: /plot backup save/list/load")
2020-07-21 21:39:52 +02:00
);
2020-05-10 15:51:27 +02:00
} else {
final int number;
try {
number = Integer.parseInt(args[0]);
} catch (final Exception e) {
2020-07-21 21:39:52 +02:00
player.sendMessage(
TranslatableCaption.of("invalid.not_a_number"),
Template.of("value", args[0])
2020-07-21 21:39:52 +02:00
);
2020-05-10 15:51:27 +02:00
return;
}
2020-07-10 22:12:37 +02:00
final BackupProfile backupProfile = Objects.requireNonNull(this.backupManager.getProfile(plot));
2020-05-10 15:51:27 +02:00
if (backupProfile instanceof NullBackupProfile) {
2020-07-21 21:39:52 +02:00
player.sendMessage(
TranslatableCaption.of("backups.backup_impossible"),
Template.of("plot", TranslatableCaption.of("generic.generic_other").getComponent(player))
2020-07-21 21:39:52 +02:00
);
2020-05-10 15:51:27 +02:00
} else {
backupProfile.listBackups().whenComplete((backups, throwable) -> {
if (throwable != null) {
2020-07-21 21:39:52 +02:00
player.sendMessage(
TranslatableCaption.of("backups.backup_load_failure"),
Template.of("reason", throwable.getMessage())
2020-07-21 21:39:52 +02:00
);
2020-05-10 19:20:11 +02:00
throwable.printStackTrace();
} else {
if (number < 1 || number > backups.size()) {
2020-07-21 21:39:52 +02:00
player.sendMessage(
TranslatableCaption.of("backups.backup_impossible"),
Template.of(
2021-08-18 11:58:18 +02:00
"plot",
TranslatableCaption.of("generic.generic_invalid_choice").getComponent(player)
)
2020-07-21 21:39:52 +02:00
);
} else {
final com.plotsquared.core.backup.Backup backup =
backups.get(number - 1);
if (backup == null || backup.getFile() == null || !Files
.exists(backup.getFile())) {
2020-07-21 21:39:52 +02:00
player.sendMessage(
TranslatableCaption.of("backups.backup_impossible"),
Template.of(
2021-08-18 11:58:18 +02:00
"plot",
TranslatableCaption.of("generic.generic_invalid_choice").getComponent(player)
)
2020-07-21 21:39:52 +02:00
);
} else {
CmdConfirm.addPending(player, "/plot backup load " + number,
() -> backupProfile.restoreBackup(backup, player)
.whenComplete((n, error) -> {
if (error != null) {
player.sendMessage(
TranslatableCaption.of("backups.backup_load_failure"),
Template.of("reason", error.getMessage())
);
} else {
player.sendMessage(TranslatableCaption.of("backups.backup_load_success"));
}
})
);
}
}
}
2020-05-10 15:51:27 +02:00
});
}
}
2020-05-10 15:36:20 +02:00
}
}