.
This commit is contained in:
parent
3433e1d4df
commit
08129e7474
16 changed files with 439 additions and 153 deletions
|
|
@ -27,7 +27,5 @@ public interface FriendsService {
|
||||||
/**
|
/**
|
||||||
* @param from id of player sending the friend request
|
* @param from id of player sending the friend request
|
||||||
* @param to id of the player the initiator wants to befriend
|
* @param to id of the player the initiator wants to befriend
|
||||||
* @throws FriendRequestUsageException
|
|
||||||
*/
|
*/
|
||||||
Mono<@NotNull Friendship> sendFriendRequest(UUID from, UUID to);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ public class OrderedUUIDPair {
|
||||||
private final UUID second;
|
private final UUID second;
|
||||||
|
|
||||||
public OrderedUUIDPair(UUID uuid1, UUID uuid2) {
|
public OrderedUUIDPair(UUID uuid1, UUID uuid2) {
|
||||||
Preconditions.checkArgument(uuid1 != uuid2);
|
Preconditions.checkArgument(uuid1 != uuid2, "UUIDPair may consist of identical UUIDs");
|
||||||
if (uuid1.compareTo(uuid2) < 0) {
|
if (uuid1.compareTo(uuid2) < 0) {
|
||||||
this.first = uuid1;
|
this.first = uuid1;
|
||||||
this.second = uuid2;
|
this.second = uuid2;
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,12 @@ package de.kentoj.scrow.bukkit;
|
||||||
import de.kentoj.scrow.bukkit.economy.CoinsCommand;
|
import de.kentoj.scrow.bukkit.economy.CoinsCommand;
|
||||||
import de.kentoj.scrow.bukkit.friends.command.FriendCommand;
|
import de.kentoj.scrow.bukkit.friends.command.FriendCommand;
|
||||||
import de.kentoj.scrow.bukkit.friends.friendship.MongoFriendshipDAO;
|
import de.kentoj.scrow.bukkit.friends.friendship.MongoFriendshipDAO;
|
||||||
|
import de.kentoj.scrow.bukkit.friends.request.FriendRequestImpl;
|
||||||
|
import de.kentoj.scrow.bukkit.friends.request.MongoFriendRequestDAO;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class CoreImplPlugin extends JavaPlugin {
|
public class CoreImplPlugin extends JavaPlugin {
|
||||||
|
|
@ -14,9 +17,13 @@ public class CoreImplPlugin extends JavaPlugin {
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
ScrowAPISurface.initScrowAPI(this, true);
|
ScrowAPISurface.initScrowAPI(this, true);
|
||||||
|
|
||||||
|
assert ScrowAPI.getDatabase() != null;
|
||||||
|
var friendshipDAO = new MongoFriendshipDAO(ScrowAPI.getDatabase());
|
||||||
|
var friendRequestsDAO = new MongoFriendRequestDAO(ScrowAPI.getDatabase());
|
||||||
|
|
||||||
{
|
{
|
||||||
ScrowAPI.getCommandManager().register(new CoinsCommand().getRootNode());
|
ScrowAPI.getCommandManager().register(new CoinsCommand().getRootNode());
|
||||||
ScrowAPI.getCommandManager().register(new FriendCommand(new MongoFriendshipDAO(ScrowAPI.getDatabase())).getRootNode());
|
ScrowAPI.getCommandManager().register(new FriendCommand(friendshipDAO, friendRequestsDAO).getRootNode());
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
@ -34,6 +41,20 @@ public class CoreImplPlugin extends JavaPlugin {
|
||||||
.doOnNext(a -> System.out.println("coins: " + a))
|
.doOnNext(a -> System.out.println("coins: " + a))
|
||||||
.block();
|
.block();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
friendRequestsDAO.saveFriendRequest(new FriendRequestImpl(
|
||||||
|
UUID.fromString("7fca8ec5-c855-4547-aed9-21a20b31617c") /* logan */,
|
||||||
|
UUID.fromString("3218c49a-b80d-49ae-a42e-4496141eb2b1") /* kento2 */,
|
||||||
|
Instant.now()
|
||||||
|
)).block();
|
||||||
|
|
||||||
|
friendRequestsDAO.saveFriendRequest(new FriendRequestImpl(
|
||||||
|
UUID.fromString("3218c49a-b80d-49ae-a42e-4496141eb2b1") /* kento2 */,
|
||||||
|
UUID.fromString("3218c49a-b80d-49ae-a42e-4496141eb2b1") /* kento2 */,
|
||||||
|
Instant.now()
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,86 @@
|
||||||
|
package de.kentoj.scrow.bukkit.friends.command;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.*;
|
||||||
|
|
||||||
|
public class BukkitExecutorService implements ExecutorService {
|
||||||
|
|
||||||
|
private final ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
|
||||||
|
|
||||||
|
public <T> Future<T> io(Callable<T> task) {
|
||||||
|
return executor.submit(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void shutdown() {
|
||||||
|
executor.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull List<Runnable> shutdownNow() {
|
||||||
|
return executor.shutdownNow();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isShutdown() {
|
||||||
|
return executor.isShutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isTerminated() {
|
||||||
|
return executor.isTerminated();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean awaitTermination(long l, @NotNull TimeUnit timeUnit) throws InterruptedException {
|
||||||
|
return executor.awaitTermination(l, timeUnit);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull <T> Future<T> submit(@NotNull Callable<T> callable) {
|
||||||
|
return executor.submit(callable);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull <T> Future<T> submit(@NotNull Runnable runnable, T t) {
|
||||||
|
return executor.submit(runnable, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull Future<?> submit(@NotNull Runnable runnable) {
|
||||||
|
return executor.submit(runnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull <T> List<Future<T>> invokeAll(@NotNull Collection<? extends Callable<T>> collection) throws InterruptedException {
|
||||||
|
return executor.invokeAll(collection);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull <T> List<Future<T>> invokeAll(@NotNull Collection<? extends Callable<T>> collection, long l, @NotNull TimeUnit timeUnit) throws InterruptedException {
|
||||||
|
return executor.invokeAll(collection, l, timeUnit);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull <T> T invokeAny(@NotNull Collection<? extends Callable<T>> collection) throws InterruptedException, ExecutionException {
|
||||||
|
return (T) executor.invokeAll(collection);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> T invokeAny(@NotNull Collection<? extends Callable<T>> collection, long l, @NotNull TimeUnit timeUnit) throws InterruptedException, ExecutionException, TimeoutException {
|
||||||
|
return (T) executor.invokeAll(collection, l, timeUnit);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
executor.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(@NotNull Runnable runnable) {
|
||||||
|
executor.execute(runnable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
package de.kentoj.scrow.bukkit.friends.command;
|
||||||
|
|
||||||
|
import de.kentoj.kencommandapi.BukkitCommandContext;
|
||||||
|
import de.kentoj.kencommandapi.api.structure.node.CommandNode;
|
||||||
|
import de.kentoj.kencommandapi.type.OfflinePlayerArgumentType;
|
||||||
|
import de.kentoj.scrow.bukkit.ScrowAPI;
|
||||||
|
import de.kentoj.scrow.bukkit.friends.command.handler.FriendAddHandler;
|
||||||
|
import de.kentoj.scrow.bukkit.friends.friendship.FriendshipDAO;
|
||||||
|
import de.kentoj.scrow.bukkit.friends.request.FriendRequestDAO;
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
|
public class FriendAddLiteral {
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final CommandNode<CommandSender, BukkitCommandContext> node;
|
||||||
|
|
||||||
|
public FriendAddLiteral(FriendshipDAO friendshipDAO, FriendRequestDAO friendRequestDAO) {
|
||||||
|
var cmdManager = ScrowAPI.getCommandManager();
|
||||||
|
var playerArg = cmdManager.createArgument("player", OfflinePlayerArgumentType.getInstance());
|
||||||
|
|
||||||
|
this.node = cmdManager.createNode("add");
|
||||||
|
this.node.addArgument(playerArg);
|
||||||
|
this.node.setExecutor(ctx -> {
|
||||||
|
var handler = new FriendAddHandler(ctx.getPlayerSender(), ctx.getArg(playerArg), friendshipDAO, friendRequestDAO);
|
||||||
|
handler.handle();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,6 +4,7 @@ import de.kentoj.kencommandapi.BukkitCommandContext;
|
||||||
import de.kentoj.kencommandapi.api.structure.node.CommandNode;
|
import de.kentoj.kencommandapi.api.structure.node.CommandNode;
|
||||||
import de.kentoj.scrow.bukkit.ScrowAPI;
|
import de.kentoj.scrow.bukkit.ScrowAPI;
|
||||||
import de.kentoj.scrow.bukkit.friends.friendship.FriendshipDAO;
|
import de.kentoj.scrow.bukkit.friends.friendship.FriendshipDAO;
|
||||||
|
import de.kentoj.scrow.bukkit.friends.request.FriendRequestDAO;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
|
|
@ -12,8 +13,10 @@ public class FriendCommand {
|
||||||
@Getter
|
@Getter
|
||||||
private final CommandNode<CommandSender, BukkitCommandContext> rootNode;
|
private final CommandNode<CommandSender, BukkitCommandContext> rootNode;
|
||||||
|
|
||||||
public FriendCommand(FriendshipDAO friendshipDAO) {
|
public FriendCommand(FriendshipDAO friendshipDAO, FriendRequestDAO friendRequestDAO) {
|
||||||
this.rootNode = ScrowAPI.getCommandManager().createNode("friends", "f", "friend");
|
this.rootNode = ScrowAPI.getCommandManager().createNode("friends", "f", "friend");
|
||||||
rootNode.addLiteral(new FriendListLiteral(friendshipDAO).getNode());
|
rootNode.addLiteral(new FriendListLiteral(friendshipDAO).getNode());
|
||||||
|
rootNode.addLiteral(new FriendAddLiteral(friendshipDAO, friendRequestDAO).getNode());
|
||||||
|
rootNode.addLiteral(new FriendRequestsLiteral(friendRequestDAO).getNode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,16 +25,16 @@ public class FriendListLiteral {
|
||||||
var ownUid = ctx.getPlayerSender().getUniqueId();
|
var ownUid = ctx.getPlayerSender().getUniqueId();
|
||||||
ctx.getPlayerSender().sendMessage("friends:");
|
ctx.getPlayerSender().sendMessage("friends:");
|
||||||
friendshipDAO.getFriendships(ownUid)
|
friendshipDAO.getFriendships(ownUid)
|
||||||
.publishOn(ScrowAPI.getMinecraftScheduler())
|
|
||||||
.subscribeOn(Schedulers.boundedElastic())
|
|
||||||
.map(friendship -> {
|
.map(friendship -> {
|
||||||
var friendPlayerUid = friendship.getUuids().getOther(ownUid);
|
var friendPlayerUid = friendship.getUuids().getOther(ownUid);
|
||||||
var friendPlayerName = Bukkit.getOfflinePlayer(friendPlayerUid).getName();
|
var friendPlayerName = Bukkit.getOfflinePlayer(friendPlayerUid).getName();
|
||||||
return "- " + friendPlayerName;
|
return "- " + friendPlayerName;
|
||||||
}).doOnNext(line -> {
|
})
|
||||||
ctx.getPlayerSender().sendMessage(line);
|
.doOnNext(line -> ctx.getSender().sendMessage(line))
|
||||||
}).doOnComplete(() -> {
|
.doOnComplete(() -> ctx.getSender().sendMessage("EOF"))
|
||||||
ctx.getPlayerSender().sendMessage("EOF");
|
|
||||||
});
|
.publishOn(ScrowAPI.getMinecraftScheduler())
|
||||||
|
.subscribeOn(Schedulers.boundedElastic())
|
||||||
|
.subscribe();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
package de.kentoj.scrow.bukkit.friends.command;
|
||||||
|
|
||||||
|
import de.kentoj.kencommandapi.BukkitCommandContext;
|
||||||
|
import de.kentoj.kencommandapi.api.structure.node.CommandNode;
|
||||||
|
import de.kentoj.scrow.bukkit.ScrowAPI;
|
||||||
|
import de.kentoj.scrow.bukkit.friends.request.FriendRequestDAO;
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import reactor.core.scheduler.Schedulers;
|
||||||
|
|
||||||
|
public class FriendRequestsLiteral {
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final CommandNode<CommandSender, BukkitCommandContext> node;
|
||||||
|
private final FriendRequestDAO friendRequestDAO;
|
||||||
|
|
||||||
|
public FriendRequestsLiteral(FriendRequestDAO friendRequestDAO) {
|
||||||
|
this.friendRequestDAO = friendRequestDAO;
|
||||||
|
this.node = ScrowAPI.getCommandManager().createNode("requests", "list-requests");
|
||||||
|
node.setExecutor(this::friendRequestsList);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void friendRequestsList(BukkitCommandContext ctx) {
|
||||||
|
var ownUid = ctx.getPlayerSender().getUniqueId();
|
||||||
|
ctx.getPlayerSender().sendMessage("incoming friends requests:");
|
||||||
|
friendRequestDAO.getFriendRequestsTo(ownUid)
|
||||||
|
.publishOn(ScrowAPI.getMinecraftScheduler())
|
||||||
|
.subscribeOn(Schedulers.boundedElastic())
|
||||||
|
.map(friendRequest -> {
|
||||||
|
var fromUid = friendRequest.getFrom();
|
||||||
|
var fromName = Bukkit.getOfflinePlayer(fromUid).getName();
|
||||||
|
return "- " + fromName;
|
||||||
|
}).doOnNext(line -> ctx.getPlayerSender().sendMessage(line))
|
||||||
|
.doOnComplete(() -> ctx.getPlayerSender().sendMessage("EOF"))
|
||||||
|
.subscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,97 @@
|
||||||
|
package de.kentoj.scrow.bukkit.friends.command.handler;
|
||||||
|
|
||||||
|
import de.kentoj.scrow.bukkit.ScrowAPI;
|
||||||
|
import de.kentoj.scrow.bukkit.friends.friendship.FriendshipDAO;
|
||||||
|
import de.kentoj.scrow.bukkit.friends.friendship.FriendshipImpl;
|
||||||
|
import de.kentoj.scrow.bukkit.friends.request.FriendRequestDAO;
|
||||||
|
import de.kentoj.scrow.bukkit.friends.request.FriendRequestImpl;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.bukkit.OfflinePlayer;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
import reactor.core.scheduler.Schedulers;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class FriendAddHandler {
|
||||||
|
|
||||||
|
private final Player self;
|
||||||
|
private final OfflinePlayer other;
|
||||||
|
private final FriendshipDAO friendshipDAO;
|
||||||
|
private final FriendRequestDAO friendRequestDAO;
|
||||||
|
|
||||||
|
public void handle() {
|
||||||
|
findAction()
|
||||||
|
.flatMap(this::executeAction)
|
||||||
|
.subscribeOn(Schedulers.boundedElastic())
|
||||||
|
.subscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Mono<?> executeAction(AddAction action) {
|
||||||
|
return switch (action) {
|
||||||
|
case ERR_ALREADY_FRIENDS -> sendMessage(self, "[friends] You are already friends with " + other.getName());
|
||||||
|
case ERR_ALREADY_REQUESTED ->
|
||||||
|
sendMessage(self, "[friends] You already requested " + other.getName() + " to be friends with you");
|
||||||
|
case SEND_REQUEST -> sendRequest();
|
||||||
|
case ACCEPT_REQUEST -> acceptRequest();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private Mono<?> sendRequest() {
|
||||||
|
return friendRequestDAO.saveFriendRequest(new FriendRequestImpl(self.getUniqueId(), other.getUniqueId(), Instant.now()))
|
||||||
|
.then(sendMessage(self.getPlayer(), "[friends] Successfully sent " + other.getName() + " a friend request."))
|
||||||
|
.then(Mono.fromRunnable(() -> {
|
||||||
|
var otherPlayer = other.getPlayer();
|
||||||
|
if (otherPlayer != null)
|
||||||
|
sendMessage(otherPlayer, "[friends] " + self.getName() + " wants to be friends with you. Use '/f add " + self.getName() + "' to accept.").subscribe();
|
||||||
|
}))
|
||||||
|
.doOnError(this::handleError);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Mono<?> acceptRequest() {
|
||||||
|
return Mono.when(
|
||||||
|
friendRequestDAO.deleteFriendRequest(self.getUniqueId(), other.getUniqueId()),
|
||||||
|
friendRequestDAO.deleteFriendRequest(other.getUniqueId(), self.getUniqueId()),
|
||||||
|
friendshipDAO.saveFriendship(new FriendshipImpl(self.getUniqueId(), other.getUniqueId(), Instant.now()))
|
||||||
|
)
|
||||||
|
.then(sendMessage(self, "[friends] You are now friends with " + other.getName()))
|
||||||
|
.then(Mono.fromRunnable(() -> {
|
||||||
|
var otherPlayer = other.getPlayer();
|
||||||
|
if (otherPlayer != null)
|
||||||
|
sendMessage(otherPlayer, "[friends] You are now friends with " + self.getName()).subscribe();
|
||||||
|
}))
|
||||||
|
.doOnError(this::handleError);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Mono<@NotNull AddAction> findAction() {
|
||||||
|
return friendshipDAO.getFriendship(self.getUniqueId(), other.getUniqueId())
|
||||||
|
.map(f -> AddAction.ERR_ALREADY_FRIENDS)
|
||||||
|
.switchIfEmpty(
|
||||||
|
friendRequestDAO.getFriendRequest(self.getUniqueId(), other.getUniqueId())
|
||||||
|
.map(r -> AddAction.ERR_ALREADY_REQUESTED)
|
||||||
|
.switchIfEmpty(
|
||||||
|
friendRequestDAO.getFriendRequest(other.getUniqueId(), self.getUniqueId())
|
||||||
|
.map(r -> AddAction.ACCEPT_REQUEST)
|
||||||
|
.switchIfEmpty(Mono.just(AddAction.SEND_REQUEST))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Mono<?> sendMessage(Player player, String msg) {
|
||||||
|
return Mono.fromRunnable(() -> player.sendMessage(msg))
|
||||||
|
.subscribeOn(ScrowAPI.getMinecraftScheduler());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleError(Throwable e) {
|
||||||
|
sendMessage(self.getPlayer(), "FAILED SENDING REQUEST. REPORT THIS BUG. " + e.getMessage()).subscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum AddAction {
|
||||||
|
ERR_ALREADY_FRIENDS,
|
||||||
|
ERR_ALREADY_REQUESTED,
|
||||||
|
SEND_REQUEST,
|
||||||
|
ACCEPT_REQUEST
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package de.kentoj.scrow.bukkit.friends.friendship;
|
package de.kentoj.scrow.bukkit.friends.friendship;
|
||||||
|
|
||||||
import de.kentoj.scrow.bukkit.friends.Friendship;
|
import de.kentoj.scrow.bukkit.friends.Friendship;
|
||||||
|
import de.kentoj.scrow.bukkit.friends.OrderedUUIDPair;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import reactor.core.publisher.Flux;
|
import reactor.core.publisher.Flux;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
@ -9,9 +10,11 @@ import java.util.UUID;
|
||||||
|
|
||||||
public interface FriendshipDAO {
|
public interface FriendshipDAO {
|
||||||
|
|
||||||
|
Mono<@NotNull Friendship> getFriendship(UUID uuid1, UUID uuid2);
|
||||||
|
|
||||||
Flux<@NotNull Friendship> getFriendships(UUID playerId);
|
Flux<@NotNull Friendship> getFriendships(UUID playerId);
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* @return True if friendship saved, false if friendship already exists
|
* @return True if friendship saved, false if friendship already exists
|
||||||
*/
|
*/
|
||||||
Mono<@NotNull Boolean> saveFriendship(Friendship playerIds);
|
Mono<@NotNull Boolean> saveFriendship(Friendship playerIds);
|
||||||
|
|
|
||||||
|
|
@ -26,14 +26,26 @@ public class MongoFriendshipDAO implements FriendshipDAO {
|
||||||
public MongoFriendshipDAO(MongoDatabase database) {
|
public MongoFriendshipDAO(MongoDatabase database) {
|
||||||
this.database = database;
|
this.database = database;
|
||||||
|
|
||||||
Mono.from(database.createCollection(COLLECTION_NAME)).block();
|
Mono.when(
|
||||||
Mono.from(collection().createIndex(
|
database.createCollection(COLLECTION_NAME),
|
||||||
Indexes.compoundIndex(
|
collection().createIndex(
|
||||||
Indexes.ascending("first"),
|
Indexes.compoundIndex(
|
||||||
Indexes.ascending("second")
|
Indexes.ascending("first"),
|
||||||
),
|
Indexes.ascending("second")
|
||||||
new IndexOptions().unique(true)
|
),
|
||||||
)).block();
|
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.or(
|
||||||
|
Filters.eq("first", uuids.getFirst()),
|
||||||
|
Filters.eq("second", uuids.getSecond())
|
||||||
|
)))
|
||||||
|
.map(this::fromDocument);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -73,14 +85,15 @@ public class MongoFriendshipDAO implements FriendshipDAO {
|
||||||
return database.getCollection(COLLECTION_NAME);
|
return database.getCollection(COLLECTION_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
private @NotNull Friendship fromDocument(Document doc) {
|
private Friendship fromDocument(Document doc) {
|
||||||
var first = UUID.fromString(doc.getString("first"));
|
return new FriendshipImpl(
|
||||||
var second = UUID.fromString(doc.getString("second"));
|
doc.get("first", UUID.class),
|
||||||
var createdAt = doc.getDate("createdAt").toInstant();
|
doc.get("second", UUID.class),
|
||||||
return new FriendshipImpl(first, second, createdAt);
|
doc.getDate("createdAt").toInstant()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private @NotNull Document toDocument(Friendship friendship) {
|
private Document toDocument(Friendship friendship) {
|
||||||
return new Document()
|
return new Document()
|
||||||
.append("first", friendship.getUuids().getFirst().toString())
|
.append("first", friendship.getUuids().getFirst().toString())
|
||||||
.append("second", friendship.getUuids().getSecond().toString())
|
.append("second", friendship.getUuids().getSecond().toString())
|
||||||
|
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
package de.kentoj.scrow.bukkit.friends.request;
|
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
|
||||||
import de.kentoj.scrow.bukkit.friends.FriendRequest;
|
|
||||||
import lombok.Value;
|
|
||||||
import org.bson.codecs.pojo.annotations.BsonCreator;
|
|
||||||
import org.bson.codecs.pojo.annotations.BsonProperty;
|
|
||||||
import org.bson.types.ObjectId;
|
|
||||||
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
@Value
|
|
||||||
public class BsonFriendRequest implements FriendRequest {
|
|
||||||
ObjectId requestId;
|
|
||||||
UUID from;
|
|
||||||
UUID to;
|
|
||||||
Instant createdAt;
|
|
||||||
|
|
||||||
@BsonCreator
|
|
||||||
public BsonFriendRequest(
|
|
||||||
@BsonProperty("_id") ObjectId requestId,
|
|
||||||
@BsonProperty("from") UUID from,
|
|
||||||
@BsonProperty("to") UUID to,
|
|
||||||
@BsonProperty("createdAt") Instant createdAt
|
|
||||||
) {
|
|
||||||
Preconditions.checkArgument(from != to, "friend-request can not have same 'from' and 'to' value");
|
|
||||||
this.requestId = requestId;
|
|
||||||
this.from = from;
|
|
||||||
this.to = to;
|
|
||||||
this.createdAt = createdAt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BsonFriendRequest(UUID from, UUID to, Instant createdAt) {
|
|
||||||
this(ObjectId.get(), from, to, createdAt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -8,18 +8,18 @@ import reactor.core.publisher.Mono;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public interface FriendRequestRepository {
|
public interface FriendRequestDAO {
|
||||||
|
|
||||||
Flux<@NotNull FriendRequest> getIncomingFriendRequests(UUID playerId);
|
Flux<@NotNull FriendRequest> getFriendRequestsTo(UUID playerId);
|
||||||
|
|
||||||
Flux<@NotNull FriendRequest> getOutgoingFriendRequests(UUID playerId);
|
Flux<@NotNull FriendRequest> getFriendRequestsFrom(UUID playerId);
|
||||||
|
|
||||||
Mono<@NotNull FriendRequest> getFriendRequest(UUID from, UUID to);
|
Mono<@NotNull FriendRequest> getFriendRequest(UUID from, UUID to);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return True if request saved, false if already existing request found.
|
* @return True if request saved, false if already existing request found.
|
||||||
*/
|
*/
|
||||||
Mono<@NotNull Boolean> saveFriendRequest(UUID from, UUID to, Instant createdAt);
|
Mono<@NotNull Boolean> saveFriendRequest(FriendRequest friendRequest);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return True if request deleted, false if none found.
|
* @return True if request deleted, false if none found.
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
package de.kentoj.scrow.bukkit.friends.request;
|
||||||
|
|
||||||
|
import de.kentoj.scrow.bukkit.friends.FriendRequest;
|
||||||
|
import lombok.Value;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Value
|
||||||
|
public class FriendRequestImpl implements FriendRequest {
|
||||||
|
UUID from;
|
||||||
|
UUID to;
|
||||||
|
Instant createdAt;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,106 @@
|
||||||
|
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 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 MongoFriendRequestDAO implements FriendRequestDAO {
|
||||||
|
|
||||||
|
private static final String COLLECTION_NAME = "friend-requests";
|
||||||
|
|
||||||
|
private final MongoDatabase database;
|
||||||
|
|
||||||
|
public MongoFriendRequestDAO(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()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,85 +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 org.jetbrains.annotations.NotNull;
|
|
||||||
import reactor.core.publisher.Flux;
|
|
||||||
import reactor.core.publisher.Mono;
|
|
||||||
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class MongoFriendRequestRepository implements FriendRequestRepository {
|
|
||||||
|
|
||||||
private static final String COLLECTION_NAME = "friend-requests";
|
|
||||||
|
|
||||||
private final MongoDatabase database;
|
|
||||||
|
|
||||||
public MongoFriendRequestRepository(MongoDatabase database) {
|
|
||||||
this.database = database;
|
|
||||||
|
|
||||||
database.createCollection(COLLECTION_NAME);
|
|
||||||
collection().createIndex(
|
|
||||||
Indexes.compoundIndex(
|
|
||||||
Indexes.ascending("from"),
|
|
||||||
Indexes.ascending("to")
|
|
||||||
),
|
|
||||||
new IndexOptions().unique(true)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@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)
|
|
||||||
))
|
|
||||||
.first());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Mono<@NotNull Boolean> saveFriendRequest(UUID from, UUID to, Instant createdAt) {
|
|
||||||
var request = new BsonFriendRequest(from, to, createdAt);
|
|
||||||
return Mono.from(collection()
|
|
||||||
.insertOne(request)
|
|
||||||
)
|
|
||||||
.map(__ -> true)
|
|
||||||
.onErrorResume(e -> {
|
|
||||||
if (!(e instanceof MongoWriteException)) return Mono.error(e);
|
|
||||||
if (((MongoWriteException) e).getError().getCategory() != ErrorCategory.DUPLICATE_KEY)
|
|
||||||
return Mono.error(e);
|
|
||||||
return Mono.just(false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Flux<@NotNull FriendRequest> getIncomingFriendRequests(UUID playerId) {
|
|
||||||
return Flux.from(collection().find(Filters.eq("to", playerId)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Flux<@NotNull FriendRequest> getOutgoingFriendRequests(UUID playerId) {
|
|
||||||
return Flux.from(collection().find(Filters.eq("from", playerId)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@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<BsonFriendRequest> collection() {
|
|
||||||
return database.getCollection(COLLECTION_NAME, BsonFriendRequest.class);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue