This commit is contained in:
kento2 2026-08-10 21:45:45 +02:00
parent a088d27485
commit 46978ae799
18 changed files with 2233 additions and 112 deletions

View file

@ -5,7 +5,8 @@ bazel_dep(name = "rules_shell", version = "0.8.0")
git_override( git_override(
module_name = "rules_jvm_external", module_name = "rules_jvm_external",
remote = "http://forge.kentoj.de/scrow/rules_jvm_external.git", remote = "https://github.com/acecilia/rules_jvm_external.git",
branch = "3-snapshot_support",
) )
maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven") maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven")
@ -20,27 +21,31 @@ maven.install(
"org.slf4j:slf4j-simple:2.0.18", "org.slf4j:slf4j-simple:2.0.18",
"net.kyori:adventure-api:5.2.0", "net.kyori:adventure-api:5.2.0",
"net.kyori:adventure-text-minimessage:5.2.0", "net.kyori:adventure-text-minimessage:5.2.0",
"io.papermc.paper:paper-api:[26.2.build,)", # use `env REPIN=1 bazel run @maven//:pin` after updating
"com.velocitypowered:velocity-api:4.1.0-20260802.091736-8", "com.velocitypowered:velocity-api:4.1.0-SNAPSHOT",
"org.jdbi:jdbi3-core:3.53.0", "org.jdbi:jdbi3-core:3.53.0",
"org.jdbi:jdbi3-postgres:3.53.0", "org.jdbi:jdbi3-postgres:3.53.0",
"org.postgresql:postgresql:42.7.12", "org.postgresql:postgresql:42.7.12",
"org.mongodb:bson:5.8.0", "org.mongodb:bson:5.8.0",
"io.nats:jnats:2.25.2", "io.nats:jnats:2.25.2",
"de.kentoj.scrow:kencommandapi-core:0.41-SNAPSHOT", "de.kentoj.scrow:kencommandapi-core:0.42-SNAPSHOT",
"de.kentoj.scrow:kencommandapi-bukkit:0.41-SNAPSHOT", "de.kentoj.scrow:kencommandapi-bukkit:0.42-SNAPSHOT",
"de.kentoj.scrow:kencommandapi-velocity:0.41-SNAPSHOT", "de.kentoj.scrow:kencommandapi-velocity:0.42-SNAPSHOT",
"io.papermc.paper:paper-api:[26.2.build,)", "io.papermc.paper:paper-api:[26.2.build,)",
"net.luckperms:api:5.5", "net.luckperms:api:5.5",
"com.google.code.gson:gson:2.14.0", "com.google.code.gson:gson:2.14.0",
], ],
fetch_sources = True, fetch_sources = False,
repositories = [ repositories = [
"https://repo.papermc.io/repository/maven-public/", "https://repo1.maven.org/maven2",
"https://git.lab0x13.site/api/packages/scrow/maven", "https://git.lab0x13.site/api/packages/scrow/maven",
"https://repo.papermc.io/repository/maven-public/",
], ],
known_contributing_modules = ["protobuf"], known_contributing_modules = ["protobuf"],
fail_on_missing_checksum = False, # for kencommandapi fail_on_missing_checksum = False, # for kencommandapi
resolver = "gradle",
lock_file = "//:maven_install.json",
) )
# luckperms is provided at runtime # luckperms is provided at runtime

View file

@ -7,6 +7,7 @@
- refactor BUILD files: MODULES.bazel - refactor BUILD files: MODULES.bazel
## core ## core
- configurator: need to use json nodes for storing data so i can rlly update subfields
- convert commands to new api - convert commands to new api
- CommandExecutor now has a style parameter which is always MessageStyle(not ScrowMessageStyle), - CommandExecutor now has a style parameter which is always MessageStyle(not ScrowMessageStyle),
this kinda sucks. i could merge kencommandapi into core or make it more flexible(but then i need even more generics) this kinda sucks. i could merge kencommandapi into core or make it more flexible(but then i need even more generics)

View file

@ -38,7 +38,7 @@ class KeyLiteral {
var actionLiteralBuilder = Literal.<Player>builder(action.name()); var actionLiteralBuilder = Literal.<Player>builder(action.name());
for (var argument : action.arguments()) for (var argument : action.arguments())
actionLiteralBuilder.withArgument(argument); actionLiteralBuilder.withArgument(argument);
actionLiteralBuilder.withSyncExecutor((style, ctx) -> { actionLiteralBuilder.withSyncExecutor(ctx -> {
if (action.requiresValue() && node.value() == null) { if (action.requiresValue() && node.value() == null) {
ctx.sender().sendMessage(style.err("No value set.")); ctx.sender().sendMessage(style.err("No value set."));
return; return;

View file

@ -24,12 +24,12 @@ public final class CoinsCommand {
.asRootLiteral(ScrowMessageStyle.GENERIC); .asRootLiteral(ScrowMessageStyle.GENERIC);
} }
public CompletableFuture<?> execute(MessageStyle style, CommandContext<Player> ctx) { public CompletableFuture<?> execute(CommandContext<Player> ctx) {
var player = ctx.sender(); var player = ctx.sender();
return Tasks.supplyAsync(() -> return Tasks.supplyAsync(() ->
ScrowAPI.economyService().getCoins(player.getUniqueId())) ScrowAPI.economyService().getCoins(player.getUniqueId()))
.thenSync(amount -> .thenSync(amount ->
player.sendMessage(style.ok("You have " + amount + "$"))) player.sendMessage(ctx.style().ok("You have " + amount + "$")))
.toFuture(); .toFuture();
} }

View file

@ -28,12 +28,12 @@ public final class CoinsGetLiteral {
.build(); .build();
} }
private CompletableFuture<?> execute(MessageStyle style, CommandContext<Player> ctx) { private CompletableFuture<?> execute(CommandContext<Player> ctx) {
var player = ctx.getArg(playerArg); var player = ctx.getArg(playerArg);
return Tasks.supplyAsync(() -> return Tasks.supplyAsync(() ->
ScrowAPI.economyService().getCoins(player.getUniqueId())) ScrowAPI.economyService().getCoins(player.getUniqueId()))
.thenSync(amount -> .thenSync(amount ->
ctx.sender().sendMessage(style.ok(player.getName() + " has " + amount + "$"))) ctx.sender().sendMessage(ctx.style().ok(player.getName() + " has " + amount + "$")))
.toFuture(); .toFuture();
} }

View file

@ -33,13 +33,13 @@ public final class CoinsSetLiteral {
.build(); .build();
} }
private CompletableFuture<?> execute(MessageStyle style, CommandContext<Player> ctx) { private CompletableFuture<?> execute(CommandContext<Player> ctx) {
var player = ctx.getArg(playerArg); var player = ctx.getArg(playerArg);
var amount = ctx.getArg(amountArg); var amount = ctx.getArg(amountArg);
return Tasks.runAsync(() -> return Tasks.runAsync(() ->
ScrowAPI.economyService().setCoins(player.getUniqueId(), amount)) ScrowAPI.economyService().setCoins(player.getUniqueId(), amount))
.runSync(() -> .runSync(() ->
ctx.sender().sendMessage(style.ok(player.getName() + " now has " + amount + "$"))) ctx.sender().sendMessage(ctx.style().ok(player.getName() + " now has " + amount + "$")))
.toFuture(); .toFuture();
} }

View file

@ -5,6 +5,7 @@ import com.leakyabstractions.result.core.Results;
import de.kentoj.kencommandapi.api.argument.CommandArgumentSpec; import de.kentoj.kencommandapi.api.argument.CommandArgumentSpec;
import de.kentoj.kencommandapi.api.invocation.CommandContext; import de.kentoj.kencommandapi.api.invocation.CommandContext;
import de.kentoj.kencommandapi.api.literal.Literal; import de.kentoj.kencommandapi.api.literal.Literal;
import de.kentoj.kencommandapi.api.platform.MessageStyle;
import de.kentoj.kencommandapi.type.OfflinePlayerArgumentType; import de.kentoj.kencommandapi.type.OfflinePlayerArgumentType;
import de.kentoj.scrow.bukkit.ScrowAPI; import de.kentoj.scrow.bukkit.ScrowAPI;
import de.kentoj.scrow.bukkit.scheduler.Task; import de.kentoj.scrow.bukkit.scheduler.Task;
@ -27,12 +28,10 @@ public final class FriendAddLiteral {
private final Literal<Player> literal; private final Literal<Player> literal;
private final CommandArgumentSpec<Player, OfflinePlayer> playerArg; private final CommandArgumentSpec<Player, OfflinePlayer> playerArg;
private final ScrowMessageStyle style;
private final FriendRequestService requestService = ScrowAPI.friendRequestService(); private final FriendRequestService requestService = ScrowAPI.friendRequestService();
private final FriendshipService friendsService = ScrowAPI.friendshipService(); private final FriendshipService friendsService = ScrowAPI.friendshipService();
FriendAddLiteral(ScrowMessageStyle style) { FriendAddLiteral() {
this.style = style;
playerArg = CommandArgumentSpec.builder("player", new OfflinePlayerArgumentType<Player>()) playerArg = CommandArgumentSpec.builder("player", new OfflinePlayerArgumentType<Player>())
.build(); .build();
literal = Literal.<Player>builder("add") literal = Literal.<Player>builder("add")
@ -41,19 +40,19 @@ public final class FriendAddLiteral {
.build(); .build();
} }
private CompletableFuture<Result<Object, String>> execute(CommandContext<Player> ctx) { private CompletableFuture<?> execute(CommandContext<Player> ctx) {
var self = ctx.sender(); var self = ctx.sender();
var other = ctx.getArg(playerArg); var other = ctx.getArg(playerArg);
return Tasks.supplyAsync(() -> findAction(self, other) return Tasks.supplyAsync(() -> findAction(self, other)
.mapSuccess(action -> { .mapSuccess(action -> {
if (action == AddAction.SEND_REQUEST) sendRequest(self, other); if (action == AddAction.SEND_REQUEST) sendRequest(ctx.style(), self, other);
else if (action == AddAction.ACCEPT_REQUEST) acceptRequest(self, other); else if (action == AddAction.ACCEPT_REQUEST) acceptRequest(ctx.style(), self, other);
return new Object(); return new Object();
})) }))
.toFuture(); .toFuture();
} }
private void sendRequest(Player self, OfflinePlayer other) { private void sendRequest(MessageStyle style, Player self, OfflinePlayer other) {
Tasks.runAsync(() -> Tasks.runAsync(() ->
requestService.saveFriendRequest(new FriendRequestImpl(self.getUniqueId(), other.getUniqueId()))) requestService.saveFriendRequest(new FriendRequestImpl(self.getUniqueId(), other.getUniqueId())))
.runSync(() -> { .runSync(() -> {
@ -65,7 +64,7 @@ public final class FriendAddLiteral {
.await(); .await();
} }
private void acceptRequest(Player self, OfflinePlayer other) { private void acceptRequest(MessageStyle style, Player self, OfflinePlayer other) {
Tasks.runAsync(() -> Tasks.awaitAll( Tasks.runAsync(() -> Tasks.awaitAll(
Tasks.runAsync(() -> requestService.deleteFriendRequest(self.getUniqueId(), other.getUniqueId())), Tasks.runAsync(() -> requestService.deleteFriendRequest(self.getUniqueId(), other.getUniqueId())),
Tasks.runAsync(() -> requestService.deleteFriendRequest(other.getUniqueId(), self.getUniqueId())), Tasks.runAsync(() -> requestService.deleteFriendRequest(other.getUniqueId(), self.getUniqueId())),

View file

@ -1,12 +1,11 @@
package de.kentoj.scrow.bukkit.command.friends; package de.kentoj.scrow.bukkit.command.friends;
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.CommandContext;
import de.kentoj.kencommandapi.api.literal.Literal; import de.kentoj.kencommandapi.api.literal.Literal;
import de.kentoj.kencommandapi.api.platform.MessageStyle; import de.kentoj.kencommandapi.api.platform.MessageStyle;
import de.kentoj.scrow.bukkit.ScrowAPI; import de.kentoj.scrow.bukkit.ScrowAPI;
import de.kentoj.scrow.bukkit.scheduler.Tasks; import de.kentoj.scrow.bukkit.scheduler.Tasks;
import de.kentoj.scrowlib.convention.ScrowMessageStyle;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.MiniMessage;
@ -29,7 +28,7 @@ public final class FriendListLiteral {
.build(); .build();
} }
private CompletableFuture<?> displayFriendList(MessageStyle style, CommandContext<Player> ctx) { private CompletableFuture<?> displayFriendList(CommandContext<Player> ctx) {
var sender = ctx.sender(); var sender = ctx.sender();
return Tasks.supplyAsync(() -> return Tasks.supplyAsync(() ->
ScrowAPI.friendshipService().getFriendships(sender.getUniqueId())) ScrowAPI.friendshipService().getFriendships(sender.getUniqueId()))
@ -39,11 +38,11 @@ public final class FriendListLiteral {
.sorted(this::compareByOnlineStatus) .sorted(this::compareByOnlineStatus)
.toList(); .toList();
if (friends.isEmpty()) { if (friends.isEmpty()) {
ctx.sender().sendMessage(style.err("You have no friends. Use /friend add <player>")); ctx.sender().sendMessage(ctx.style().err("You have no friends. Use /friend add <player>"));
return; return;
} }
sender.sendMessage(formatList(style, friends)); sender.sendMessage(formatList(ctx.style(), friends));
}).toFuture(); }).toFuture();
} }
@ -53,7 +52,7 @@ public final class FriendListLiteral {
return 0; return 0;
} }
private Component formatList(MessageStyle style, List<OfflinePlayer> friends) { private Component formatList(ScrowMessageStyle style, List<OfflinePlayer> friends) {
var message = style.ok(MiniMessage.miniMessage().deserialize("Your friends:")); var message = style.ok(MiniMessage.miniMessage().deserialize("Your friends:"));
for (var friend : friends) { for (var friend : friends) {
var status = MiniMessage.miniMessage().deserialize(friend.isOnline() var status = MiniMessage.miniMessage().deserialize(friend.isOnline()

View file

@ -8,7 +8,6 @@ import de.kentoj.kencommandapi.api.literal.Literal;
import de.kentoj.kencommandapi.type.OfflinePlayerArgumentType; import de.kentoj.kencommandapi.type.OfflinePlayerArgumentType;
import de.kentoj.scrow.bukkit.ScrowAPI; import de.kentoj.scrow.bukkit.ScrowAPI;
import de.kentoj.scrow.bukkit.scheduler.Tasks; import de.kentoj.scrow.bukkit.scheduler.Tasks;
import de.kentoj.scrowlib.convention.ScrowMessageStyle;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -18,10 +17,8 @@ public final class FriendRemoveLiteral {
private final Literal<Player> literal; private final Literal<Player> literal;
private final CommandArgumentSpec<Player, OfflinePlayer> playerArg; private final CommandArgumentSpec<Player, OfflinePlayer> playerArg;
private final ScrowMessageStyle style;
FriendRemoveLiteral(ScrowMessageStyle style) { FriendRemoveLiteral() {
this.style = style;
playerArg = CommandArgumentSpec.<Player, OfflinePlayer>builder("player", new OfflinePlayerArgumentType<>()) playerArg = CommandArgumentSpec.<Player, OfflinePlayer>builder("player", new OfflinePlayerArgumentType<>())
.build(); .build();
literal = Literal.<Player>builder("remove") literal = Literal.<Player>builder("remove")
@ -30,15 +27,16 @@ public final class FriendRemoveLiteral {
.build(); .build();
} }
private CompletableFuture<Result<Object, String>> removeFriend(CommandContext<Player> ctx) { private CompletableFuture<?> removeFriend(CommandContext<Player> ctx) {
var friend = ctx.getArg(playerArg); var friend = ctx.getArg(playerArg);
return Tasks.supplyAsync(() -> return Tasks.supplyAsync(() ->
ScrowAPI.friendshipService().deleteFriendship(friend.getUniqueId(), ctx.sender().getUniqueId())) ScrowAPI.friendshipService().deleteFriendship(friend.getUniqueId(), ctx.sender().getUniqueId()))
.<Result<Object, String>>mapSync(deleted -> { .thenSync(deleted -> {
if (!deleted) if (!deleted) {
return Results.failure("You are not friends with " + friend.getName() + "."); ctx.sender().sendMessage(ctx.style().err("You are not friends with " + friend.getName() + "."));
ctx.sender().sendMessage(style.ok("You have ended the friendship with " + friend.getName() + ".")); return;
return Results.success(new Object()); }
ctx.sender().sendMessage(ctx.style().ok("You have ended the friendship with " + friend.getName() + "."));
}).toFuture(); }).toFuture();
} }

View file

@ -19,11 +19,9 @@ public final class FriendRequestDeclineLiteral {
private final Literal<Player> literal; private final Literal<Player> literal;
private final CommandArgumentSpec<Player, OfflinePlayer> playerArg; private final CommandArgumentSpec<Player, OfflinePlayer> playerArg;
private final ScrowMessageStyle style;
private final FriendRequestService requestService = ScrowAPI.friendRequestService(); private final FriendRequestService requestService = ScrowAPI.friendRequestService();
FriendRequestDeclineLiteral(ScrowMessageStyle style) { FriendRequestDeclineLiteral() {
this.style = style;
playerArg = CommandArgumentSpec.builder("player", new OfflinePlayerArgumentType<Player>()) playerArg = CommandArgumentSpec.builder("player", new OfflinePlayerArgumentType<Player>())
.build(); .build();
literal = Literal.<Player>builder("reject", "decline") literal = Literal.<Player>builder("reject", "decline")
@ -32,16 +30,17 @@ public final class FriendRequestDeclineLiteral {
.build(); .build();
} }
private CompletableFuture<Result<Object, String>> declineFriendRequest(CommandContext<Player> ctx) { private CompletableFuture<?> declineFriendRequest(CommandContext<Player> ctx) {
var other = ctx.getArg(playerArg); var other = ctx.getArg(playerArg);
return Tasks.supplyAsync(() -> return Tasks.supplyAsync(() ->
requestService.deleteFriendRequest(other.getUniqueId(), ctx.sender().getUniqueId())) requestService.deleteFriendRequest(other.getUniqueId(), ctx.sender().getUniqueId()))
.<Result<Object, String>>mapSync(deleted -> { .thenSync(deleted -> {
if (!deleted) if (!deleted) {
return Results.failure("There's no incoming friend request from " + other.getName() + "."); ctx.sender().sendMessage(ctx.style().err("There's no incoming friend request from " + other.getName() + "."));
ctx.sender().sendMessage(style.ok("Friend request declined.")); return;
ScrowAPI.getPlayer(other).sendMessage(style.ok(ctx.sender().getName() + " has declined your friend request.")); }
return Results.success(new Object()); ctx.sender().sendMessage(ctx.style().ok("Friend request declined."));
ScrowAPI.getPlayer(other).sendMessage(ctx.style().ok(ctx.sender().getName() + " has declined your friend request."));
}).toFuture(); }).toFuture();
} }

View file

@ -1,9 +1,8 @@
package de.kentoj.scrow.bukkit.command.friends; package de.kentoj.scrow.bukkit.command.friends;
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.CommandContext;
import de.kentoj.kencommandapi.api.literal.Literal; import de.kentoj.kencommandapi.api.literal.Literal;
import de.kentoj.kencommandapi.api.platform.MessageStyle;
import de.kentoj.scrow.bukkit.ScrowAPI; import de.kentoj.scrow.bukkit.ScrowAPI;
import de.kentoj.scrow.bukkit.scheduler.Tasks; import de.kentoj.scrow.bukkit.scheduler.Tasks;
import de.kentoj.scrowlib.convention.ScrowMessageStyle; import de.kentoj.scrowlib.convention.ScrowMessageStyle;
@ -22,25 +21,25 @@ import static net.kyori.adventure.text.Component.text;
public final class FriendRequestsLiteral { public final class FriendRequestsLiteral {
private final Literal<Player> literal; private final Literal<Player> literal;
private final ScrowMessageStyle style;
FriendRequestsLiteral(ScrowMessageStyle style) { FriendRequestsLiteral() {
this.style = style;
literal = Literal.<Player>builder("requests") literal = Literal.<Player>builder("requests")
.withExecutor(this::displayFriendRequests) .withExecutor(this::displayFriendRequests)
.build(); .build();
} }
private CompletableFuture<Result<Object, String>> displayFriendRequests(CommandContext<Player> ctx) { private CompletableFuture<?> displayFriendRequests(CommandContext<Player> ctx) {
return Tasks.supplyAsync(() -> return Tasks.supplyAsync(() ->
ScrowAPI.friendRequestService().getFriendRequestsTo(ctx.sender().getUniqueId())) ScrowAPI.friendRequestService().getFriendRequestsTo(ctx.sender().getUniqueId()))
.<Result<Object, String>>mapAsync(list -> { .thenSync(list -> {
if (list.isEmpty()) return Results.failure("You have no friend requests."); if (list.isEmpty()) {
ctx.sender().sendMessage(ctx.style().err("You have no friend requests."));
return;
}
var requesters = list.stream() var requesters = list.stream()
.sorted(this::compareByAge) .sorted(this::compareByAge)
.map(fr -> Bukkit.getOfflinePlayer(fr.from()).getName()); .map(fr -> Bukkit.getOfflinePlayer(fr.from()).getName());
ctx.sender().sendMessage(formatList(requesters.toList())); ctx.sender().sendMessage(formatList(ctx.style(), requesters.toList()));
return Results.success(new Object());
}).toFuture(); }).toFuture();
} }
@ -48,7 +47,7 @@ public final class FriendRequestsLiteral {
return a.createdAt().isAfter(b.createdAt()) ? 1 : -1; return a.createdAt().isAfter(b.createdAt()) ? 1 : -1;
} }
private Component formatList(List<String> requesters) { private Component formatList(ScrowMessageStyle style, List<String> requesters) {
var message = style.ok(MiniMessage.miniMessage().deserialize("Open friend requests:")); var message = style.ok(MiniMessage.miniMessage().deserialize("Open friend requests:"));
for (String requester : requesters) { for (String requester : requesters) {
message = message message = message

View file

@ -11,12 +11,11 @@ public final class InstanceCommand {
private final RootLiteral<CommandSender> rootLiteral; private final RootLiteral<CommandSender> rootLiteral;
public InstanceCommand(InstanceCache instanceCache) { public InstanceCommand(InstanceCache instanceCache) {
var style = new ScrowMessageStyle("server-manager", NamedTextColor.RED);
rootLiteral = Literal.<CommandSender>builder("instance", "server-manager") rootLiteral = Literal.<CommandSender>builder("instance", "server-manager")
.withLiteral(new InstanceListLiteral(style).literal()) .withLiteral(new InstanceListLiteral().literal())
.withLiteral(new InstanceDeployLiteral(style).literal()) .withLiteral(new InstanceDeployLiteral().literal())
.withLiteral(new InstanceDestroyLiteral(instanceCache, style).literal()) .withLiteral(new InstanceDestroyLiteral(instanceCache).literal())
.asRootLiteral(style); .asRootLiteral(new ScrowMessageStyle("server-manager", NamedTextColor.RED));
} }
public RootLiteral<CommandSender> rootLiteral() { public RootLiteral<CommandSender> rootLiteral() {

View file

@ -1,14 +1,11 @@
package de.kentoj.scrow.bukkit.command.instance; package de.kentoj.scrow.bukkit.command.instance;
import com.leakyabstractions.result.api.Result;
import com.leakyabstractions.result.core.Results;
import de.kentoj.kencommandapi.api.argument.CommandArgumentSpec; import de.kentoj.kencommandapi.api.argument.CommandArgumentSpec;
import de.kentoj.kencommandapi.api.argument.types.StringArgumentType; import de.kentoj.kencommandapi.api.argument.types.StringArgumentType;
import de.kentoj.kencommandapi.api.invocation.CommandContext; import de.kentoj.kencommandapi.api.invocation.CommandContext;
import de.kentoj.kencommandapi.api.literal.Literal; import de.kentoj.kencommandapi.api.literal.Literal;
import de.kentoj.scrow.bukkit.ScrowAPI; import de.kentoj.scrow.bukkit.ScrowAPI;
import de.kentoj.scrow.bukkit.scheduler.Tasks; import de.kentoj.scrow.bukkit.scheduler.Tasks;
import de.kentoj.scrowlib.convention.ScrowMessageStyle;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
@ -17,11 +14,8 @@ public final class InstanceDeployLiteral {
private final Literal<CommandSender> literal; private final Literal<CommandSender> literal;
private final CommandArgumentSpec<CommandSender, String> templateArg; private final CommandArgumentSpec<CommandSender, String> templateArg;
private final ScrowMessageStyle style;
InstanceDeployLiteral(ScrowMessageStyle style) {
this.style = style;
InstanceDeployLiteral() {
templateArg = CommandArgumentSpec.builder("template", new StringArgumentType<CommandSender>()) templateArg = CommandArgumentSpec.builder("template", new StringArgumentType<CommandSender>())
.build(); .build();
literal = Literal.<CommandSender>builder("deploy") literal = Literal.<CommandSender>builder("deploy")
@ -30,15 +24,14 @@ public final class InstanceDeployLiteral {
.build(); .build();
} }
private CompletableFuture<Result<Object, String>> deployInstance(CommandContext<CommandSender> ctx) { private CompletableFuture<?> deployInstance(CommandContext<CommandSender> ctx) {
var template = ctx.getArg(templateArg); var template = ctx.getArg(templateArg);
ctx.sender().sendMessage(style.ok("Deploying instance... this may take a while.")); ctx.sender().sendMessage(ctx.style().ok("Deploying instance... this may take a while."));
return Tasks.supplyAsync(() -> return Tasks.supplyAsync(() ->
ScrowAPI.instanceManager().deployInstance(template)) ScrowAPI.instanceManager().deployInstance(template))
.<Result<Object, String>>mapSync(instance -> { .thenSync(instance -> {
ctx.sender().sendMessage(style.ok("Deployed instance of " + template + " with handle " + instance.handle() + ".")); ctx.sender().sendMessage(ctx.style().ok("Deployed instance of " + template + " with handle " + instance.handle() + "."));
// FIXME handle unknown server // FIXME handle unknown server
return Results.success(new Object());
}).toFuture(); }).toFuture();
} }

View file

@ -1,7 +1,5 @@
package de.kentoj.scrow.bukkit.command.instance; package de.kentoj.scrow.bukkit.command.instance;
import com.leakyabstractions.result.api.Result;
import com.leakyabstractions.result.core.Results;
import de.kentoj.kencommandapi.api.argument.CommandArgumentSpec; import de.kentoj.kencommandapi.api.argument.CommandArgumentSpec;
import de.kentoj.kencommandapi.api.argument.types.StringArgumentType; import de.kentoj.kencommandapi.api.argument.types.StringArgumentType;
import de.kentoj.kencommandapi.api.invocation.CommandContext; import de.kentoj.kencommandapi.api.invocation.CommandContext;
@ -18,11 +16,8 @@ public final class InstanceDestroyLiteral {
private final Literal<CommandSender> literal; private final Literal<CommandSender> literal;
private final CommandArgumentSpec<CommandSender, String> handleArg; private final CommandArgumentSpec<CommandSender, String> handleArg;
private final ScrowMessageStyle style;
InstanceDestroyLiteral(InstanceCache cache, ScrowMessageStyle style) {
this.style = style;
InstanceDestroyLiteral(InstanceCache cache) {
handleArg = CommandArgumentSpec.builder("handle", new StringArgumentType<CommandSender>()) handleArg = CommandArgumentSpec.builder("handle", new StringArgumentType<CommandSender>())
.withSuggestionProvider((_, _) -> .withSuggestionProvider((_, _) ->
cache.getInstances().stream() cache.getInstances().stream()
@ -35,14 +30,15 @@ public final class InstanceDestroyLiteral {
.build(); .build();
} }
private CompletableFuture<Result<Object, String>> destroyInstance(CommandContext<CommandSender> ctx) { private CompletableFuture<?> destroyInstance(CommandContext<CommandSender> ctx) {
var handle = ctx.getArg(handleArg); var handle = ctx.getArg(handleArg);
return Tasks.supplyAsync(() -> ScrowAPI.instanceManager().destroyInstance(handle)) return Tasks.supplyAsync(() -> ScrowAPI.instanceManager().destroyInstance(handle))
.<Result<Object, String>>mapSync(found -> { .thenSync(found -> {
if (!found) if (!found) {
return Results.failure("No instance with that handle found."); ctx.sender().sendMessage(ctx.style().err("No instance with that handle found."));
ctx.sender().sendMessage(style.ok("Destroyed server with handle " + handle + ".")); return;
return Results.success(new Object()); }
ctx.sender().sendMessage(ctx.style().ok("Destroyed server with handle " + handle + "."));
}).toFuture(); }).toFuture();
} }

View file

@ -1,12 +1,9 @@
package de.kentoj.scrow.bukkit.command.instance; package de.kentoj.scrow.bukkit.command.instance;
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.CommandContext;
import de.kentoj.kencommandapi.api.literal.Literal; import de.kentoj.kencommandapi.api.literal.Literal;
import de.kentoj.scrow.bukkit.ScrowAPI; import de.kentoj.scrow.bukkit.ScrowAPI;
import de.kentoj.scrow.bukkit.scheduler.Tasks; import de.kentoj.scrow.bukkit.scheduler.Tasks;
import de.kentoj.scrowlib.convention.ScrowMessageStyle;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -15,26 +12,23 @@ import java.util.concurrent.CompletableFuture;
public final class InstanceListLiteral { public final class InstanceListLiteral {
private final Literal<CommandSender> literal; private final Literal<CommandSender> literal;
private final ScrowMessageStyle style;
InstanceListLiteral(ScrowMessageStyle style) { InstanceListLiteral() {
this.style = style;
this.literal = Literal.<CommandSender>builder("list") this.literal = Literal.<CommandSender>builder("list")
.withExecutor(this::displayInstanceList) .withExecutor(this::displayInstanceList)
.build(); .build();
} }
private CompletableFuture<Result<Object, String>> displayInstanceList(CommandContext<CommandSender> ctx) { private CompletableFuture<?> displayInstanceList(CommandContext<CommandSender> ctx) {
return Tasks.supplyAsync(() -> return Tasks.supplyAsync(() ->
ScrowAPI.instanceManager().instances()) ScrowAPI.instanceManager().instances())
.<Result<Object, String>>mapSync(instances -> { .thenSync(instances -> {
var msg = Component.text("Running instances:"); var msg = Component.text("Running instances:");
for (var inst : instances) { for (var inst : instances) {
msg = msg.appendNewline() msg = msg.appendNewline()
.append(Component.text(" - " + inst.handle() + " on port " + inst.port())); .append(Component.text(" - " + inst.handle() + " on port " + inst.port()));
} }
ctx.sender().sendMessage(style.ok(msg)); ctx.sender().sendMessage(ctx.style().ok(msg));
return Results.success(new Object());
}).toFuture(); }).toFuture();
} }

View file

@ -19,9 +19,8 @@ public final class LobbyCommand {
.asRootLiteral(ScrowMessageStyle.GENERIC); .asRootLiteral(ScrowMessageStyle.GENERIC);
} }
private Result<Object, String> sendToLobby(CommandContext<Player> ctx) { private void sendToLobby(CommandContext<Player> ctx) {
Bukkit.dispatchCommand(ctx.sender(), "play lobby"); Bukkit.dispatchCommand(ctx.sender(), "play lobby");
return Results.success(new Object());
} }
public RootLiteral<Player> rootLiteral() { public RootLiteral<Player> rootLiteral() {

View file

@ -1,7 +1,5 @@
package de.kentoj.scrow.bukkit.command.instance; package de.kentoj.scrow.bukkit.command.instance;
import com.leakyabstractions.result.api.Result;
import com.leakyabstractions.result.core.Results;
import de.kentoj.kencommandapi.api.argument.CommandArgumentSpec; import de.kentoj.kencommandapi.api.argument.CommandArgumentSpec;
import de.kentoj.kencommandapi.api.argument.types.StringArgumentType; import de.kentoj.kencommandapi.api.argument.types.StringArgumentType;
import de.kentoj.kencommandapi.api.invocation.CommandContext; import de.kentoj.kencommandapi.api.invocation.CommandContext;
@ -12,6 +10,7 @@ import de.kentoj.scrow.bukkit.scheduler.Tasks;
import de.kentoj.scrowlib.convention.ScrowMessageStyle; import de.kentoj.scrowlib.convention.ScrowMessageStyle;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.Objects;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
public final class PlayCommand { public final class PlayCommand {
@ -28,22 +27,25 @@ public final class PlayCommand {
.asRootLiteral(style); .asRootLiteral(style);
} }
private CompletableFuture<Result<Object, String>> execute(CommandContext<Player> ctx) { private CompletableFuture<?> execute(CommandContext<Player> ctx) {
var gamemode = ctx.getArg(gamemodeArg); var gamemode = ctx.getArg(gamemodeArg);
return Tasks.supplyAsync(() -> ScrowAPI.instanceManager().instances()) return Tasks.supplyAsync(() -> ScrowAPI.instanceManager().instances())
.mapAsync(instances -> { .mapSync(instances -> {
var instance = instances.stream() var instance = instances.stream()
.filter(inst -> inst.template().equals(gamemode)) .filter(inst -> inst.template().equals(gamemode))
.findFirst() .findFirst()
.orElse(null); .orElse(null);
if (instance == null) if (instance == null) {
return Results.failure("No instance for " + gamemode + " found."); ctx.sender().sendMessage(ctx.style().err("No instance for " + gamemode + " found."));
return null;
}
return Results.ofCallable(() -> { return instance.handle();
ScrowAPI.getPlayer(ctx.sender()).sendToInstance(instance.handle()); })
return new Object(); .yieldIf(Objects::isNull)
}).mapFailure(Exception::getMessage); .thenAsync(handle ->
}).toFuture(); ScrowAPI.getPlayer(ctx.sender()).sendToInstance(handle)
).toFuture();
} }
public RootLiteral<Player> rootLiteral() { public RootLiteral<Player> rootLiteral() {

2138
maven_install.json Normal file

File diff suppressed because it is too large Load diff