lowk did smth

This commit is contained in:
kento2 2026-02-16 09:47:03 +01:00
parent 702fa6deeb
commit 4879257f47
54 changed files with 486 additions and 243 deletions

View file

@ -0,0 +1,45 @@
plugins {
id("java")
id("com.gradleup.shadow") version "9.2.0"
id("xyz.jpenilla.run-paper") version "2.3.1"
kotlin("jvm")
}
group = "de.kentoj.scrow"
version = "1.0-SNAPSHOT"
repositories {
mavenCentral()
}
dependencies {
testImplementation(platform("org.junit:junit-bom:5.10.0"))
testImplementation("org.junit.jupiter:junit-jupiter")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
implementation(project(":core-bukkit-api"))
implementation(kotlin("stdlib-jdk8"))
}
tasks {
runServer {
minecraftVersion("1.21.11")
downloadPlugins {
url("https://hangarcdn.papermc.io/plugins/ViaVersion/ViaVersion/versions/5.7.1/PAPER/ViaVersion-5.7.1.jar")
url("https://hangarcdn.papermc.io/plugins/ViaVersion/ViaBackwards/versions/5.7.1/PAPER/ViaBackwards-5.7.1.jar")
}
}
}
tasks.build {
dependsOn("shadowJar")
}
tasks.test {
useJUnitPlatform()
}
kotlin {
jvmToolchain(21)
}

View file

@ -0,0 +1,35 @@
package de.kentoj.scrow.bukkit;
import org.bukkit.plugin.java.JavaPlugin;
import reactor.core.publisher.Mono;
import java.util.UUID;
public class CoreImplPlugin extends JavaPlugin {
@Override
public void onEnable() {
ScrowAPISurface.initScrowAPI(false);
{
var playerId = UUID.randomUUID();
var economyService = ScrowAPI.getEconomyService();
Mono.when(
economyService.setCoins(playerId, 120),
economyService.depositCoins(playerId, 100)
)
.then(economyService.tryWithdrawCoins(playerId, 300))
.doOnNext(a -> System.out.println("withdraw 1 success " + a))
.then(economyService.tryWithdrawCoins(playerId, 50))
.doOnNext(a -> System.out.println("withdraw 2 success " + a))
.then(economyService.getCoins(playerId))
.doOnNext(a -> System.out.println("coins: " + a))
.block();
}
ScrowAPISurface.destroyScrowAPI();
}
@Override
public void onDisable() {
}
}

View file

@ -0,0 +1,47 @@
package de.kentoj.scrow.bukkit;
import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.reactivestreams.client.MongoClient;
import com.mongodb.reactivestreams.client.MongoClients;
import de.kentoj.scrow.bukkit.economy.InMemoryEconomyService;
import de.kentoj.scrow.bukkit.economy.MongoEconomyService;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.bson.UuidRepresentation;
import org.bson.codecs.configuration.CodecRegistries;
import org.bson.codecs.pojo.PojoCodecProvider;
import org.jetbrains.annotations.Nullable;
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class ScrowAPISurface {
private static @Nullable MongoClient databaseClient = null;
public static void initScrowAPI(boolean enableDatabase) {
if (enableDatabase) {
var pojoCodecProvider = PojoCodecProvider.builder().automatic(true).build();
var codecRegistry = CodecRegistries.fromRegistries(
MongoClientSettings.getDefaultCodecRegistry(),
CodecRegistries.fromProviders(pojoCodecProvider)
);
var settings = MongoClientSettings.builder()
.codecRegistry(codecRegistry)
.uuidRepresentation(UuidRepresentation.STANDARD)
.applyConnectionString(new ConnectionString("mongodb://localhost:27017/scrow"))
.build();
databaseClient = MongoClients.create(settings);
}
ScrowAPI.setEconomyService(
ScrowAPI.getDatabase() != null ?
new MongoEconomyService(ScrowAPI.getDatabase()) : new InMemoryEconomyService()
);
}
public static void destroyScrowAPI() {
if (databaseClient != null) {
databaseClient.close();
}
}
}

View file

@ -0,0 +1,69 @@
package de.kentoj.scrow.bukkit.command;
import com.google.common.collect.ImmutableList;
import de.kentoj.scrow.bukkit.services.old.CommandExecutor;
import de.kentoj.scrow.bukkit.services.old.RegisteredCmdArg;
import de.kentoj.scrow.bukkit.services.old.SCommand;
import de.kentoj.scrow.bukkit.services.old.arg.CmdArg;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
import org.bukkit.permissions.Permission;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
public abstract class AbstractSCommand implements SCommand {
private final List<SCommand> subCommands = new ArrayList<>();
private final List<RegisteredCmdArg<?>> args = new ArrayList<>();
@Getter
private final String[] labels;
@Getter
private @Nullable Permission permission = null;
@Getter
@Setter(value = AccessLevel.PROTECTED)
private @Nullable String description;
@Getter
@Setter(value = AccessLevel.PROTECTED)
private @Nullable CommandExecutor executor = null;
public AbstractSCommand(String... labels) {
this.labels = labels;
}
protected <T> void addArg(String key, CmdArg<T> arg) {
}
protected <T> void addArg(String key, CmdArg<T> arg, T defaultValue) {
var index = args.size();
args.add(new RegisteredCmdArg<>(index, key, arg));
}
@Override
public RegisteredCmdArg<?> getArg(int index) {
//noinspection OptionalGetWithoutIsPresent
return args.stream()
.filter(ra -> ra.getIndex() == index)
.findFirst()
.get();
}
public void addSubCommand(SCommand subCommand) {
subCommands.add(subCommand);
}
protected void setPermission(@Nullable Permission permission) {
this.permission = permission;
}
protected void setPermission(String permission) {
setPermission(new Permission(permission));
}
public List<SCommand> getSubCommands() {
return ImmutableList.copyOf(subCommands);
}
}

View file

@ -0,0 +1,33 @@
package de.kentoj.scrow.bukkit.command;
import de.kentoj.scrow.bukkit.services.old.CmdContext;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import java.util.Map;
@RequiredArgsConstructor
public class CmdContextImpl implements CmdContext {
private final Map<String, Object> args;
@Getter
private final CommandSender sender;
@Override
public Player getSenderPlayer() {
return (Player) sender;
}
@Override
public Entity getSenderEntity() {
return (Entity) sender;
}
@SuppressWarnings("unchecked")
public <T> T getArg(String key) {
return (T) args.get(key);
}
}

View file

@ -0,0 +1,29 @@
package de.kentoj.scrow.bukkit.command;
import de.kentoj.scrow.bukkit.services.old.CmdContext;
import de.kentoj.scrow.bukkit.services.old.SCommand;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Map;
public class CommandProcessor implements CommandExecutor {
public CmdContext process(SCommand scommand, String[] strArgs, CommandSender sender) {
Map<String, Object> args = new HashMap<>();
for (int i = 0; i < strArgs.length; i++) {
var arg = scommand.getArg(i);
var value = arg.getArg().parseInput(strArgs[i]);
args.put(arg.getKey(), value);
}
return new CmdContextImpl(args, sender);
}
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
return false;
}
}

View file

@ -0,0 +1,26 @@
package de.kentoj.scrow.bukkit.command;
import de.kentoj.scrow.bukkit.services.old.CommandExecutor;
import de.kentoj.scrow.bukkit.services.old.arg.PlayerArgType;
import de.kentoj.scrow.bukkit.services.old.CmdContext;
import org.bukkit.entity.Player;
import org.bukkit.permissions.Permission;
import org.bukkit.util.Vector;
public class LaunchCommand extends AbstractSCommand implements CommandExecutor {
public LaunchCommand() {
super("launch");
setPermission(new Permission("corebukkit.cmd.launch"));
setExecutor(this);
addArg("player", PlayerArgType.player);
addArg("factor", IntRangeType.range(1, 5), 1);
}
@Override
public boolean execute(CmdContext ctx) {
final Player player = ctx.getArg("player");
player.setVelocity(new Vector(0, 1, 0));
return true;
}
}

View file

@ -0,0 +1,47 @@
package de.kentoj.scrow.bukkit.economy;
import com.google.common.base.Preconditions;
import de.kentoj.scrow.bukkit.services.EconomyService;
import org.jetbrains.annotations.NotNull;
import reactor.core.publisher.Mono;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
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));
}
@Override
public Mono<@NotNull Void> setCoins(UUID playerId, int amount) {
Preconditions.checkArgument(amount >= 0, "amount can not be negative");
return Mono.fromSupplier(() -> coins.put(playerId, amount)).then();
}
@Override
public Mono<@NotNull 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);
});
}
@Override
public Mono<@NotNull 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;
});
}
}

View file

@ -0,0 +1,74 @@
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.services.EconomyService;
import org.bson.Document;
import org.bson.types.ObjectId;
import org.jetbrains.annotations.NotNull;
import reactor.core.publisher.Mono;
import java.util.UUID;
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);
}
}

View file

@ -0,0 +1,22 @@
package de.kentoj.scrow.bukkit.friends;
import com.mojang.brigadier.Command;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
public class FriendsCommand {
public static Command<?> createCommand() {
return LiteralArgumentBuilder.literal("friends")
.then(LiteralArgumentBuilder.literal("add")
.then(RequiredArgumentBuilder.argument("player", StringArgumentType.word())))
.then(LiteralArgumentBuilder.literal("list"))
.then(LiteralArgumentBuilder.literal("requests"))
.then(LiteralArgumentBuilder.literal("remove"))
.then(LiteralArgumentBuilder.literal("jump"))
.then(LiteralArgumentBuilder.literal("accept"))
.then(LiteralArgumentBuilder.literal("deny"))
.build().getCommand();
}
}

View file

@ -0,0 +1,36 @@
package de.kentoj.scrow.bukkit.friends;
import de.kentoj.scrow.bukkit.services.friends.FriendRequest;
import de.kentoj.scrow.bukkit.services.friends.Friendship;
import org.jetbrains.annotations.NotNull;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.UUID;
public interface FriendshipService {
Flux<@NotNull Friendship> getFriendships(UUID playerId);
/**
* @param initiator id of player who wished to end the friendship
* @param other id of the player the initiator wants to end the friendship with
* @return true on success, false if no such friendship existed.
*/
Mono<@NotNull Boolean> endFriendship(UUID initiator, UUID other);
Flux<@NotNull FriendRequest> getIncomingFriendRequests(UUID playerId);
Flux<@NotNull FriendRequest> getOutgoingFriendRequests(UUID playerId);
/**
* @param initiator id of player sending the friend request
* @param to id of the player the initiator wants to befriend
* @return true on success, false if already requested
*/
Mono<@NotNull Boolean> sendFriendRequest(UUID initiator, UUID to);
Mono<@NotNull Friendship> acceptFriendRequest(UUID from, UUID to);
Mono<@NotNull Friendship> denyFriendRequest(UUID from, UUID to);
}

View file

@ -0,0 +1,36 @@
package de.kentoj.scrow.bukkit.friends.friendship;
import com.google.common.base.Preconditions;
import de.kentoj.scrow.bukkit.services.friends.Friendship;
import de.kentoj.scrow.bukkit.util.pair.Tuple2;
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 BsonFriendship implements Friendship {
ObjectId id;
Tuple2<UUID, UUID> playerIds;
Instant createdAt;
@BsonCreator
public BsonFriendship(
@BsonProperty("_id") ObjectId id,
@BsonProperty("playerIds") Tuple2<UUID, UUID> playerIds,
@BsonProperty("createdAt") Instant createdAt
) {
Preconditions.checkArgument(playerIds.getFirst() != playerIds.getSecond());
this.id = id;
this.playerIds = FriendshipUtils.toOrderedTuple(playerIds);
this.createdAt = createdAt;
}
public BsonFriendship(Tuple2<UUID, UUID> playerIds, Instant createdAt) {
this(ObjectId.get(), playerIds, createdAt);
}
}

View file

@ -0,0 +1,27 @@
package de.kentoj.scrow.bukkit.friends.friendship;
import de.kentoj.scrow.bukkit.services.friends.Friendship;
import de.kentoj.scrow.bukkit.util.pair.Tuple2;
import org.jetbrains.annotations.NotNull;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.time.Instant;
import java.util.UUID;
public interface FriendshipRepository {
Flux<@NotNull Friendship> getFriendships(UUID playerId);
Mono<@NotNull Friendship> getFriendship(Tuple2<UUID, UUID> playerIds);
/**
* @return True if friendship saved, false if friendship already exists
*/
Mono<@NotNull Boolean> saveFriendship(Tuple2<UUID, UUID> playerIds, Instant createdAt);
/**
* @return True if friendship deleted, false if none found
*/
Mono<@NotNull Boolean> deleteFriendship(Tuple2<UUID, UUID> playerIds);
}

View file

@ -0,0 +1,22 @@
package de.kentoj.scrow.bukkit.friends.friendship;
import de.kentoj.scrow.bukkit.util.pair.Tuple2;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import java.util.UUID;
@NoArgsConstructor(access = AccessLevel.PRIVATE)
class FriendshipUtils {
/**
* ensures constant order
* @return an ordered tuple
*/
public static Tuple2<UUID, UUID> toOrderedTuple(Tuple2<UUID, UUID> playerIds) {
if (playerIds.getFirst().compareTo(playerIds.getSecond()) < 0)
return new Tuple2<>(playerIds.getFirst(), playerIds.getSecond());
else
return new Tuple2<>(playerIds.getSecond(), playerIds.getFirst());
}
}

View file

@ -0,0 +1,86 @@
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.services.friends.Friendship;
import de.kentoj.scrow.bukkit.util.pair.Tuple2;
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 MongoFriendshipRepository implements FriendshipRepository {
private static final String COLLECTION_NAME = "friendships";
private final MongoDatabase database;
public MongoFriendshipRepository(MongoDatabase database) {
this.database = database;
database.createCollection(COLLECTION_NAME);
collection().createIndex(
Indexes.compoundIndex(
Indexes.ascending("playerIds.first"),
Indexes.ascending("playerIds.second")
),
new IndexOptions().unique(true)
);
}
@Override
public Flux<@NotNull Friendship> getFriendships(UUID playerId) {
return Flux.from(collection()
.find(Filters.or(
Filters.eq("playerIds.first", playerId),
Filters.eq("playerIds.second", playerId)
)));
}
@Override
public Mono<@NotNull Friendship> getFriendship(Tuple2<UUID, UUID> playerIds) {
playerIds = FriendshipUtils.toOrderedTuple(playerIds);
return Mono.from(collection()
.find(Filters.and(
Filters.eq("playerIds.first", playerIds.getFirst()),
Filters.eq("playerIds.second", playerIds.getSecond())
)));
}
@Override
public Mono<@NotNull Boolean> saveFriendship(Tuple2<UUID, UUID> playerIds, Instant createdAt) {
var friendship = new BsonFriendship(playerIds, createdAt);
return Mono.from(collection()
.insertOne(friendship)
)
.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 Mono<@NotNull Boolean> deleteFriendship(Tuple2<UUID, UUID> playerIds) {
playerIds = FriendshipUtils.toOrderedTuple(playerIds);
return Mono.from(collection()
.deleteOne(Filters.and(
Filters.eq("playerIds.first", playerIds.getFirst()),
Filters.eq("playerIds.second", playerIds.getSecond())
)))
.map(res -> res.getDeletedCount() > 0);
}
private MongoCollection<BsonFriendship> collection() {
return database.getCollection(COLLECTION_NAME, BsonFriendship.class);
}
}

View file

@ -0,0 +1,37 @@
package de.kentoj.scrow.bukkit.friends.request;
import com.google.common.base.Preconditions;
import de.kentoj.scrow.bukkit.services.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);
}
}

View file

@ -0,0 +1,28 @@
package de.kentoj.scrow.bukkit.friends.request;
import de.kentoj.scrow.bukkit.services.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 interface FriendRequestRepository {
Flux<@NotNull FriendRequest> getIncomingFriendRequests(UUID playerId);
Flux<@NotNull FriendRequest> getOutgoingFriendRequests(UUID playerId);
Mono<@NotNull FriendRequest> getFriendRequest(UUID from, UUID to);
/**
* @return True if request saved, false if already existing request found.
*/
Mono<@NotNull Boolean> saveFriendRequest(UUID from, UUID to, Instant createdAt);
/**
* @return True if request deleted, false if none found.
*/
Mono<@NotNull Boolean> deleteFriendRequest(UUID from, UUID to);
}

View file

@ -0,0 +1,85 @@
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.services.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);
}
}

View file

@ -0,0 +1,5 @@
name: "CoreBukkit"
version: "1.0"
main: "de.kentoj.scrow.bukkit.CoreImplPlugin"
api-version: "1.1"
author: "Kento2 <kento@placeq.com>"