currently refactoring a lot
This commit is contained in:
parent
7fe7409a15
commit
a32805a623
46 changed files with 571 additions and 642 deletions
|
|
@ -22,12 +22,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.21")
|
||||
|
||||
// TODO remove, we use postgres now
|
||||
// https://www.mongodb.com/docs/languages/java/reactive-streams-driver/current/get-started/download-and-install/
|
||||
implementation(platform("org.mongodb:mongodb-driver-bom:5.6.1"))
|
||||
implementation("org.mongodb:mongodb-driver-reactivestreams")
|
||||
implementation("de.kentoj.scrow:kencommandapi-core:0.22")
|
||||
}
|
||||
|
||||
tasks {
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
package de.kentoj.scrow.bukkit;
|
||||
|
||||
import de.kentoj.scrow.bukkit.crown.CrownCommand;
|
||||
import de.kentoj.scrow.bukkit.economy.CoinsCommand;
|
||||
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.region.RegionPlayerTracker;
|
||||
import de.kentoj.scrow.bukkit.region.RegionTask;
|
||||
import de.kentoj.scrow.bukkit.server.LobbyCommand;
|
||||
import de.kentoj.scrow.bukkit.server.PlayCommand;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.io.IOException;
|
||||
|
|
@ -26,8 +26,8 @@ public class CoreImplPlugin extends JavaPlugin {
|
|||
ScrowAPISurface.initScrowAPI(this, ENABLE_DATABASE);
|
||||
|
||||
{
|
||||
ScrowAPI.getCommandApi().register(new FriendCommand().getRootNode());
|
||||
ScrowAPI.getCommandApi().register(new CoinsCommand().getRootNode());
|
||||
ScrowAPI.getCommandApi().register(new FriendCommand().getRootNode());
|
||||
ScrowAPI.getCommandApi().register(new CrownCommand().getRootNode());
|
||||
ScrowAPI.getCommandApi().register(new PlayCommand().getRootNode());
|
||||
ScrowAPI.getCommandApi().register(new LobbyCommand().getRootNode());
|
||||
|
|
|
|||
|
|
@ -27,9 +27,7 @@ import java.io.IOException;
|
|||
public class ScrowAPISurface {
|
||||
|
||||
public static void initScrowAPI(Plugin plugin, boolean enableDatabase) {
|
||||
ScrowAPI.setMinecraftScheduler(Schedulers.fromExecutor(cmd -> {
|
||||
Bukkit.getScheduler().runTask(plugin, cmd);
|
||||
}));
|
||||
ScrowAPI.setCorePlugin(plugin);
|
||||
|
||||
try {
|
||||
String natsHost = EnvUtils.envOrThrow("HOST_NATS");
|
||||
|
|
@ -44,23 +42,23 @@ public class ScrowAPISurface {
|
|||
|
||||
if (enableDatabase) {
|
||||
ConnectionFactory factory = ConnectionFactories.get(EnvUtils.envOrThrow("HOST_POSTGRES"));
|
||||
ScrowAPI.setDbConFactory(new DatabaseConnectionFactoryImpl(factory));
|
||||
ScrowAPI.setJdbi(new DatabaseConnectionFactoryImpl(factory));
|
||||
}
|
||||
|
||||
ScrowAPI.setRegionManager(new RegionManagerImpl());
|
||||
ScrowAPI.setCommandApi(new CommandAPI(plugin));
|
||||
ScrowAPI.setInstanceManager(new InstanceManagerImpl(ScrowAPI.getNats()));
|
||||
ScrowAPI.setEconomyService(ScrowAPI.getDbConFactory() != null ?
|
||||
new PostgresEconomyService(ScrowAPI.getDbConFactory()) : new InMemoryEconomyService());
|
||||
ScrowAPI.setFriendRequestService(ScrowAPI.getDbConFactory() != null ?
|
||||
new PostgresFriendRequestService(ScrowAPI.getDbConFactory()) : new InMemoryFriendRequestService());
|
||||
ScrowAPI.setFriendshipService(ScrowAPI.getDbConFactory() != null ?
|
||||
new PostgresFriendshipService(ScrowAPI.getDbConFactory()) : new InMemoryFriendshipService());
|
||||
ScrowAPI.setEconomyService(ScrowAPI.getJdbi() != null ?
|
||||
new PostgresEconomyService(ScrowAPI.getJdbi()) : new InMemoryEconomyService());
|
||||
ScrowAPI.setFriendRequestService(ScrowAPI.getJdbi() != null ?
|
||||
new PostgresFriendRequestService(ScrowAPI.getJdbi()) : new InMemoryFriendRequestService());
|
||||
ScrowAPI.setFriendshipService(ScrowAPI.getJdbi() != null ?
|
||||
new PostgresFriendshipService(ScrowAPI.getJdbi()) : new InMemoryFriendshipService());
|
||||
}
|
||||
|
||||
public static void destroyScrowAPI() {
|
||||
try {
|
||||
ScrowAPI.getDbConFactory().close();
|
||||
ScrowAPI.getJdbi().close();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ public class CrownDeployServerLiteral implements CommandExecutor<CommandSender>
|
|||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Result<Void,String>> execute(CommandContext<CommandSender> ctx) {
|
||||
public CompletableFuture<Result<Object,String>> execute(CommandContext<CommandSender> ctx) {
|
||||
var template = ctx.getArg(templateArg);
|
||||
return ScrowAPI.getInstanceManager().deployInstance(template)
|
||||
.map(server -> {
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ public class CrownDestroyServerLiteral implements CommandExecutor<CommandSender>
|
|||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Result<Void,String>> execute(CommandContext<CommandSender> ctx) {
|
||||
public CompletableFuture<Result<Object,String>> execute(CommandContext<CommandSender> ctx) {
|
||||
var handle = ctx.getArg(handleArg);
|
||||
return ScrowAPI.getInstanceManager().destroyInstance(handle)
|
||||
.map(__ -> {
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ public class CrownListServersLiteral implements CommandExecutor<CommandSender> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Result<Void,String>> execute(CommandContext<CommandSender> ctx) {
|
||||
public CompletableFuture<Result<Object,String>> execute(CommandContext<CommandSender> ctx) {
|
||||
return ScrowAPI.getInstanceManager().getInstances()
|
||||
.collectList()
|
||||
.map(list -> style.list(Component.text("Running instances:"),
|
||||
|
|
|
|||
|
|
@ -1,78 +0,0 @@
|
|||
package de.kentoj.scrow.bukkit.economy;
|
||||
|
||||
import com.leakyabstractions.result.api.Result;
|
||||
import com.leakyabstractions.result.core.Results;
|
||||
import de.kentoj.kencommandapi.api.node.CommandNode;
|
||||
import de.kentoj.kencommandapi.api.argument.CommandArgument;
|
||||
import de.kentoj.kencommandapi.api.argument.types.IntegerArgumentType;
|
||||
import de.kentoj.kencommandapi.api.invocation.CommandContext;
|
||||
import com.leakyabstractions.result.api.Result;
|
||||
import com.leakyabstractions.result.api.Results;
|
||||
import de.kentoj.kencommandapi.type.OfflinePlayerArgumentType;
|
||||
import de.kentoj.scrow.bukkit.ScrowAPI;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import reactor.core.scheduler.Schedulers;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class CoinsCommand {
|
||||
|
||||
@Getter
|
||||
private final CommandNode<CommandSender> rootNode;
|
||||
private final CommandArgument<CommandSender, OfflinePlayer> playerArg;
|
||||
private final CommandArgument<CommandSender, Integer> amountArg;
|
||||
|
||||
public CoinsCommand() {
|
||||
this.rootNode = CommandNode.node("coins", "eco");
|
||||
this.playerArg = CommandArgument.arg("player", OfflinePlayerArgumentType.getInstance());
|
||||
this.amountArg = CommandArgument.arg("amount", new IntegerArgumentType<>());
|
||||
|
||||
{
|
||||
CommandNode<CommandSender> setLiteral = CommandNode.node("set");
|
||||
rootNode.addLiteral(setLiteral);
|
||||
setLiteral.addArgument(playerArg);
|
||||
setLiteral.addArgument(amountArg);
|
||||
setLiteral.setExecutor(this::setCoins);
|
||||
}
|
||||
{
|
||||
CommandNode<CommandSender> getLiteral = CommandNode.node("get");
|
||||
rootNode.addLiteral(getLiteral);
|
||||
getLiteral.addArgument(playerArg);
|
||||
getLiteral.setExecutor(this::getCoins);
|
||||
}
|
||||
}
|
||||
|
||||
private CompletableFuture<Result<Void,String>> getCoins(CommandContext<CommandSender> ctx) {
|
||||
var player = ctx.getArg(playerArg);
|
||||
return ScrowAPI.getEconomyService()
|
||||
.getCoins(player.getUniqueId())
|
||||
.subscribeOn(Schedulers.boundedElastic())
|
||||
.publishOn(ScrowAPI.getMinecraftScheduler())
|
||||
.map(amount -> {
|
||||
if (player == ctx.getSender()) {
|
||||
ctx.getSender().sendMessage("You have " + amount + "$");
|
||||
} else {
|
||||
ctx.getSender().sendMessage(player.getName() + " has " + amount + "$");
|
||||
}
|
||||
return Result.success();
|
||||
}).toFuture();
|
||||
}
|
||||
|
||||
private CompletableFuture<Result<Void,String>> setCoins(CommandContext<CommandSender> ctx) {
|
||||
var player = ctx.getArg(playerArg);
|
||||
var amount = ctx.getArg(amountArg);
|
||||
|
||||
return ScrowAPI.getEconomyService()
|
||||
.setCoins(player.getUniqueId(), amount)
|
||||
.subscribeOn(Schedulers.boundedElastic())
|
||||
.publishOn(ScrowAPI.getMinecraftScheduler())
|
||||
.map(__ -> {
|
||||
ctx.getSender().sendMessage(player.getName() + " now has " + amount + "$");
|
||||
return Results.success(null);
|
||||
}).toFuture();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +1,7 @@
|
|||
package de.kentoj.scrow.bukkit.economy;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import de.kentoj.scrow.bukkit.EconomyService;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import reactor.core.publisher.Mono;
|
||||
import de.kentoj.scrow.bukkit.misc.EconomyService;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
|
@ -14,34 +12,29 @@ public class InMemoryEconomyService implements EconomyService {
|
|||
private final Map<UUID, Integer> coins = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public Mono<@NotNull Integer> getCoins(UUID playerId) {
|
||||
return Mono.fromSupplier(() -> coins.getOrDefault(playerId, 0));
|
||||
public int getCoins(UUID playerId) {
|
||||
return coins.getOrDefault(playerId, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<@NotNull Void> setCoins(UUID playerId, int amount) {
|
||||
public void setCoins(UUID playerId, int amount) {
|
||||
Preconditions.checkArgument(amount >= 0, "amount can not be negative");
|
||||
return Mono.fromSupplier(() -> coins.put(playerId, amount)).then();
|
||||
coins.put(playerId, amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<@NotNull Void> depositCoins(UUID playerId, int amount) {
|
||||
public void depositCoins(UUID playerId, int amount) {
|
||||
Preconditions.checkArgument(amount >= 0, "amount can not be negative");
|
||||
return Mono.fromRunnable(() -> {
|
||||
var cur = coins.getOrDefault(playerId, amount);
|
||||
coins.put(playerId, cur + amount);
|
||||
});
|
||||
var cur = coins.getOrDefault(playerId, 0);
|
||||
coins.put(playerId, cur + amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<@NotNull Boolean> tryWithdrawCoins(UUID playerId, int amount) {
|
||||
public boolean tryWithdrawCoins(UUID playerId, int amount) {
|
||||
Preconditions.checkArgument(amount >= 0, "amount can not be negative");
|
||||
return Mono.fromSupplier(() -> {
|
||||
var cur = coins.getOrDefault(playerId, 0);
|
||||
if (cur < amount) return false;
|
||||
|
||||
coins.put(playerId, cur - amount);
|
||||
return true;
|
||||
});
|
||||
var cur = coins.getOrDefault(playerId, 0);
|
||||
if (cur < amount) return false;
|
||||
coins.put(playerId, cur - amount);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,74 +0,0 @@
|
|||
package de.kentoj.scrow.bukkit.economy;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.mongodb.client.model.Filters;
|
||||
import com.mongodb.client.model.UpdateOptions;
|
||||
import com.mongodb.client.model.Updates;
|
||||
import com.mongodb.reactivestreams.client.MongoCollection;
|
||||
import com.mongodb.reactivestreams.client.MongoDatabase;
|
||||
import de.kentoj.scrow.bukkit.EconomyService;
|
||||
import org.bson.Document;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
// TODO log
|
||||
public class MongoEconomyService implements EconomyService {
|
||||
|
||||
private static final String COLLECTION_NAME = "economy";
|
||||
private final @NotNull MongoDatabase database;
|
||||
|
||||
public MongoEconomyService(MongoDatabase database) {
|
||||
this.database = database;
|
||||
Mono.from(database.createCollection(COLLECTION_NAME)).block();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<@NotNull Integer> getCoins(UUID playerId) {
|
||||
return Mono.from(
|
||||
getCollection().find(Filters.eq("_id", playerId)).first()
|
||||
).map(result -> result.getInteger("coins")).defaultIfEmpty(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<@NotNull Void> setCoins(UUID playerId, int amount) {
|
||||
Preconditions.checkArgument(amount >= 0, "amount can not be negative");
|
||||
|
||||
return Mono.from(
|
||||
getCollection().updateOne(
|
||||
Filters.eq("_id", playerId),
|
||||
Updates.set("coins", amount),
|
||||
new UpdateOptions().upsert(true)
|
||||
)
|
||||
).then();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<@NotNull Void> depositCoins(UUID playerId, int amount) {
|
||||
Preconditions.checkArgument(amount >= 0, "amount can not be negative");
|
||||
|
||||
return Mono.from(getCollection().updateOne(
|
||||
Filters.eq("_id", playerId),
|
||||
Updates.inc("coins", amount),
|
||||
new UpdateOptions().upsert(true)
|
||||
)).then();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<@NotNull Boolean> tryWithdrawCoins(UUID playerId, int amount) {
|
||||
Preconditions.checkArgument(amount >= 0, "amount can not be negative");
|
||||
|
||||
return Mono.from(getCollection().updateOne(
|
||||
Filters.and(
|
||||
Filters.eq("_id", playerId),
|
||||
Filters.gte("coins", amount)
|
||||
),
|
||||
Updates.inc("coins", -1 * amount)
|
||||
)).map(result -> result.getModifiedCount() > 0);
|
||||
}
|
||||
|
||||
private MongoCollection<Document> getCollection() {
|
||||
return database.getCollection(COLLECTION_NAME);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,46 +1,46 @@
|
|||
package de.kentoj.scrow.bukkit.economy;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import de.kentoj.scrow.bukkit.EconomyService;
|
||||
import de.kentoj.scrowlib.connection.DatabaseConnectionFactory;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import reactor.core.publisher.Mono;
|
||||
import de.kentoj.scrow.bukkit.ScrowAPI;
|
||||
import de.kentoj.scrow.bukkit.misc.EconomyService;
|
||||
import org.jdbi.v3.core.Jdbi;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
// TODO log operations to separate table
|
||||
public class PostgresEconomyService implements EconomyService {
|
||||
|
||||
private final DatabaseConnectionFactory conFactory;
|
||||
private final Jdbi jdbi;
|
||||
|
||||
public PostgresEconomyService(DatabaseConnectionFactory conFactory) {
|
||||
this.conFactory = conFactory;
|
||||
conFactory.create().sql("""
|
||||
public PostgresEconomyService() {
|
||||
checkNotNull(ScrowAPI.getJdbi());
|
||||
this.jdbi = ScrowAPI.getJdbi();
|
||||
jdbi.withHandle(h -> h.execute("""
|
||||
CREATE TABLE IF NOT EXISTS economy (
|
||||
playerId UUID NOT NULL,
|
||||
balance INTEGER NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY(playerId)
|
||||
)
|
||||
""").then().block();
|
||||
"""));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<@NotNull Integer> getCoins(UUID playerId) {
|
||||
return conFactory.create()
|
||||
.sql("""
|
||||
SELECT balance
|
||||
FROM economy
|
||||
WHERE playerId = :playerId
|
||||
""")
|
||||
public int getCoins(UUID playerId) {
|
||||
return jdbi.withHandle(h -> h
|
||||
.createQuery("SELECT balance FROM economy WHERE playerId = :playerId")
|
||||
.bind("playerId", playerId)
|
||||
.map(row -> row.get("balance", Integer.class))
|
||||
.one();
|
||||
.map(row -> row.getColumn("balance", Integer.class))
|
||||
.findOne()
|
||||
.orElse(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<@NotNull Void> setCoins(UUID playerId, int amount) {
|
||||
Preconditions.checkArgument(amount >= 0, "amount can not be negative");
|
||||
return conFactory.create().sql("""
|
||||
public void setCoins(UUID playerId, int amount) {
|
||||
checkArgument(amount >= 0, "amount cannot be negative");
|
||||
jdbi.withHandle(h -> h
|
||||
.createUpdate("""
|
||||
INSERT INTO economy (playerId, balance)
|
||||
VALUES (:playerId, :amount)
|
||||
ON CONFLICT (playerId)
|
||||
|
|
@ -50,13 +50,14 @@ public class PostgresEconomyService implements EconomyService {
|
|||
""")
|
||||
.bind("playerId", playerId)
|
||||
.bind("amount", amount)
|
||||
.then();
|
||||
.execute());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<@NotNull Void> depositCoins(UUID playerId, int amount) {
|
||||
Preconditions.checkArgument(amount >= 0, "amount can not be negative");
|
||||
return conFactory.create().sql("""
|
||||
public void depositCoins(UUID playerId, int amount) {
|
||||
checkArgument(amount >= 0, "amount cannot be negative");
|
||||
jdbi.withHandle(h -> h.
|
||||
createUpdate("""
|
||||
INSERT INTO economy (playerId, balance)
|
||||
VALUES (:playerId, :amount)
|
||||
ON CONFLICT (playerId)
|
||||
|
|
@ -66,21 +67,20 @@ public class PostgresEconomyService implements EconomyService {
|
|||
""")
|
||||
.bind("playerId", playerId)
|
||||
.bind("amount", amount)
|
||||
.then();
|
||||
.execute());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<@NotNull Boolean> tryWithdrawCoins(UUID playerId, int amount) {
|
||||
Preconditions.checkArgument(amount >= 0, "amount can not be negative");
|
||||
return conFactory.create().sql("""
|
||||
public boolean tryWithdrawCoins(UUID playerId, int amount) {
|
||||
checkArgument(amount >= 0, "amount cannot be negative");
|
||||
return jdbi.withHandle(h -> h
|
||||
.createUpdate("""
|
||||
UPDATE economy
|
||||
SET balance = balance - :amount
|
||||
WHERE playerId = :playerId
|
||||
""")
|
||||
.bind("playerId", playerId)
|
||||
.bind("amount", amount)
|
||||
.fetch()
|
||||
.rowsUpdated()
|
||||
.map(updated -> updated > 0);
|
||||
.execute() > 0);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,56 @@
|
|||
package de.kentoj.scrow.bukkit.economy.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.kencommandapi.api.node.RootCommandNode;
|
||||
import de.kentoj.kencommandapi.api.platform.MessageStyle;
|
||||
import de.kentoj.scrow.bukkit.ScrowAPI;
|
||||
import de.kentoj.scrow.bukkit.ScrowAPISurface;
|
||||
import de.kentoj.scrow.bukkit.scheduler.Tasks;
|
||||
import de.kentoj.scrowlib.convention.ScrowMessageStyle;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@NoArgsConstructor(access = AccessLevel.NONE)
|
||||
public class CoinsCommand implements CommandExecutor<CommandSender> {
|
||||
@Getter
|
||||
private final RootCommandNode<CommandSender> rootNode;
|
||||
private final MessageStyle style;
|
||||
|
||||
public CoinsCommand() {
|
||||
style = new ScrowMessageStyle("Coins", NamedTextColor.GOLD);
|
||||
rootNode = CommandNode.rootNode(style, "coins", "bal", "balance");
|
||||
rootNode.setPermission("command.coins.get.self");
|
||||
|
||||
var setLiteral = new CoinsSetLiteral(style).getLiteral();
|
||||
setLiteral.setPermission("command.coins.set");
|
||||
rootNode.addLiteral(setLiteral);
|
||||
|
||||
var getLiteral = new CoinsGetLiteral(style).getLiteral();
|
||||
getLiteral.setPermission("command.coins.get.others");
|
||||
rootNode.addLiteral(getLiteral);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Result<Object, String>> execute(CommandContext<CommandSender> ctx) {
|
||||
var player = ((Player) ctx.getSender());
|
||||
return Tasks.supplyAsync(() ->
|
||||
ScrowAPI.getEconomyService().getCoins(player.getUniqueId()))
|
||||
.<Result<Object, String>>mapSync(amount -> {
|
||||
player.sendMessage(style.ok("You have " + amount + "$"));
|
||||
return Results.success(Optional.empty());
|
||||
}).asFuture();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
package de.kentoj.scrow.bukkit.economy.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.invocation.CommandContext;
|
||||
import de.kentoj.kencommandapi.api.invocation.CommandExecutor;
|
||||
import de.kentoj.kencommandapi.api.node.CommandNode;
|
||||
import de.kentoj.kencommandapi.api.platform.MessageStyle;
|
||||
import de.kentoj.kencommandapi.type.OfflinePlayerArgumentType;
|
||||
import de.kentoj.scrow.bukkit.ScrowAPI;
|
||||
import de.kentoj.scrow.bukkit.scheduler.Tasks;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class CoinsGetLiteral implements CommandExecutor<CommandSender> {
|
||||
|
||||
@Getter
|
||||
private final CommandNode<CommandSender> literal;
|
||||
|
||||
private final MessageStyle style;
|
||||
private final CommandArgument<CommandSender, OfflinePlayer> playerArg;
|
||||
|
||||
public CoinsGetLiteral(MessageStyle style) {
|
||||
this.style = style;
|
||||
|
||||
playerArg = CommandArgument.arg("player", OfflinePlayerArgumentType.getInstance());
|
||||
playerArg.setDefaultValueProvider(sender -> (OfflinePlayer) sender);
|
||||
|
||||
literal = CommandNode.node("set");
|
||||
literal.addArgument(playerArg);
|
||||
literal.setExecutor(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Result<Object, String>> execute(CommandContext<CommandSender> ctx) {
|
||||
var player = ctx.getArg(playerArg);
|
||||
return Tasks.supplyAsync(() ->
|
||||
ScrowAPI.getEconomyService().getCoins(player.getUniqueId()))
|
||||
.<Result<Object, String>>mapSync(amount -> {
|
||||
ctx.getSender().sendMessage(style.ok(player.getName() + " has " + amount + "$"));
|
||||
return Results.success(Optional.empty());
|
||||
}).asFuture();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
package de.kentoj.scrow.bukkit.economy.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.IntegerArgumentType;
|
||||
import de.kentoj.kencommandapi.api.invocation.CommandContext;
|
||||
import de.kentoj.kencommandapi.api.invocation.CommandExecutor;
|
||||
import de.kentoj.kencommandapi.api.node.CommandNode;
|
||||
import de.kentoj.kencommandapi.api.platform.MessageStyle;
|
||||
import de.kentoj.kencommandapi.type.OfflinePlayerArgumentType;
|
||||
import de.kentoj.scrow.bukkit.ScrowAPI;
|
||||
import de.kentoj.scrow.bukkit.scheduler.Tasks;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class CoinsSetLiteral implements CommandExecutor<CommandSender> {
|
||||
|
||||
@Getter
|
||||
private final CommandNode<CommandSender> literal;
|
||||
|
||||
private final MessageStyle style;
|
||||
private final CommandArgument<CommandSender, OfflinePlayer> playerArg;
|
||||
private final CommandArgument<CommandSender, Integer> amountArg;
|
||||
|
||||
public CoinsSetLiteral(MessageStyle style) {
|
||||
this.style = style;
|
||||
|
||||
playerArg = CommandArgument.arg("player", OfflinePlayerArgumentType.getInstance());
|
||||
amountArg = CommandArgument.arg("amount", new IntegerArgumentType<>());
|
||||
|
||||
literal = CommandNode.node("set");
|
||||
literal.addArgument(playerArg);
|
||||
literal.addArgument(amountArg);
|
||||
literal.setExecutor(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Result<Object, String>> execute(CommandContext<CommandSender> ctx) {
|
||||
var player = ctx.getArg(playerArg);
|
||||
var amount = ctx.getArg(amountArg);
|
||||
return Tasks.runAsync(() ->
|
||||
ScrowAPI.getEconomyService().setCoins(player.getUniqueId(), amount))
|
||||
.<Result<Object, String>>supplySync(() -> {
|
||||
ctx.getSender().sendMessage(style.ok(player.getName() + " now has " + amount + "$"));
|
||||
return Results.success(Optional.empty());
|
||||
}).asFuture();
|
||||
}
|
||||
}
|
||||
|
|
@ -36,7 +36,7 @@ public class FriendAddLiteral implements CommandExecutor<CommandSender> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Result<Void,String>> execute(CommandContext<CommandSender> ctx) {
|
||||
public CompletableFuture<Result<Object,String>> execute(CommandContext<CommandSender> ctx) {
|
||||
var self = (Player) ctx.getSender();
|
||||
var other = ctx.getArg(playerArg);
|
||||
return findAction(self, other)
|
||||
|
|
|
|||
|
|
@ -3,20 +3,16 @@ package de.kentoj.scrow.bukkit.friends.command;
|
|||
import de.kentoj.kencommandapi.api.node.CommandNode;
|
||||
import de.kentoj.kencommandapi.api.node.RootCommandNode;
|
||||
import de.kentoj.scrowlib.convention.ScrowMessageStyle;
|
||||
import lombok.Getter;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
@NoArgsConstructor(access = AccessLevel.NONE)
|
||||
public class FriendCommand {
|
||||
|
||||
@Getter
|
||||
private final RootCommandNode<CommandSender> rootNode;
|
||||
|
||||
public FriendCommand() {
|
||||
var style = new ScrowMessageStyle(Component.text("Friends")
|
||||
.color(NamedTextColor.GREEN));
|
||||
this.rootNode = CommandNode.rootNode(style, "f", "friend");
|
||||
public static RootCommandNode<CommandSender> create() {
|
||||
var style = new ScrowMessageStyle("Friends", NamedTextColor.GREEN);
|
||||
var rootNode = CommandNode.rootNode(style, "f", "friend");
|
||||
rootNode.addLiteral(new FriendListLiteral(style).getRootNode());
|
||||
rootNode.addLiteral(new FriendAddLiteral(style).getRootNode());
|
||||
rootNode.addLiteral(new FriendRemoveLiteral(style).getRootNode());
|
||||
|
|
|
|||
|
|
@ -1,12 +1,15 @@
|
|||
package de.kentoj.scrow.bukkit.friends.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 com.leakyabstractions.result.api.Result;
|
||||
import com.leakyabstractions.result.api.Results;
|
||||
import de.kentoj.kencommandapi.api.node.CommandNode;
|
||||
import de.kentoj.kencommandapi.api.platform.MessageStyle;
|
||||
import de.kentoj.scrow.bukkit.ScrowAPI;
|
||||
import lombok.Getter;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
|
@ -18,34 +21,42 @@ public class FriendListLiteral implements CommandExecutor<CommandSender> {
|
|||
|
||||
@Getter
|
||||
private final CommandNode<CommandSender> rootNode;
|
||||
private final MessageStyle style;
|
||||
|
||||
public FriendListLiteral() {
|
||||
public FriendListLiteral(MessageStyle style) {
|
||||
this.style = style;
|
||||
this.rootNode = CommandNode.node("list");
|
||||
rootNode.setExecutor(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Result<Void,String>> execute(CommandContext<CommandSender> ctx) {
|
||||
public CompletableFuture<Result<Object, String>> execute(CommandContext<CommandSender> ctx) {
|
||||
var sender = (Player) ctx.getSender();
|
||||
var ownUid = sender.getUniqueId();
|
||||
return ScrowAPI.getFriendshipService().getFriendships(ownUid)
|
||||
.map(friendship -> Bukkit.getOfflinePlayer(friendship.getUuids().getOther(ownUid)))
|
||||
.sort(this::compareByOnlineStatus)
|
||||
.collectList()
|
||||
.map(list -> {
|
||||
if (list.isEmpty()) return Result.error("You have no friends. Use /friend add <player>");
|
||||
return CompletableFuture.supplyAsync(() ->
|
||||
ScrowAPI.getFriendshipService().getFriendships(ownUid))
|
||||
.thenApply(friendships -> ScrowAPI.getScheduler().sync(() -> {
|
||||
var list = friendships.stream()
|
||||
.map(friendship -> Bukkit.getOfflinePlayer(friendship.getUuids().getOther(ownUid)))
|
||||
.sorted(this::compareByOnlineStatus)
|
||||
.toList();
|
||||
if (list.isEmpty()) return Results.failure("You have no friends. Use /friend add <player>");
|
||||
|
||||
var msg = "§3§lFriends§r§7 ☆ You have §3" + list.size() + "§7 friend";
|
||||
if (list.size() > 1) msg += "s";
|
||||
msg += ":§r\n";
|
||||
var message = "§7You have §3" + list.size() + "§7" + ("§" +
|
||||
.append(Component.text(list.size() == 1 ? " friend:" : " friends:"));
|
||||
for (var friend : list) {
|
||||
var status = friend.isOnline() ? "(§aonline§7)" : "(offline)";
|
||||
msg += "§c≫ §7" + friend.getName() + " " + status + "\n";
|
||||
message = message.appendNewline();
|
||||
var status = Component.text("(").append(
|
||||
friend.isOnline()
|
||||
? Component.text("online").color(NamedTextColor.GRAY)
|
||||
: Component.text("offline").color(NamedTextColor.RED))
|
||||
.append(Component.text(")"));
|
||||
message = message.append(Component.text("≫").color(NamedTextColor.AQUA));
|
||||
}
|
||||
|
||||
sender.sendMessage(msg);
|
||||
return Result.success();
|
||||
}).toFuture();
|
||||
});
|
||||
}
|
||||
|
||||
private int compareByOnlineStatus(OfflinePlayer p1, OfflinePlayer p2) {
|
||||
|
|
|
|||
|
|
@ -1,18 +1,20 @@
|
|||
package de.kentoj.scrow.bukkit.friends.command;
|
||||
|
||||
import de.kentoj.kencommandapi.api.node.CommandNode;
|
||||
import com.leakyabstractions.result.api.Result;
|
||||
import com.leakyabstractions.result.core.Results;
|
||||
import de.kentoj.kencommandapi.api.argument.CommandArgument;
|
||||
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.kencommandapi.api.node.CommandNode;
|
||||
import de.kentoj.kencommandapi.type.OfflinePlayerArgumentType;
|
||||
import de.kentoj.scrow.bukkit.ScrowAPI;
|
||||
import de.kentoj.scrow.bukkit.scheduler.Tasks;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class FriendRemoveLiteral implements CommandExecutor<CommandSender> {
|
||||
|
|
@ -20,6 +22,8 @@ public class FriendRemoveLiteral implements CommandExecutor<CommandSender> {
|
|||
private final CommandNode<CommandSender> rootNode;
|
||||
private final CommandArgument<CommandSender, OfflinePlayer> playerArg;
|
||||
|
||||
private final Scheduler scheduler = ScrowAPI.getScheduler();
|
||||
|
||||
public FriendRemoveLiteral() {
|
||||
this.playerArg = CommandArgument.arg("player", OfflinePlayerArgumentType.getInstance());
|
||||
this.rootNode = CommandNode.node("remove");
|
||||
|
|
@ -28,15 +32,16 @@ public class FriendRemoveLiteral implements CommandExecutor<CommandSender> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Result<Void,String>> execute(CommandContext<CommandSender> ctx) {
|
||||
public CompletableFuture<Result<Object, String>> execute(CommandContext<CommandSender> ctx) {
|
||||
var friend = ctx.getArg(playerArg);
|
||||
var player = (Player) ctx.getSender();
|
||||
return ScrowAPI.getFriendshipService().deleteFriendship(friend.getUniqueId(), player.getUniqueId())
|
||||
.map(wasAdded -> wasAdded
|
||||
? Result.success() : Result.error("You are not friends with " + friend.getName())
|
||||
).doOnNext(success -> {
|
||||
if (success.isSuccess())
|
||||
ctx.getSender().sendMessage("You are no longer friends with " + friend.getName());
|
||||
}).toFuture();
|
||||
return Tasks.supplyAsync(() ->
|
||||
ScrowAPI.getFriendshipService().deleteFriendship(friend.getUniqueId(), player.getUniqueId()))
|
||||
.<Result<Object, String>>mapSync(deleted -> {
|
||||
if (!deleted)
|
||||
return Results.failure("You are not friends with " + friend.getName());
|
||||
ctx.getSender().sendMessage("You have ended the friendship with " + friend.getName());
|
||||
return Results.success(Optional.empty());
|
||||
}).asFuture();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ public class FriendRequestsLiteral implements CommandExecutor<CommandSender> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Result<Void,String>> execute(CommandContext<CommandSender> ctx) {
|
||||
public CompletableFuture<Result<Object,String>> execute(CommandContext<CommandSender> ctx) {
|
||||
var sender = (Player) ctx.getSender();
|
||||
return ScrowAPI.getFriendRequestService().getFriendRequestsTo(sender.getUniqueId())
|
||||
.collectList()
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
package de.kentoj.scrow.bukkit.friends.friendship;
|
||||
|
||||
import com.leakyabstractions.result.api.Result;
|
||||
import com.leakyabstractions.result.core.Results;
|
||||
import de.kentoj.scrow.bukkit.friends.Friendship;
|
||||
import de.kentoj.scrow.bukkit.friends.FriendshipService;
|
||||
import de.kentoj.scrow.bukkit.friends.OrderedUUIDPair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
@ -16,24 +16,27 @@ public class InMemoryFriendshipService implements FriendshipService {
|
|||
private final Map<OrderedUUIDPair, Friendship> friendships = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public Mono<@NotNull Friendship> getFriendship(UUID uuid1, UUID uuid2) {
|
||||
return Mono.justOrEmpty(friendships.get(new OrderedUUIDPair(uuid1, uuid2)));
|
||||
public Result<Friendship, String> getFriendship(UUID uuid1, UUID uuid2) {
|
||||
return Results.success(friendships.get(new OrderedUUIDPair(uuid1, uuid2)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<@NotNull Friendship> getFriendships(UUID playerId) {
|
||||
return Flux.fromStream(friendships.keySet().stream()
|
||||
.filter(pair -> pair.getFirst().equals(playerId) || pair.getSecond().equals(playerId))
|
||||
.map(friendships::get));
|
||||
public Result<List<Friendship>, String> getFriendships(UUID playerId) {
|
||||
return Results.success(friendships.entrySet().stream()
|
||||
.filter(ent ->
|
||||
ent.getKey().getFirst().equals(playerId) || ent.getKey().getSecond().equals(playerId)
|
||||
)
|
||||
.map(Map.Entry::getValue)
|
||||
.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<@NotNull Boolean> saveFriendship(Friendship friendship) {
|
||||
return Mono.just(friendships.putIfAbsent(friendship.getUuids(), friendship) == null);
|
||||
public Result<Boolean, String> saveFriendship(Friendship friendship) {
|
||||
return Results.success(friendships.putIfAbsent(friendship.getUuids(), friendship) == null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<@NotNull Boolean> deleteFriendship(UUID uuid1, UUID uuid2) {
|
||||
return Mono.just(friendships.remove(new OrderedUUIDPair(uuid1, uuid2)) != null);
|
||||
public Result<Boolean, String> deleteFriendship(UUID uuid1, UUID uuid2) {
|
||||
return Results.success(friendships.remove(new OrderedUUIDPair(uuid1, uuid2)) != null);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,103 +0,0 @@
|
|||
package de.kentoj.scrow.bukkit.friends.friendship;
|
||||
|
||||
import com.mongodb.ErrorCategory;
|
||||
import com.mongodb.MongoWriteException;
|
||||
import com.mongodb.client.model.Filters;
|
||||
import com.mongodb.client.model.IndexOptions;
|
||||
import com.mongodb.client.model.Indexes;
|
||||
import com.mongodb.reactivestreams.client.MongoCollection;
|
||||
import com.mongodb.reactivestreams.client.MongoDatabase;
|
||||
import de.kentoj.scrow.bukkit.friends.Friendship;
|
||||
import de.kentoj.scrow.bukkit.friends.FriendshipService;
|
||||
import de.kentoj.scrow.bukkit.friends.OrderedUUIDPair;
|
||||
import org.bson.Document;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.sql.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
public class MongoFriendshipService implements FriendshipService {
|
||||
|
||||
private static final String COLLECTION_NAME = "friendships";
|
||||
|
||||
private final MongoDatabase database;
|
||||
|
||||
public MongoFriendshipService(MongoDatabase database) {
|
||||
this.database = database;
|
||||
|
||||
Mono.when(
|
||||
database.createCollection(COLLECTION_NAME),
|
||||
collection().createIndex(
|
||||
Indexes.compoundIndex(
|
||||
Indexes.ascending("first"),
|
||||
Indexes.ascending("second")
|
||||
),
|
||||
new IndexOptions().unique(true))
|
||||
).block();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<@NotNull Friendship> getFriendship(UUID uuid1, UUID uuid2) {
|
||||
var uuids = new OrderedUUIDPair(uuid1, uuid2);
|
||||
return Mono.from(collection()
|
||||
.find(Filters.and(
|
||||
Filters.eq("first", uuids.getFirst()),
|
||||
Filters.eq("second", uuids.getSecond())
|
||||
)))
|
||||
.map(this::fromDocument);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<@NotNull Friendship> getFriendships(UUID playerId) {
|
||||
return Flux.from(collection()
|
||||
.find(Filters.or(
|
||||
Filters.eq("first", playerId),
|
||||
Filters.eq("second", playerId)
|
||||
)))
|
||||
.map(this::fromDocument);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<@NotNull Boolean> saveFriendship(Friendship friendship) {
|
||||
return Mono.from(collection()
|
||||
.insertOne(toDocument(friendship)))
|
||||
.thenReturn(true)
|
||||
.onErrorResume(MongoWriteException.class, e ->
|
||||
e.getError().getCategory() == ErrorCategory.DUPLICATE_KEY
|
||||
? Mono.just(Boolean.FALSE)
|
||||
: Mono.error(e)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<@NotNull Boolean> deleteFriendship(UUID uuid1, UUID uuid2) {
|
||||
var uuids = new OrderedUUIDPair(uuid1, uuid2);
|
||||
return Mono.from(collection()
|
||||
.deleteOne(Filters.and(
|
||||
Filters.eq("first", uuids.getFirst()),
|
||||
Filters.eq("second", uuids.getSecond())
|
||||
)))
|
||||
.map(res -> res.getDeletedCount() > 0);
|
||||
}
|
||||
|
||||
private MongoCollection<Document> collection() {
|
||||
return database.getCollection(COLLECTION_NAME);
|
||||
}
|
||||
|
||||
private Friendship fromDocument(Document doc) {
|
||||
return new FriendshipImpl(
|
||||
doc.get("first", UUID.class),
|
||||
doc.get("second", UUID.class),
|
||||
doc.getDate("createdAt").toInstant()
|
||||
);
|
||||
}
|
||||
|
||||
private Document toDocument(Friendship friendship) {
|
||||
return new Document()
|
||||
.append("first", friendship.getUuids().getFirst())
|
||||
.append("second", friendship.getUuids().getSecond())
|
||||
.append("createdAt", Date.from(friendship.getCreatedAt()));
|
||||
}
|
||||
}
|
||||
|
|
@ -30,7 +30,7 @@ public class PostgresFriendshipService implements FriendshipService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Mono<@NotNull Friendship> getFriendship(UUID uuid1, UUID uuid2) {
|
||||
public Result<Friendship, String> getFriendship(UUID uuid1, UUID uuid2) {
|
||||
var uuids = new OrderedUUIDPair(uuid1, uuid2);
|
||||
|
||||
return dbConFactory.create().sql("""
|
||||
|
|
@ -49,7 +49,7 @@ public class PostgresFriendshipService implements FriendshipService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Flux<@NotNull Friendship> getFriendships(UUID playerId) {
|
||||
public Result<List<Friendship>, String> getFriendships(UUID playerId) {
|
||||
return dbConFactory.create().sql("""
|
||||
SELECT first_uuid, second_uuid, created_at
|
||||
FROM friendships
|
||||
|
|
@ -65,7 +65,7 @@ public class PostgresFriendshipService implements FriendshipService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Mono<@NotNull Boolean> saveFriendship(Friendship friendship) {
|
||||
public Result<Boolean, String> saveFriendship(Friendship friendship) {
|
||||
return dbConFactory.create().sql("""
|
||||
INSERT INTO friendships (first_uuid, second_uuid, created_at)
|
||||
VALUES (:first, :second, :createdAt)
|
||||
|
|
@ -80,7 +80,7 @@ public class PostgresFriendshipService implements FriendshipService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Mono<@NotNull Boolean> deleteFriendship(UUID uuid1, UUID uuid2) {
|
||||
public Result<Boolean, String> deleteFriendship(UUID uuid1, UUID uuid2) {
|
||||
var uuids = new OrderedUUIDPair(uuid1, uuid2);
|
||||
|
||||
return dbConFactory.create().sql("""
|
||||
|
|
|
|||
|
|
@ -2,11 +2,9 @@ package de.kentoj.scrow.bukkit.friends.request;
|
|||
|
||||
import de.kentoj.scrow.bukkit.friends.FriendRequest;
|
||||
import de.kentoj.scrow.bukkit.friends.FriendRequestService;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
@ -15,34 +13,34 @@ public class InMemoryFriendRequestService implements FriendRequestService {
|
|||
private final Set<FriendRequest> requests = new HashSet<>();
|
||||
|
||||
@Override
|
||||
public Flux<@NotNull FriendRequest> getFriendRequestsTo(UUID playerId) {
|
||||
return Flux.fromStream(requests.stream()
|
||||
.filter(req -> req.getTo().equals(playerId)));
|
||||
public List<FriendRequest> getFriendRequestsTo(UUID playerId) {
|
||||
return requests.stream()
|
||||
.filter(req -> req.getTo().equals(playerId))
|
||||
.toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<@NotNull FriendRequest> getFriendRequestsFrom(UUID playerId) {
|
||||
return Flux.fromStream(requests.stream()
|
||||
.filter(req -> req.getFrom().equals(playerId)));
|
||||
public List<FriendRequest> getFriendRequestsFrom(UUID playerId) {
|
||||
return requests.stream()
|
||||
.filter(req -> req.getFrom().equals(playerId))
|
||||
.toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<@NotNull FriendRequest> getFriendRequest(UUID from, UUID to) {
|
||||
return Mono.justOrEmpty(requests.stream()
|
||||
.filter(req -> req.getFrom().equals(from) && req.getTo().equals(to))
|
||||
.findFirst()
|
||||
.orElse(null));
|
||||
public FriendRequest getFriendRequest(UUID from, UUID to) {
|
||||
return requests.stream()
|
||||
.filter(req -> req.getFrom().equals(from) && req.getTo().equals(to))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<@NotNull Boolean> saveFriendRequest(FriendRequest friendRequest) {
|
||||
return getFriendRequest(friendRequest.getFrom(), friendRequest.getTo())
|
||||
.map(__ -> false)
|
||||
.switchIfEmpty(Mono.fromRunnable(() -> requests.add(friendRequest)));
|
||||
public boolean saveFriendRequest(FriendRequest friendRequest) {
|
||||
return requests.add(friendRequest);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<@NotNull Boolean> deleteFriendRequest(UUID from, UUID to) {
|
||||
return Mono.just(requests.removeIf(req -> req.getFrom().equals(from) && req.getTo().equals(to)));
|
||||
public boolean deleteFriendRequest(UUID from, UUID to) {
|
||||
return requests.removeIf(req -> req.getFrom().equals(from) && req.getTo().equals(to));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,107 +0,0 @@
|
|||
package de.kentoj.scrow.bukkit.friends.request;
|
||||
|
||||
import com.mongodb.ErrorCategory;
|
||||
import com.mongodb.MongoWriteException;
|
||||
import com.mongodb.client.model.Filters;
|
||||
import com.mongodb.client.model.IndexOptions;
|
||||
import com.mongodb.client.model.Indexes;
|
||||
import com.mongodb.reactivestreams.client.MongoCollection;
|
||||
import com.mongodb.reactivestreams.client.MongoDatabase;
|
||||
import de.kentoj.scrow.bukkit.friends.FriendRequest;
|
||||
import de.kentoj.scrow.bukkit.friends.FriendRequestService;
|
||||
import org.bson.Document;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
public class MongoFriendRequestService implements FriendRequestService {
|
||||
|
||||
private static final String COLLECTION_NAME = "friend-requests";
|
||||
|
||||
private final MongoDatabase database;
|
||||
|
||||
public MongoFriendRequestService(MongoDatabase database) {
|
||||
this.database = database;
|
||||
|
||||
Mono.when(
|
||||
database.createCollection(COLLECTION_NAME),
|
||||
collection().createIndex(
|
||||
Indexes.compoundIndex(
|
||||
Indexes.ascending("from"),
|
||||
Indexes.ascending("to")
|
||||
),
|
||||
new IndexOptions().unique(true)
|
||||
)
|
||||
).block();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<@NotNull FriendRequest> getFriendRequest(UUID from, UUID to) {
|
||||
return Mono.from(collection()
|
||||
.find(Filters.and(
|
||||
Filters.eq("from", from),
|
||||
Filters.eq("to", to)
|
||||
)))
|
||||
.map(this::fromDocument);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<@NotNull Boolean> saveFriendRequest(FriendRequest friendRequest) {
|
||||
return Mono.from(collection()
|
||||
.insertOne(toDocument(friendRequest))
|
||||
)
|
||||
.map(__ -> true)
|
||||
.onErrorResume(MongoWriteException.class, e ->
|
||||
e.getError().getCategory() == ErrorCategory.DUPLICATE_KEY ?
|
||||
Mono.just(false) :
|
||||
Mono.error(e)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<@NotNull FriendRequest> getFriendRequestsTo(UUID playerId) {
|
||||
return Flux.from(collection()
|
||||
.find(Filters.eq("to", playerId)))
|
||||
.map(this::fromDocument);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<@NotNull FriendRequest> getFriendRequestsFrom(UUID playerId) {
|
||||
return Flux.from(collection()
|
||||
.find()
|
||||
.filter(Filters.eq("from", playerId)))
|
||||
.map(this::fromDocument);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<@NotNull Boolean> deleteFriendRequest(UUID from, UUID to) {
|
||||
return Mono.from(collection()
|
||||
.deleteOne(Filters.and(
|
||||
Filters.eq("from", from),
|
||||
Filters.eq("to", to)
|
||||
)))
|
||||
.map(res -> res.getDeletedCount() > 0);
|
||||
}
|
||||
|
||||
private MongoCollection<Document> collection() {
|
||||
return database.getCollection(COLLECTION_NAME);
|
||||
}
|
||||
|
||||
private Document toDocument(FriendRequest req) {
|
||||
return new Document()
|
||||
.append("from", req.getFrom())
|
||||
.append("to", req.getTo())
|
||||
.append("createdAt", Date.from(req.getCreatedAt()));
|
||||
}
|
||||
|
||||
private FriendRequest fromDocument(Document doc) {
|
||||
return new FriendRequestImpl(
|
||||
doc.get("from", UUID.class),
|
||||
doc.get("to", UUID.class),
|
||||
doc.getDate("createdAt").toInstant()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -31,7 +31,7 @@ public class PostgresFriendRequestService implements FriendRequestService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Mono<@NotNull FriendRequest> getFriendRequest(UUID from, UUID to) {
|
||||
public Result<FriendRequest, String> getFriendRequest(UUID from, UUID to) {
|
||||
return conFactory.create().sql("""
|
||||
SELECT *
|
||||
FROM friend-requests
|
||||
|
|
@ -44,7 +44,7 @@ public class PostgresFriendRequestService implements FriendRequestService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Mono<@NotNull Boolean> saveFriendRequest(FriendRequest friendRequest) {
|
||||
public Result<Boolean, String> saveFriendRequest(FriendRequest friendRequest) {
|
||||
return conFactory.create().sql("""
|
||||
INSERT INTO friend-requests (from_uuid, to_uuid, created_at)
|
||||
VALUES (:from, :to, :created_at)
|
||||
|
|
@ -57,7 +57,7 @@ public class PostgresFriendRequestService implements FriendRequestService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Flux<@NotNull FriendRequest> getFriendRequestsTo(UUID playerId) {
|
||||
public Result<List<FriendRequest>, String> getFriendRequestsTo(UUID playerId) {
|
||||
return conFactory.create().sql("""
|
||||
SELECT *
|
||||
FROM friend-requests
|
||||
|
|
@ -69,7 +69,7 @@ public class PostgresFriendRequestService implements FriendRequestService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Flux<@NotNull FriendRequest> getFriendRequestsFrom(UUID playerId) {
|
||||
public Result<List<FriendRequest>, String> getFriendRequestsFrom(UUID playerId) {
|
||||
return conFactory.create().sql("""
|
||||
SELECT *
|
||||
FROM friend-requests
|
||||
|
|
@ -81,7 +81,7 @@ public class PostgresFriendRequestService implements FriendRequestService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Mono<@NotNull Boolean> deleteFriendRequest(UUID from, UUID to) {
|
||||
public Result<Boolean, String> deleteFriendRequest(UUID from, UUID to) {
|
||||
return conFactory.create().sql("""
|
||||
DELETE
|
||||
FROM friend-requests
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package de.kentoj.scrow.bukkit.playermanager;
|
||||
|
||||
import com.leakyabstractions.result.api.Result;
|
||||
import de.kentoj.scrow.bukkit.PlayerManager;
|
||||
import de.kentoj.scrow.bukkit.misc.PlayerManager;
|
||||
import de.kentoj.scrowlib.messaging.MessageBroker;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.bson.Document;
|
||||
|
|
@ -14,7 +14,7 @@ public class PlayerManagerImpl implements PlayerManager {
|
|||
private final MessageBroker messageBroker;
|
||||
|
||||
@Override
|
||||
public Result<Void, String> sendPlayer(UUID playerId, String instanceHandle) {
|
||||
public Result<Object, String> sendPlayer(UUID playerId, String instanceHandle) {
|
||||
return messageBroker.request("players.send", new Document()
|
||||
.append("playerId", playerId)
|
||||
.append("handle", instanceHandle))
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ public class LobbyCommand implements CommandExecutor<CommandSender> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Result<Void, String>> execute(CommandContext<CommandSender> ctx) {
|
||||
public CompletableFuture<Result<Object, String>> execute(CommandContext<CommandSender> ctx) {
|
||||
Bukkit.dispatchCommand(ctx.getSender(), "play lobby");
|
||||
return CompletableFuture.completedFuture(Results.success(null));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ public class PlayCommand implements CommandExecutor<CommandSender> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Result<Void, String>> execute(CommandContext<CommandSender> ctx) {
|
||||
public CompletableFuture<Result<Object, String>> execute(CommandContext<CommandSender> ctx) {
|
||||
var gamemode = ctx.getArg(gamemodeArg);
|
||||
var player = (Player) ctx.getSender();
|
||||
return CompletableFuture.supplyAsync(() -> ScrowAPI.getInstanceManager().getInstances()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue