mirror of
https://github.com/WiIIiam278/HuskSync.git
synced 2025-12-19 14:59:21 +00:00
feat: add ability to run /userdata dump without args
This commit is contained in:
@@ -149,7 +149,7 @@ public class HuskSyncAPI {
|
||||
*/
|
||||
public CompletableFuture<Optional<DataSnapshot.Unpacked>> getCurrentData(@NotNull User user) {
|
||||
return plugin.getRedisManager()
|
||||
.getUserData(UUID.randomUUID(), user)
|
||||
.getOnlineUserData(UUID.randomUUID(), user, DataSnapshot.SaveCause.API)
|
||||
.thenApply(data -> data.or(() -> plugin.getDatabase().getLatestSnapshot(user)))
|
||||
.thenApply(data -> data.map(snapshot -> snapshot.unpack(plugin)));
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ import java.util.Optional;
|
||||
public class EnderChestCommand extends ItemsCommand {
|
||||
|
||||
public EnderChestCommand(@NotNull HuskSync plugin) {
|
||||
super("enderchest", List.of("echest", "openechest"), plugin);
|
||||
super("enderchest", List.of("echest", "openechest"), DataSnapshot.SaveCause.ENDERCHEST_COMMAND, plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -83,10 +83,10 @@ public class EnderChestCommand extends ItemsCommand {
|
||||
|
||||
// Create and pack the snapshot with the updated enderChest
|
||||
final DataSnapshot.Packed snapshot = latestData.get().copy();
|
||||
boolean pin = plugin.getSettings().getSynchronization().doAutoPin(DataSnapshot.SaveCause.ENDERCHEST_COMMAND);
|
||||
boolean pin = plugin.getSettings().getSynchronization().doAutoPin(saveCause);
|
||||
snapshot.edit(plugin, (data) -> {
|
||||
data.getEnderChest().ifPresent(enderChest -> enderChest.setContents(items));
|
||||
data.setSaveCause(DataSnapshot.SaveCause.ENDERCHEST_COMMAND);
|
||||
data.setSaveCause(saveCause);
|
||||
data.setPinned(pin);
|
||||
});
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ import java.util.Optional;
|
||||
public class InventoryCommand extends ItemsCommand {
|
||||
|
||||
public InventoryCommand(@NotNull HuskSync plugin) {
|
||||
super("inventory", List.of("invsee", "openinv"), plugin);
|
||||
super("inventory", List.of("invsee", "openinv"), DataSnapshot.SaveCause.INVENTORY_COMMAND, plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -84,10 +84,10 @@ public class InventoryCommand extends ItemsCommand {
|
||||
|
||||
// Create and pack the snapshot with the updated inventory
|
||||
final DataSnapshot.Packed snapshot = latestData.get().copy();
|
||||
boolean pin = plugin.getSettings().getSynchronization().doAutoPin(DataSnapshot.SaveCause.INVENTORY_COMMAND);
|
||||
boolean pin = plugin.getSettings().getSynchronization().doAutoPin(saveCause);
|
||||
snapshot.edit(plugin, (data) -> {
|
||||
data.getInventory().ifPresent(inventory -> inventory.setContents(items));
|
||||
data.setSaveCause(DataSnapshot.SaveCause.INVENTORY_COMMAND);
|
||||
data.setSaveCause(saveCause);
|
||||
data.setPinned(pin);
|
||||
});
|
||||
|
||||
|
||||
@@ -34,8 +34,12 @@ import java.util.UUID;
|
||||
|
||||
public abstract class ItemsCommand extends PluginCommand {
|
||||
|
||||
protected ItemsCommand(@NotNull String name, @NotNull List<String> aliases, @NotNull HuskSync plugin) {
|
||||
protected final DataSnapshot.SaveCause saveCause;
|
||||
|
||||
protected ItemsCommand(@NotNull String name, @NotNull List<String> aliases,
|
||||
@NotNull DataSnapshot.SaveCause saveCause, @NotNull HuskSync plugin) {
|
||||
super(name, aliases, Permission.Default.IF_OP, ExecutionScope.IN_GAME, plugin);
|
||||
this.saveCause = saveCause;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -50,7 +54,7 @@ public abstract class ItemsCommand extends PluginCommand {
|
||||
return;
|
||||
}
|
||||
this.showSnapshotItems(online, user, version);
|
||||
}, user("username"), uuid("version"));
|
||||
}, user("username"), versionUuid());
|
||||
command.addSyntax((ctx) -> {
|
||||
final User user = ctx.getArgument("username", User.class);
|
||||
final CommandUser executor = user(command, ctx);
|
||||
@@ -65,7 +69,7 @@ public abstract class ItemsCommand extends PluginCommand {
|
||||
|
||||
// View (and edit) the latest user data
|
||||
private void showLatestItems(@NotNull OnlineUser viewer, @NotNull User user) {
|
||||
plugin.getRedisManager().getUserData(user.getUuid(), user).thenAccept(data -> data
|
||||
plugin.getRedisManager().getOnlineUserData(user.getUuid(), user, saveCause).thenAccept(d -> d
|
||||
.or(() -> plugin.getDatabase().getLatestSnapshot(user))
|
||||
.or(() -> {
|
||||
plugin.getLocales().getLocale("error_no_data_to_display")
|
||||
|
||||
@@ -32,6 +32,7 @@ import net.william278.uniform.element.ArgumentElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Function;
|
||||
@@ -104,14 +105,23 @@ public abstract class PluginCommand extends Command {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected <S> ArgumentElement<S, UUID> uuid(@NotNull String name) {
|
||||
return new ArgumentElement<>(name, reader -> {
|
||||
protected <S> ArgumentElement<S, UUID> versionUuid() {
|
||||
return new ArgumentElement<>("version", reader -> {
|
||||
try {
|
||||
return UUID.fromString(reader.readString());
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw CommandSyntaxException.BUILT_IN_EXCEPTIONS.dispatcherUnknownArgument().createWithContext(reader);
|
||||
}
|
||||
}, (context, builder) -> builder.buildFuture());
|
||||
}, (context, builder) -> {
|
||||
try {
|
||||
plugin.getDatabase().getAllSnapshots(context.getArgument("username", User.class))
|
||||
.stream().sorted(Comparator.comparing(d -> d.getTimestamp().toEpochSecond()))
|
||||
.forEach(id -> builder.suggest(id.getId().toString()));
|
||||
return builder.buildFuture();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return builder.buildFuture();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
|
||||
@@ -30,9 +30,9 @@ import net.william278.husksync.redis.RedisManager;
|
||||
import net.william278.husksync.user.CommandUser;
|
||||
import net.william278.husksync.user.OnlineUser;
|
||||
import net.william278.husksync.user.User;
|
||||
import net.william278.husksync.util.UserDataDumper;
|
||||
import net.william278.husksync.util.DataSnapshotList;
|
||||
import net.william278.husksync.util.DataSnapshotOverview;
|
||||
import net.william278.husksync.util.UserDataDumper;
|
||||
import net.william278.uniform.BaseCommand;
|
||||
import net.william278.uniform.CommandProvider;
|
||||
import net.william278.uniform.Permission;
|
||||
@@ -185,7 +185,7 @@ public class UserDataCommand extends PluginCommand {
|
||||
.ifPresent(executor::sendMessage);
|
||||
}
|
||||
|
||||
// Dump a snapshot
|
||||
// Lookup a snapshot by UUID and dump
|
||||
private void dumpSnapshot(@NotNull CommandUser executor, @NotNull User user, @NotNull UUID version,
|
||||
@NotNull DumpType type) {
|
||||
final Optional<DataSnapshot.Packed> data = plugin.getDatabase().getSnapshot(user, version);
|
||||
@@ -194,9 +194,12 @@ public class UserDataCommand extends PluginCommand {
|
||||
.ifPresent(executor::sendMessage);
|
||||
return;
|
||||
}
|
||||
this.dumpSnapshot(executor, user, data.get(), type);
|
||||
}
|
||||
|
||||
// Dump the data
|
||||
final DataSnapshot.Packed userData = data.get();
|
||||
// Dump a snapshot
|
||||
private void dumpSnapshot(@NotNull CommandUser executor, @NotNull User user,
|
||||
@NotNull DataSnapshot.Packed userData, @NotNull DumpType type) {
|
||||
final UserDataDumper dumper = UserDataDumper.create(userData, user, plugin);
|
||||
try {
|
||||
final String url = type == DumpType.WEB ? dumper.toWeb() : dumper.toFile();
|
||||
@@ -212,17 +215,11 @@ public class UserDataCommand extends PluginCommand {
|
||||
|
||||
@NotNull
|
||||
private CommandProvider view() {
|
||||
return (sub) -> {
|
||||
sub.addSyntax((ctx) -> {
|
||||
final User user = ctx.getArgument("username", User.class);
|
||||
viewLatestSnapshot(user(sub, ctx), user);
|
||||
}, user("username"));
|
||||
sub.addSyntax((ctx) -> {
|
||||
return (sub) -> sub.addSyntax((ctx) -> {
|
||||
final User user = ctx.getArgument("username", User.class);
|
||||
final UUID version = ctx.getArgument("version", UUID.class);
|
||||
viewSnapshot(user(sub, ctx), user, version);
|
||||
}, user("username"), uuid("version"));
|
||||
};
|
||||
}, user("username"), versionUuid());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -246,7 +243,7 @@ public class UserDataCommand extends PluginCommand {
|
||||
final User user = ctx.getArgument("username", User.class);
|
||||
final UUID version = ctx.getArgument("version", UUID.class);
|
||||
deleteSnapshot(user(sub, ctx), user, version);
|
||||
}, user("username"), uuid("version"));
|
||||
}, user("username"), versionUuid());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -263,7 +260,7 @@ public class UserDataCommand extends PluginCommand {
|
||||
final User user = ctx.getArgument("username", User.class);
|
||||
final UUID version = ctx.getArgument("version", UUID.class);
|
||||
restoreSnapshot(user(sub, ctx), user, version);
|
||||
}, user("username"), uuid("version"));
|
||||
}, user("username"), versionUuid());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -272,17 +269,32 @@ public class UserDataCommand extends PluginCommand {
|
||||
final User user = ctx.getArgument("username", User.class);
|
||||
final UUID version = ctx.getArgument("version", UUID.class);
|
||||
pinSnapshot(user(sub, ctx), user, version);
|
||||
}, user("username"), uuid("version"));
|
||||
}, user("username"), versionUuid());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private CommandProvider dump() {
|
||||
return (sub) -> sub.addSyntax((ctx) -> {
|
||||
return (sub) -> {
|
||||
sub.addSyntax((ctx) -> {
|
||||
final User user = ctx.getArgument("username", User.class);
|
||||
final CommandUser executor = user(sub, ctx);
|
||||
plugin.getRedisManager()
|
||||
.getOnlineUserData(UUID.randomUUID(), user, DataSnapshot.SaveCause.DUMP_COMMAND)
|
||||
.thenAccept((data) -> data
|
||||
.or(() -> plugin.getDatabase().getLatestSnapshot(user))
|
||||
.ifPresentOrElse(
|
||||
(s) -> dumpSnapshot(executor, user, s, DumpType.WEB),
|
||||
() -> plugin.getLocales().getLocale("error_no_data_to_display")
|
||||
.ifPresent(executor::sendMessage)
|
||||
));
|
||||
}, user("username"));
|
||||
sub.addSyntax((ctx) -> {
|
||||
final User user = ctx.getArgument("username", User.class);
|
||||
final UUID version = ctx.getArgument("version", UUID.class);
|
||||
final DumpType type = ctx.getArgument("type", DumpType.class);
|
||||
dumpSnapshot(user(sub, ctx), user, version, type);
|
||||
}, user("username"), uuid("version"), dumpType());
|
||||
}, user("username"), versionUuid(), dumpType());
|
||||
};
|
||||
}
|
||||
|
||||
private <S> ArgumentElement<S, DumpType> dumpType() {
|
||||
|
||||
@@ -887,6 +887,13 @@ public class DataSnapshot {
|
||||
*/
|
||||
public static final SaveCause SAVE_COMMAND = of("SAVE_COMMAND", true);
|
||||
|
||||
/**
|
||||
* Indicates data was saved from executing the {@code /userdata dump} command
|
||||
*
|
||||
* @since 3.8
|
||||
*/
|
||||
public static final SaveCause DUMP_COMMAND = of("DUMP_COMMAND", true);
|
||||
|
||||
/**
|
||||
* Indicates data was saved by an API call
|
||||
*
|
||||
|
||||
@@ -218,16 +218,17 @@ public class RedisManager extends JedisPubSub {
|
||||
});
|
||||
}
|
||||
|
||||
public CompletableFuture<Optional<DataSnapshot.Packed>> getUserData(@NotNull UUID requestId, @NotNull User user) {
|
||||
public CompletableFuture<Optional<DataSnapshot.Packed>> getOnlineUserData(@NotNull UUID requestId, @NotNull User user,
|
||||
@NotNull DataSnapshot.SaveCause saveCause) {
|
||||
return plugin.getOnlineUser(user.getUuid())
|
||||
.map(online -> CompletableFuture.completedFuture(
|
||||
Optional.of(online.createSnapshot(DataSnapshot.SaveCause.API)))
|
||||
Optional.of(online.createSnapshot(saveCause)))
|
||||
)
|
||||
.orElse(this.requestData(requestId, user));
|
||||
.orElse(this.getNetworkedUserData(requestId, user));
|
||||
}
|
||||
|
||||
// Request a user's dat x-server
|
||||
private CompletableFuture<Optional<DataSnapshot.Packed>> requestData(@NotNull UUID requestId, @NotNull User user) {
|
||||
private CompletableFuture<Optional<DataSnapshot.Packed>> getNetworkedUserData(@NotNull UUID requestId, @NotNull User user) {
|
||||
final CompletableFuture<Optional<DataSnapshot.Packed>> future = new CompletableFuture<>();
|
||||
pendingRequests.put(requestId, future);
|
||||
plugin.runAsync(() -> {
|
||||
|
||||
@@ -42,6 +42,7 @@ locales:
|
||||
save_cause_death: 'death'
|
||||
save_cause_server_shutdown: 'server shutdown'
|
||||
save_cause_save_command: 'save command'
|
||||
save_cause_dump_command: 'dump command'
|
||||
save_cause_inventory_command: 'inventory command'
|
||||
save_cause_enderchest_command: 'enderchest command'
|
||||
save_cause_backup_restore: 'backup restore'
|
||||
|
||||
@@ -42,6 +42,7 @@ locales:
|
||||
save_cause_death: 'Tod'
|
||||
save_cause_server_shutdown: 'server gestoppt'
|
||||
save_cause_save_command: 'save command'
|
||||
save_cause_dump_command: 'dump command'
|
||||
save_cause_inventory_command: 'inventar Befehl'
|
||||
save_cause_enderchest_command: 'enderchest Befehl'
|
||||
save_cause_backup_restore: 'backup wiederhergestellt'
|
||||
|
||||
@@ -42,6 +42,7 @@ locales:
|
||||
save_cause_death: 'death'
|
||||
save_cause_server_shutdown: 'server shutdown'
|
||||
save_cause_save_command: 'save command'
|
||||
save_cause_dump_command: 'dump command'
|
||||
save_cause_inventory_command: 'inventory command'
|
||||
save_cause_enderchest_command: 'enderchest command'
|
||||
save_cause_backup_restore: 'backup restore'
|
||||
|
||||
@@ -42,6 +42,7 @@ locales:
|
||||
save_cause_death: 'death'
|
||||
save_cause_server_shutdown: 'server shutdown'
|
||||
save_cause_save_command: 'save command'
|
||||
save_cause_dump_command: 'dump command'
|
||||
save_cause_inventory_command: 'inventory command'
|
||||
save_cause_enderchest_command: 'enderchest command'
|
||||
save_cause_backup_restore: 'backup restore'
|
||||
|
||||
@@ -42,6 +42,7 @@ locales:
|
||||
save_cause_death: 'mort'
|
||||
save_cause_server_shutdown: 'arrêt du serveur'
|
||||
save_cause_save_command: 'save command'
|
||||
save_cause_dump_command: 'dump command'
|
||||
save_cause_inventory_command: 'commande d''inventaire'
|
||||
save_cause_enderchest_command: 'commande du coffre de l''Ender'
|
||||
save_cause_backup_restore: 'restauration de sauvegarde'
|
||||
|
||||
@@ -42,6 +42,7 @@ locales:
|
||||
save_cause_death: 'kematian'
|
||||
save_cause_server_shutdown: 'pematian server'
|
||||
save_cause_save_command: 'save command'
|
||||
save_cause_dump_command: 'dump command'
|
||||
save_cause_inventory_command: 'perintah inventaris'
|
||||
save_cause_enderchest_command: 'perintah enderchest'
|
||||
save_cause_backup_restore: 'pemulihan cadangan'
|
||||
|
||||
@@ -42,6 +42,7 @@ locales:
|
||||
save_cause_death: 'death'
|
||||
save_cause_server_shutdown: 'server shutdown'
|
||||
save_cause_save_command: 'save command'
|
||||
save_cause_dump_command: 'dump command'
|
||||
save_cause_inventory_command: 'inventory command'
|
||||
save_cause_enderchest_command: 'enderchest command'
|
||||
save_cause_backup_restore: 'backup restore'
|
||||
|
||||
@@ -42,6 +42,7 @@ locales:
|
||||
save_cause_death: 'death'
|
||||
save_cause_server_shutdown: 'server shutdown'
|
||||
save_cause_save_command: 'save command'
|
||||
save_cause_dump_command: 'dump command'
|
||||
save_cause_inventory_command: 'inventory command'
|
||||
save_cause_enderchest_command: 'enderchest command'
|
||||
save_cause_backup_restore: 'backup restore'
|
||||
|
||||
@@ -42,6 +42,7 @@ locales:
|
||||
save_cause_death: 'death'
|
||||
save_cause_server_shutdown: 'server shutdown'
|
||||
save_cause_save_command: 'save command'
|
||||
save_cause_dump_command: 'dump command'
|
||||
save_cause_inventory_command: 'inventory command'
|
||||
save_cause_enderchest_command: 'enderchest command'
|
||||
save_cause_backup_restore: 'backup restore'
|
||||
|
||||
@@ -42,6 +42,7 @@ locales:
|
||||
save_cause_death: 'death'
|
||||
save_cause_server_shutdown: 'server shutdown'
|
||||
save_cause_save_command: 'save command'
|
||||
save_cause_dump_command: 'dump command'
|
||||
save_cause_inventory_command: 'inventory command'
|
||||
save_cause_enderchest_command: 'enderchest command'
|
||||
save_cause_backup_restore: 'backup restore'
|
||||
|
||||
@@ -42,6 +42,7 @@ locales:
|
||||
save_cause_death: 'death'
|
||||
save_cause_server_shutdown: 'server shutdown'
|
||||
save_cause_save_command: 'save command'
|
||||
save_cause_dump_command: 'dump command'
|
||||
save_cause_inventory_command: 'inventory command'
|
||||
save_cause_enderchest_command: 'enderchest command'
|
||||
save_cause_backup_restore: 'backup restore'
|
||||
|
||||
@@ -42,6 +42,7 @@ locales:
|
||||
save_cause_death: 'смерть'
|
||||
save_cause_server_shutdown: 'отключение сервера'
|
||||
save_cause_save_command: 'save command'
|
||||
save_cause_dump_command: 'dump command'
|
||||
save_cause_inventory_command: 'команда inventory'
|
||||
save_cause_enderchest_command: 'команда enderchest'
|
||||
save_cause_backup_restore: 'восстановление из снимка'
|
||||
|
||||
@@ -42,6 +42,7 @@ locales:
|
||||
save_cause_death: 'ölüm'
|
||||
save_cause_server_shutdown: 'sunucu kapatma'
|
||||
save_cause_save_command: 'save command'
|
||||
save_cause_dump_command: 'dump command'
|
||||
save_cause_inventory_command: 'envanter komutu'
|
||||
save_cause_enderchest_command: 'ender sandığı komutu'
|
||||
save_cause_backup_restore: 'yedek geri yükleme'
|
||||
|
||||
@@ -42,6 +42,7 @@ locales:
|
||||
save_cause_death: 'death'
|
||||
save_cause_server_shutdown: 'server shutdown'
|
||||
save_cause_save_command: 'save command'
|
||||
save_cause_dump_command: 'dump command'
|
||||
save_cause_inventory_command: 'inventory command'
|
||||
save_cause_enderchest_command: 'enderchest command'
|
||||
save_cause_backup_restore: 'backup restore'
|
||||
|
||||
@@ -42,6 +42,7 @@ locales:
|
||||
save_cause_death: '死亡'
|
||||
save_cause_server_shutdown: '服务器关闭'
|
||||
save_cause_save_command: 'save command'
|
||||
save_cause_dump_command: 'dump command'
|
||||
save_cause_inventory_command: '背包命令'
|
||||
save_cause_enderchest_command: '末影箱命令'
|
||||
save_cause_backup_restore: '备份还原'
|
||||
|
||||
@@ -42,6 +42,7 @@ locales:
|
||||
save_cause_death: '死亡'
|
||||
save_cause_server_shutdown: '伺服器關閉'
|
||||
save_cause_save_command: 'save command'
|
||||
save_cause_dump_command: 'dump command'
|
||||
save_cause_inventory_command: '背包指令'
|
||||
save_cause_enderchest_command: '終界箱指令'
|
||||
save_cause_backup_restore: '備份還原'
|
||||
|
||||
Reference in New Issue
Block a user