Skip to content

Commit

Permalink
feat: collections can now be edited via editor
Browse files Browse the repository at this point in the history
  • Loading branch information
HappyAreaBean committed Apr 22, 2024
1 parent c8406a7 commit 3fba698
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 30 deletions.
2 changes: 1 addition & 1 deletion src/main/java/cc/happyareabean/sjm/SimpleJoinMessage.java
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ public void loadSync() {
return;
}

database.getContent(collection).ifPresentOrElse(data -> {
database.getRawContent(collection).ifPresentOrElse(data -> {
logger().info("Updating join message from collection [%s]...".formatted(collection));

String content = new String(Util.BASE64_DECODER.decode(data.getContent()));
Expand Down
95 changes: 69 additions & 26 deletions src/main/java/cc/happyareabean/sjm/commands/SJMCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import revxrsal.commands.annotation.DefaultFor;
import revxrsal.commands.annotation.Description;
import revxrsal.commands.annotation.Named;
import revxrsal.commands.annotation.Optional;
import revxrsal.commands.annotation.Subcommand;
import revxrsal.commands.bukkit.BukkitCommandActor;
import revxrsal.commands.bukkit.annotation.CommandPermission;
Expand All @@ -28,7 +29,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.concurrent.CompletableFuture;

import static cc.happyareabean.sjm.SimpleJoinMessage.LEGACY_SERIALIZER;
import static cc.happyareabean.sjm.SimpleJoinMessage.MINIMESSAGE;
Expand Down Expand Up @@ -87,56 +88,97 @@ public void show(BukkitCommandActor actor) {
}

@Subcommand({"editor"})
@Description("Open join message editor")
public void editor(BukkitCommandActor actor) {
@Description("Open a new join message editor session")
@AutoComplete("@sjmData")
public void editor(BukkitCommandActor actor, @Optional @Named("collection") String collection) {
SJMConfig config = SimpleJoinMessage.getInstance().getSJMConfig();
AdventureWebEditorAPI api = SimpleJoinMessage.getInstance().getAdventureWebEditorAPI();
actor.reply(Constants.PREFIX.append(text("Preparing new editor session, please wait...", NamedTextColor.GRAY)));
api.startSession(String.join("\n", config.getJoinMessage()), "/sjm applyedits {token}", Constants.USER_AGENT)
.whenComplete((token, throwable) -> {
if (throwable != null) {
actor.reply(Constants.PREFIX.append(text("Error occurred when processing your request: " + throwable.getMessage(), NamedTextColor.RED)));
return;
}
String url = config.getAdventureWebURL() + "?token=" + token;

actor.reply(Constants.PREFIX.append(text("Click the link below to open the editor:", NamedTextColor.GREEN)));
actor.reply(text(url, NamedTextColor.AQUA).clickEvent(clickEvent(ClickEvent.Action.OPEN_URL, url)));
});
CompletableFuture.supplyAsync(() -> {
if (collection == null)
return config.getJoinMessage();

return SimpleJoinMessage.getInstance().getDatabase().getContent(collection);
}).whenComplete((strings, throwable) -> {

if (throwable != null) {
actor.reply(Constants.PREFIX.append(text("Error occurred when preparing your editor session: " + throwable.getMessage(),
NamedTextColor.RED)));
return;
}

// Check if strings are null and a collection is entered
// Because strings will always non-null if a collection is not entered
if (strings == null && collection != null) {
actor.reply(Constants.PREFIX.append(text("The collection '%s' does not exist.".formatted(collection), NamedTextColor.RED)));
return;
}

AdventureWebEditorAPI api = SimpleJoinMessage.getInstance().getAdventureWebEditorAPI();
String command = collection != null ? "/sjm applyedits {token} " + collection : "/sjm applyedits {token}";
actor.reply(Constants.PREFIX.append(text("Preparing new editor session, please wait...", NamedTextColor.GRAY)));
api.startSession(String.join("\n", strings), command, Constants.USER_AGENT)
.whenComplete((token, editorThrowable) -> {
if (editorThrowable != null) {
actor.reply(Constants.PREFIX.append(text("Error occurred when processing your request: " + editorThrowable.getMessage(), NamedTextColor.RED)));
return;
}
String url = config.getAdventureWebURL() + "?token=" + token;

actor.reply(Constants.PREFIX.append(text("Click the link below to open the editor:", NamedTextColor.GREEN)));
actor.reply(text(url, NamedTextColor.AQUA).clickEvent(clickEvent(ClickEvent.Action.OPEN_URL, url)));
});
});
}

@Subcommand({"applyedits"})
@Description("Apply edit from editor")
public void applyEdits(BukkitCommandActor actor, @Named("token") String token) {
public void applyEdits(BukkitCommandActor actor, @Named("token") String token, @Optional @Named("collection") String collection) {
SJMConfig config = SimpleJoinMessage.getInstance().getSJMConfig();
AdventureWebEditorAPI api = SimpleJoinMessage.getInstance().getAdventureWebEditorAPI();
actor.reply(Constants.PREFIX.append(text("Applying your edits...", NamedTextColor.GRAY)));

if (collection != null && !SimpleJoinMessage.getInstance().getDatabase().getCollections().contains(collection)) {
actor.reply(Constants.PREFIX.append(text("The collection '%s' does not exist.".formatted(collection), NamedTextColor.RED)));
return;
}

api.retrieveSession(token)
.whenComplete((value, throwable) -> {
if (throwable != null) {
actor.reply(Constants.PREFIX.append(text("Error occurred when processing your request: " + throwable.getMessage(), NamedTextColor.RED)));
return;
}

config.setJoinMessage(Arrays.stream(value.split("\n")).collect(Collectors.toList()));
config.save();
config.reloadAndSave();
List<String> messages = Arrays.stream(value.split("\n")).toList();
SJMSync sync = SimpleJoinMessage.getInstance().getSyncConfig();

// Perform different action if sync enabled and collection arg are not null
// This makes sure apply edits will operate normally if sync is disabled
if (sync.isEnabled() && collection != null) {
SimpleJoinMessage.getInstance().getDatabase().updateCollection(collection, value);
} else {
config.setJoinMessage(messages);
config.save();
config.reloadAndSave();
}

String command = collection != null ? "/sjm collection show " + collection : "/sjm show";
actor.reply(Constants.PREFIX
.append(text("Web editor data was applied successfully.", NamedTextColor.GREEN))
.append(space())
.append(text("Click here to view join message", NamedTextColor.WHITE, TextDecoration.BOLD)
.hoverEvent(text("Click here to run /sjm show", NamedTextColor.YELLOW))
.clickEvent(clickEvent(ClickEvent.Action.RUN_COMMAND, "/sjm show")))
.hoverEvent(text("Click here to run " + command, NamedTextColor.YELLOW))
.clickEvent(clickEvent(ClickEvent.Action.RUN_COMMAND, command)))
);
});
}

@Subcommand({"regenerate"})
@Description("Regenerate SJM settings back to default")
@Description("Regenerate SJM settings.yml back to default")
public void regenerate(BukkitCommandActor actor) {
actor.reply(Constants.PREFIX.append(text("Regenerating SJM settings...")));
actor.reply(Constants.PREFIX.append(text("Regenerating SJM settings.yml...")));
String fileName = SimpleJoinMessage.getInstance().regenerateSettings();
actor.reply(Constants.PREFIX.append(text("Settings has been regenerated and a backup has been saved as "))
actor.reply(Constants.PREFIX.append(text("settings.yml has been regenerated and a backup has been saved as "))
.append(text(fileName, NamedTextColor.GRAY)));
}

Expand Down Expand Up @@ -208,7 +250,7 @@ public void collectionShow(BukkitCommandActor actor, @Named("collection") String
Player player = actor.requirePlayer();

Bukkit.getScheduler().runTaskAsynchronously(SimpleJoinMessage.getInstance(), () -> SimpleJoinMessage.getInstance().getDatabase()
.getContentFuture(collectionName)
.getRawContentFuture(collectionName)
.whenCompleteAsync((data, throwable) -> {

if (data.isEmpty()) {
Expand Down Expand Up @@ -255,9 +297,10 @@ public void syncSet(BukkitCommandActor actor, @Named("collection") String collec

actor.reply(Constants.PREFIX.append(text("The collection has been updated to %s.".formatted(collectionName), NamedTextColor.GREEN)));
actor.reply(Constants.PREFIX.append(text("It will be applied when the next server starts up.", NamedTextColor.GREEN)));
actor.reply(Constants.PREFIX.append(text("Or you can manually trigger sync by using '/sjm sync now'", NamedTextColor.GREEN)));
}

@Subcommand({"sync"})
@Subcommand({"sync now"})
@Description("Manually perform sync operation")
public void sync(BukkitCommandActor actor) {
Bukkit.getScheduler().runTaskAsynchronously(SimpleJoinMessage.getInstance(), () -> {
Expand Down
21 changes: 18 additions & 3 deletions src/main/java/cc/happyareabean/sjm/database/DatabaseManager.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cc.happyareabean.sjm.database;

import cc.happyareabean.sjm.SimpleJoinMessage;
import cc.happyareabean.sjm.utils.Util;
import com.nivixx.ndatabase.api.NDatabase;
import com.nivixx.ndatabase.api.Promise;
import com.nivixx.ndatabase.api.query.NQuery;
Expand All @@ -22,6 +23,7 @@

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
Expand Down Expand Up @@ -126,7 +128,7 @@ public CompletableFuture<Void> updateCollection(String name, String content) {
.findOne(NQuery.predicate("$.collection_name == " + name));

if (optional.isEmpty())
throw new RuntimeException("This collection does not exist");
return;

SJMData newData = optional.get();
newData.setContent(BASE64_ENCODER.encodeToString(content.getBytes()));
Expand All @@ -139,17 +141,30 @@ public Promise.AsyncEmptyResult deleteCollection(String name) {
.deleteAsync(name);
}

public CompletableFuture<Optional<SJMData>> getContentFuture(String collectionName) {
public CompletableFuture<Optional<SJMData>> getRawContentFuture(String collectionName) {
return SimpleJoinMessage.getInstance().getDatabase().getData()
.findOneAsync(NQuery.predicate("$.collection_name == " + collectionName))
.getResultFuture();
}

public Optional<SJMData> getContent(String collectionName) {
public Optional<SJMData> getRawContent(String collectionName) {
return SimpleJoinMessage.getInstance().getDatabase().getData()
.findOne(NQuery.predicate("$.collection_name == " + collectionName));
}

public CompletableFuture<List<String>> getContentFuture(String collectionName) {
return CompletableFuture.supplyAsync(() -> getContent(collectionName));
}

public List<String> getContent(String collectionName) {
Optional<SJMData> sjmData = getRawContent(collectionName);

if (sjmData.isEmpty()) return null;

String content = new String(Util.BASE64_DECODER.decode(sjmData.get().getContent()));
return Arrays.stream(content.split("\n")).toList();
}

public void updateCollectionNames() {
collections.clear();
data.streamAllValuesAsync().thenAsync(stream -> {
Expand Down

0 comments on commit 3fba698

Please sign in to comment.