diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 0c8cf8e..44f08f3 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -5,26 +5,47 @@
-
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -157,7 +178,7 @@
"git-widget-placeholder": "master",
"kotlin-language-version-configured": "true",
"last_opened_file_path": "/home/a/src/scrow",
- "project.structure.last.edited": "Project",
+ "project.structure.last.edited": "Modules",
"project.structure.proportion": "0.15",
"project.structure.side.proportion": "0.6268199",
"settings.editor.selected.configurable": "preferences.pluginManager"
@@ -169,12 +190,14 @@
+
+
diff --git a/core-bukkit-api/build.gradle.kts b/core-bukkit-api/build.gradle.kts
index a9219c5..1057536 100644
--- a/core-bukkit-api/build.gradle.kts
+++ b/core-bukkit-api/build.gradle.kts
@@ -24,9 +24,9 @@ dependencies {
api("io.nats:jnats:2.25.2")
// http://forge.kentoj.de/scrow/-/packages/maven/de.kentoj.scrow:kencommandapi-core
- api("de.kentoj.scrow:kencommandapi-core:0.22")
+ api("de.kentoj.scrow:kencommandapi-core:0.23")
// http://forge.kentoj.de/scrow/-/packages/maven/de.kentoj.scrow:kencommandapi-bukkit
- api("de.kentoj.scrow:kencommandapi-bukkit:0.22")
+ api("de.kentoj.scrow:kencommandapi-bukkit:0.23")
}
publishing {
diff --git a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/ScrowAPI.java b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/ScrowAPI.java
index 127756b..cca3405 100644
--- a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/ScrowAPI.java
+++ b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/ScrowAPI.java
@@ -6,7 +6,7 @@ import de.kentoj.scrow.bukkit.friends.FriendshipService;
import de.kentoj.scrow.bukkit.misc.EconomyService;
import de.kentoj.scrow.bukkit.misc.PlayerManager;
import de.kentoj.scrow.bukkit.region.RegionManager;
-import de.kentoj.scrowlib.servermanager.InstanceManager;
+import de.kentoj.scrowlib.instancemanager.InstanceManager;
import io.nats.client.Connection;
import lombok.AccessLevel;
import lombok.Getter;
diff --git a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/minigame/MinigameInfo.java b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/minigame/MinigameInfo.java
index 5cefd7c..170da7d 100644
--- a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/minigame/MinigameInfo.java
+++ b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/minigame/MinigameInfo.java
@@ -1,6 +1,6 @@
package de.kentoj.scrow.bukkit.minigame;
-import de.kentoj.scrowlib.servermanager.ServerInstance;
+import de.kentoj.scrowlib.instancemanager.ServerInstance;
public interface MinigameInfo {
diff --git a/core-bukkit-impl/build.gradle.kts b/core-bukkit-impl/build.gradle.kts
index c936191..ee8669b 100644
--- a/core-bukkit-impl/build.gradle.kts
+++ b/core-bukkit-impl/build.gradle.kts
@@ -5,7 +5,6 @@ plugins {
id("de.kentoj.scrow.scrow-repository")
id("de.kentoj.scrow.base-dependencies")
id("de.kentoj.scrow.database")
- id("de.kentoj.scrow.reactor")
}
group = "de.kentoj.scrow"
@@ -22,7 +21,7 @@ dependencies {
implementation(project(":core-bukkit-api"))
// http://forge.kentoj.de/scrow/-/packages/maven/de.kentoj.scrow:kencommandapi-core
- implementation("de.kentoj.scrow:kencommandapi-core:0.22")
+ implementation("de.kentoj.scrow:kencommandapi-core:0.23")
}
tasks {
diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/CoreImplPlugin.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/CoreImplPlugin.java
index 5eaa390..4c465c1 100644
--- a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/CoreImplPlugin.java
+++ b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/CoreImplPlugin.java
@@ -1,9 +1,8 @@
package de.kentoj.scrow.bukkit;
-import de.kentoj.scrow.bukkit.crown.CrownCommand;
import de.kentoj.scrow.bukkit.economy.command.CoinsCommand;
-import de.kentoj.scrow.bukkit.economy.command.CoinsSetLiteral;
import de.kentoj.scrow.bukkit.friends.command.FriendCommand;
+import de.kentoj.scrow.bukkit.instancemanager.command.InstanceCommand;
import de.kentoj.scrow.bukkit.region.RegionPlayerTracker;
import de.kentoj.scrow.bukkit.region.RegionTask;
import de.kentoj.scrow.bukkit.server.LobbyCommand;
@@ -27,8 +26,8 @@ public class CoreImplPlugin extends JavaPlugin {
{
ScrowAPI.getCommandApi().register(new CoinsCommand().getRootNode());
- ScrowAPI.getCommandApi().register(new FriendCommand().getRootNode());
- ScrowAPI.getCommandApi().register(new CrownCommand().getRootNode());
+ ScrowAPI.getCommandApi().register(FriendCommand.create());
+ ScrowAPI.getCommandApi().register(InstanceCommand.create());
ScrowAPI.getCommandApi().register(new PlayCommand().getRootNode());
ScrowAPI.getCommandApi().register(new LobbyCommand().getRootNode());
}
diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/ScrowAPISurface.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/ScrowAPISurface.java
index c2b1eea..bc94557 100644
--- a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/ScrowAPISurface.java
+++ b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/ScrowAPISurface.java
@@ -8,18 +8,14 @@ import de.kentoj.scrow.bukkit.friends.friendship.PostgresFriendshipService;
import de.kentoj.scrow.bukkit.friends.request.InMemoryFriendRequestService;
import de.kentoj.scrow.bukkit.friends.request.PostgresFriendRequestService;
import de.kentoj.scrow.bukkit.region.RegionManagerImpl;
-import de.kentoj.scrowlib.connection.DatabaseConnectionFactoryImpl;
-import de.kentoj.scrowlib.servermanager.InstanceManagerImpl;
+import de.kentoj.scrowlib.instancemanager.InstanceManagerImpl;
import de.kentoj.scrowlib.utils.EnvUtils;
import io.nats.client.Nats;
import io.nats.client.Options;
-import io.r2dbc.spi.ConnectionFactories;
-import io.r2dbc.spi.ConnectionFactory;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
-import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
-import reactor.core.scheduler.Schedulers;
+import org.jdbi.v3.core.Jdbi;
import java.io.IOException;
@@ -41,26 +37,20 @@ public class ScrowAPISurface {
}
if (enableDatabase) {
- ConnectionFactory factory = ConnectionFactories.get(EnvUtils.envOrThrow("HOST_POSTGRES"));
- ScrowAPI.setJdbi(new DatabaseConnectionFactoryImpl(factory));
+ ScrowAPI.setJdbi(Jdbi.create(EnvUtils.envOrThrow("HOST_POSTGRES")));
}
ScrowAPI.setRegionManager(new RegionManagerImpl());
ScrowAPI.setCommandApi(new CommandAPI(plugin));
ScrowAPI.setInstanceManager(new InstanceManagerImpl(ScrowAPI.getNats()));
ScrowAPI.setEconomyService(ScrowAPI.getJdbi() != null ?
- new PostgresEconomyService(ScrowAPI.getJdbi()) : new InMemoryEconomyService());
+ new PostgresEconomyService() : new InMemoryEconomyService());
ScrowAPI.setFriendRequestService(ScrowAPI.getJdbi() != null ?
- new PostgresFriendRequestService(ScrowAPI.getJdbi()) : new InMemoryFriendRequestService());
+ new PostgresFriendRequestService() : new InMemoryFriendRequestService());
ScrowAPI.setFriendshipService(ScrowAPI.getJdbi() != null ?
- new PostgresFriendshipService(ScrowAPI.getJdbi()) : new InMemoryFriendshipService());
+ new PostgresFriendshipService() : new InMemoryFriendshipService());
}
public static void destroyScrowAPI() {
- try {
- ScrowAPI.getJdbi().close();
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
}
}
diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/CrownCommand.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/CrownCommand.java
deleted file mode 100644
index f94001f..0000000
--- a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/CrownCommand.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package de.kentoj.scrow.bukkit.crown;
-
-import de.kentoj.kencommandapi.api.node.CommandNode;
-import de.kentoj.scrowlib.convention.ScrowMessageStyle;
-import lombok.Getter;
-import net.kyori.adventure.text.Component;
-import net.kyori.adventure.text.format.NamedTextColor;
-import org.bukkit.command.CommandSender;
-
-public class CrownCommand {
-
- @Getter
- private final CommandNode rootNode;
-
- public CrownCommand() {
- this.rootNode = CommandNode.node("crown", "server-manager");
- var style = new ScrowMessageStyle(Component.text("crown")
- .color(NamedTextColor.GOLD));
- this.rootNode.addLiteral(new CrownListServersLiteral(style).getNode());
- this.rootNode.addLiteral(new CrownDeployServerLiteral(style).getRootNode());
- this.rootNode.addLiteral(new CrownDestroyServerLiteral(style).getRootNode());
- }
-}
diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/CrownDeployServerLiteral.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/CrownDeployServerLiteral.java
deleted file mode 100644
index 22f1054..0000000
--- a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/CrownDeployServerLiteral.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package de.kentoj.scrow.bukkit.crown;
-
-import de.kentoj.kencommandapi.api.node.CommandNode;
-import de.kentoj.kencommandapi.api.argument.CommandArgument;
-import de.kentoj.kencommandapi.api.argument.types.StringArgumentType;
-import de.kentoj.kencommandapi.api.invocation.CommandContext;
-import de.kentoj.kencommandapi.api.invocation.CommandExecutor;
-import com.leakyabstractions.result.api.Result;
-import de.kentoj.scrow.bukkit.ScrowAPI;
-import lombok.Getter;
-import org.bukkit.command.CommandSender;
-
-import java.util.concurrent.CompletableFuture;
-
-public class CrownDeployServerLiteral implements CommandExecutor {
-
- @Getter
- private final CommandNode rootNode;
- private final CommandArgument templateArg;
-
- public CrownDeployServerLiteral() {
- this.rootNode = CommandNode.node("deploy-server");
- this.rootNode.setExecutor(this);
- {
- this.templateArg = CommandArgument.arg("template", new StringArgumentType<>());
- this.rootNode.addArgument(templateArg);
- }
- }
-
- @Override
- public CompletableFuture> execute(CommandContext ctx) {
- var template = ctx.getArg(templateArg);
- return ScrowAPI.getInstanceManager().deployInstance(template)
- .map(server -> {
- ctx.getSender().sendMessage("Deployed instance of " + template + " with handle " + server.getHandle());
- // FIXME handle unknown server
- return Result.success();
- }).toFuture();
- }
-}
diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/CrownDestroyServerLiteral.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/CrownDestroyServerLiteral.java
deleted file mode 100644
index 06fe639..0000000
--- a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/CrownDestroyServerLiteral.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package de.kentoj.scrow.bukkit.crown;
-
-import de.kentoj.kencommandapi.api.node.CommandNode;
-import de.kentoj.kencommandapi.api.argument.CommandArgument;
-import de.kentoj.kencommandapi.api.argument.types.StringArgumentType;
-import de.kentoj.kencommandapi.api.invocation.CommandContext;
-import de.kentoj.kencommandapi.api.invocation.CommandExecutor;
-import com.leakyabstractions.result.api.Result;
-import com.leakyabstractions.result.api.Results;
-import de.kentoj.scrow.bukkit.ScrowAPI;
-import de.kentoj.scrowlib.servermanager.ServerInstance;
-import lombok.Getter;
-import org.bukkit.command.CommandSender;
-
-import java.util.concurrent.CompletableFuture;
-import java.util.stream.Collectors;
-
-public class CrownDestroyServerLiteral implements CommandExecutor {
-
- @Getter
- private final CommandNode rootNode;
- private final CommandArgument handleArg;
-
- public CrownDestroyServerLiteral() {
- this.rootNode = CommandNode.node("destroy-server");
- this.rootNode.setExecutor(this);
- {
- this.handleArg = CommandArgument.arg("template", new StringArgumentType<>());
- this.handleArg.setSuggestionProvider(ctx -> {
- //noinspection CodeBlock2Expr
- return ScrowAPI.getInstanceManager().getInstances()
- .map(ServerInstance::getHandle)
- .collect(Collectors.toSet())
- .toFuture();
- });
- this.rootNode.addArgument(handleArg);
- }
- }
-
- @Override
- public CompletableFuture> execute(CommandContext ctx) {
- var handle = ctx.getArg(handleArg);
- return ScrowAPI.getInstanceManager().destroyInstance(handle)
- .map(__ -> {
- ctx.getSender().sendMessage("Destroyed server with handle " + handle);
- return Result.success();
- }).toFuture();
- }
-}
diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/CrownListServersLiteral.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/CrownListServersLiteral.java
deleted file mode 100644
index 17753e9..0000000
--- a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/CrownListServersLiteral.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package de.kentoj.scrow.bukkit.crown;
-
-import de.kentoj.kencommandapi.api.invocation.CommandContext;
-import de.kentoj.kencommandapi.api.invocation.CommandExecutor;
-import com.leakyabstractions.result.api.Result;
-import de.kentoj.kencommandapi.api.node.CommandNode;
-import de.kentoj.scrow.bukkit.ScrowAPI;
-import de.kentoj.scrowlib.convention.ScrowMessageStyle;
-import lombok.Getter;
-import net.kyori.adventure.text.Component;
-import org.bukkit.command.CommandSender;
-
-import java.util.concurrent.CompletableFuture;
-
-public class CrownListServersLiteral implements CommandExecutor {
-
- @Getter
- private final CommandNode node;
- private final ScrowMessageStyle style;
-
- public CrownListServersLiteral(ScrowMessageStyle style) {
- this.style = style;
- this.node = CommandNode.node("list-servers");
- this.node.setExecutor(this);
- }
-
- @Override
- public CompletableFuture> execute(CommandContext ctx) {
- return ScrowAPI.getInstanceManager().getInstances()
- .collectList()
- .map(list -> style.list(Component.text("Running instances:"),
- list.stream()
- .map(inst ->
- Component.text(inst.getHandle() + " on port " + inst.getPort() + ": " + inst.getState())
- )
- .toList())
- )
- .doOnNext(ctx.getSender()::sendMessage)
- .thenReturn(Result.success()).toFuture();
- }
-}
diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/economy/command/CoinsCommand.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/economy/command/CoinsCommand.java
index faf9952..2711cce 100644
--- a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/economy/command/CoinsCommand.java
+++ b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/economy/command/CoinsCommand.java
@@ -26,7 +26,7 @@ public class CoinsCommand implements CommandExecutor {
private final MessageStyle style;
public CoinsCommand() {
- style = new ScrowMessageStyle("Coins", NamedTextColor.GOLD);
+ style = ScrowMessageStyle.GENERIC;
rootNode = CommandNode.rootNode(style, "coins", "bal", "balance");
rootNode.setPermission("command.coins.get.self");
@@ -44,7 +44,7 @@ public class CoinsCommand implements CommandExecutor {
public CompletableFuture> execute(CommandContext ctx) {
var player = ((Player) ctx.getSender());
return Tasks.supplyAsync(() ->
- ScrowAPI.getEconomyService().getCoins(player.getUniqueId()))
+ ScrowAPI.getEconomyService().getCoins(player.getUniqueId()))
.>mapSync(amount -> {
player.sendMessage(style.ok("You have " + amount + "$"));
return Results.success(new Object());
diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/command/FriendCommand.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/command/FriendCommand.java
index ffca644..4e07f50 100644
--- a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/command/FriendCommand.java
+++ b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/command/FriendCommand.java
@@ -17,5 +17,6 @@ public class FriendCommand {
rootNode.addLiteral(new FriendAddLiteral(style).getLiteral());
rootNode.addLiteral(new FriendRemoveLiteral(style).getRootNode());
rootNode.addLiteral(new FriendRequestsLiteral(style).getLiteral());
+ return rootNode;
}
}
diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/instancemanager/command/InstanceCommand.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/instancemanager/command/InstanceCommand.java
new file mode 100644
index 0000000..31d83f1
--- /dev/null
+++ b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/instancemanager/command/InstanceCommand.java
@@ -0,0 +1,21 @@
+package de.kentoj.scrow.bukkit.instancemanager.command;
+
+import de.kentoj.kencommandapi.api.node.CommandNode;
+import de.kentoj.kencommandapi.api.node.RootCommandNode;
+import de.kentoj.scrowlib.convention.ScrowMessageStyle;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import net.kyori.adventure.text.format.NamedTextColor;
+import org.bukkit.command.CommandSender;
+
+@NoArgsConstructor(access = AccessLevel.NONE)
+public class InstanceCommand {
+ public static RootCommandNode create() {
+ var style = new ScrowMessageStyle("server-manager", NamedTextColor.RED);
+ RootCommandNode rootNode = CommandNode.rootNode(style, "instance", "server-manager");
+ rootNode.addLiteral(new InstanceListLiteral(style).getNode());
+ rootNode.addLiteral(new InstanceDeployLiteral(style).getLiteral());
+ rootNode.addLiteral(new InstanceDestroyLiteral(style).getLiteral());
+ return rootNode;
+ }
+}
diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/instancemanager/command/InstanceDeployLiteral.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/instancemanager/command/InstanceDeployLiteral.java
new file mode 100644
index 0000000..06c46ab
--- /dev/null
+++ b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/instancemanager/command/InstanceDeployLiteral.java
@@ -0,0 +1,47 @@
+package de.kentoj.scrow.bukkit.instancemanager.command;
+
+import com.leakyabstractions.result.api.Result;
+import com.leakyabstractions.result.core.Results;
+import de.kentoj.kencommandapi.api.argument.CommandArgument;
+import de.kentoj.kencommandapi.api.argument.types.StringArgumentType;
+import de.kentoj.kencommandapi.api.invocation.CommandContext;
+import de.kentoj.kencommandapi.api.invocation.CommandExecutor;
+import de.kentoj.kencommandapi.api.node.CommandNode;
+import de.kentoj.scrow.bukkit.ScrowAPI;
+import de.kentoj.scrow.bukkit.scheduler.Tasks;
+import de.kentoj.scrowlib.convention.ScrowMessageStyle;
+import lombok.Getter;
+import org.bukkit.command.CommandSender;
+
+import java.util.concurrent.CompletableFuture;
+
+public class InstanceDeployLiteral implements CommandExecutor {
+
+ @Getter
+ private final CommandNode literal;
+ private final CommandArgument templateArg;
+ private final ScrowMessageStyle style;
+
+ public InstanceDeployLiteral(ScrowMessageStyle style) {
+ this.style = style;
+
+ templateArg = CommandArgument.arg("template", new StringArgumentType<>());
+
+ literal = CommandNode.node("deploy");
+ literal.addArgument(templateArg);
+ literal.setExecutor(this);
+ }
+
+ @Override
+ public CompletableFuture> execute(CommandContext ctx) {
+ var template = ctx.getArg(templateArg);
+ ctx.getSender().sendMessage(style.ok("Deploying instance... this may take a while"));
+ return Tasks.supplyAsync(() ->
+ ScrowAPI.getInstanceManager().deployInstance(template))
+ .>mapSync(instance -> {
+ ctx.getSender().sendMessage(style.ok("Deployed instance of " + template + " with handle " + instance.getHandle()));
+ // FIXME handle unknown server
+ return Results.success(new Object());
+ }).toFuture();
+ }
+}
diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/instancemanager/command/InstanceDestroyLiteral.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/instancemanager/command/InstanceDestroyLiteral.java
new file mode 100644
index 0000000..fc2063c
--- /dev/null
+++ b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/instancemanager/command/InstanceDestroyLiteral.java
@@ -0,0 +1,52 @@
+package de.kentoj.scrow.bukkit.instancemanager.command;
+
+import com.leakyabstractions.result.api.Result;
+import com.leakyabstractions.result.core.Results;
+import de.kentoj.kencommandapi.api.argument.CommandArgument;
+import de.kentoj.kencommandapi.api.argument.types.StringArgumentType;
+import de.kentoj.kencommandapi.api.invocation.CommandContext;
+import de.kentoj.kencommandapi.api.invocation.CommandExecutor;
+import de.kentoj.kencommandapi.api.node.CommandNode;
+import de.kentoj.scrow.bukkit.ScrowAPI;
+import de.kentoj.scrow.bukkit.scheduler.Tasks;
+import de.kentoj.scrowlib.convention.ScrowMessageStyle;
+import de.kentoj.scrowlib.instancemanager.ServerInstance;
+import lombok.Getter;
+import org.bukkit.command.CommandSender;
+
+import java.util.concurrent.CompletableFuture;
+
+public class InstanceDestroyLiteral implements CommandExecutor {
+
+ @Getter
+ private final CommandNode literal;
+ private final CommandArgument handleArg;
+ private final ScrowMessageStyle style;
+
+ public InstanceDestroyLiteral(ScrowMessageStyle style) {
+ this.style = style;
+
+ handleArg = CommandArgument.arg("handle", new StringArgumentType<>());
+ handleArg.setSuggestionProvider(ctx ->
+ Tasks.supplyAsync(() -> ScrowAPI.getInstanceManager().getInstances().stream()
+ .map(ServerInstance::getHandle)
+ .toList())
+ .toFuture());
+
+ literal = CommandNode.node("destroy");
+ literal.addArgument(handleArg);
+ literal.setExecutor(this);
+ }
+
+ @Override
+ public CompletableFuture> execute(CommandContext ctx) {
+ var handle = ctx.getArg(handleArg);
+ return Tasks.supplyAsync(() -> ScrowAPI.getInstanceManager().destroyInstance(handle))
+ .>mapSync(found -> {
+ if (!found)
+ return Results.failure("No instance with that handle found");
+ ctx.getSender().sendMessage(style.ok("Destroyed server with handle " + handle));
+ return Results.success(new Object());
+ }).toFuture();
+ }
+}
diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/instancemanager/command/InstanceListLiteral.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/instancemanager/command/InstanceListLiteral.java
new file mode 100644
index 0000000..3be7901
--- /dev/null
+++ b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/instancemanager/command/InstanceListLiteral.java
@@ -0,0 +1,43 @@
+package de.kentoj.scrow.bukkit.instancemanager.command;
+
+import com.leakyabstractions.result.api.Result;
+import com.leakyabstractions.result.core.Results;
+import de.kentoj.kencommandapi.api.invocation.CommandContext;
+import de.kentoj.kencommandapi.api.invocation.CommandExecutor;
+import de.kentoj.kencommandapi.api.node.CommandNode;
+import de.kentoj.scrow.bukkit.ScrowAPI;
+import de.kentoj.scrow.bukkit.scheduler.Tasks;
+import de.kentoj.scrowlib.convention.ScrowMessageStyle;
+import lombok.Getter;
+import net.kyori.adventure.text.Component;
+import org.bukkit.command.CommandSender;
+
+import java.util.concurrent.CompletableFuture;
+
+public class InstanceListLiteral implements CommandExecutor {
+
+ @Getter
+ private final CommandNode node;
+ private final ScrowMessageStyle style;
+
+ public InstanceListLiteral(ScrowMessageStyle style) {
+ this.style = style;
+ this.node = CommandNode.node("list");
+ this.node.setExecutor(this);
+ }
+
+ @Override
+ public CompletableFuture> execute(CommandContext ctx) {
+ return Tasks.supplyAsync(() ->
+ ScrowAPI.getInstanceManager().getInstances())
+ .>mapSync(instances -> {
+ var msg = Component.text("Running instances:");
+ for (var inst : instances) {
+ msg = msg.appendNewline()
+ .append(Component.text(" - " + inst.getHandle() + " on port " + inst.getPort()));
+ }
+ ctx.getSender().sendMessage(style.ok(msg));
+ return Results.success(new Object());
+ }).toFuture();
+ }
+}
diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/playermanager/PlayerManagerImpl.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/playermanager/PlayerManagerImpl.java
index 7e35110..27434a5 100644
--- a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/playermanager/PlayerManagerImpl.java
+++ b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/playermanager/PlayerManagerImpl.java
@@ -1,8 +1,8 @@
package de.kentoj.scrow.bukkit.playermanager;
-import com.leakyabstractions.result.api.Result;
import de.kentoj.scrow.bukkit.misc.PlayerManager;
import de.kentoj.scrowlib.messaging.MessageBroker;
+import de.kentoj.scrowlib.utils.ResultUtils;
import lombok.RequiredArgsConstructor;
import org.bson.Document;
@@ -14,10 +14,10 @@ public class PlayerManagerImpl implements PlayerManager {
private final MessageBroker messageBroker;
@Override
- public Result