.
This commit is contained in:
parent
07fa0efab7
commit
145a3116bc
29 changed files with 721 additions and 62 deletions
29
core-api/src/main/java/de/kentoj/scrow/ScrowAPI.java
Normal file
29
core-api/src/main/java/de/kentoj/scrow/ScrowAPI.java
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
package de.kentoj.scrow;
|
||||
|
||||
import com.mongodb.reactivestreams.client.MongoDatabase;
|
||||
import de.kentoj.scrow.services.EconomyService;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class ScrowAPI {
|
||||
|
||||
@Getter
|
||||
private static @Nullable MongoDatabase database;
|
||||
@Getter
|
||||
private static EconomyService economyService;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static void setDatabase(@Nullable MongoDatabase database) {
|
||||
ScrowAPI.database = database;
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static void setEconomyService(EconomyService economyService) {
|
||||
ScrowAPI.economyService = economyService;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package de.kentoj.scrow.provider;
|
||||
|
||||
public class MissingServiceFieldException extends RuntimeException {
|
||||
public MissingServiceFieldException(Class<?> apiClass, Class<?> serviceClass) {
|
||||
super("missing static field of type " + serviceClass + " annotated with " + ServiceField.class.getCanonicalName() + " in " + apiClass.getCanonicalName());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package de.kentoj.scrow.provider;
|
||||
|
||||
import de.kentoj.scrow.provider.provider.ServiceProvider;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public class RegisteredService<T> {
|
||||
private final Class<T> serviceClass;
|
||||
private final ServiceProvider<T> serviceProvider;
|
||||
private final Set<Class<?>> requiredServices;
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package de.kentoj.scrow.provider;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface ServiceField {}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
package de.kentoj.scrow.provider;
|
||||
|
||||
import de.kentoj.scrow.provider.provider.ServiceProvider;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.lang.reflect.AccessFlag;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@RequiredArgsConstructor
|
||||
public class ServiceRegistry {
|
||||
|
||||
private final Set<RegisteredService<?>> registeredServices = new HashSet<>();
|
||||
|
||||
public <T> void provideService(
|
||||
Class<T> serviceInterfaceClass,
|
||||
ServiceProvider<T> serviceProvider,
|
||||
Set<Class<?>> requiredServices
|
||||
) {
|
||||
registeredServices.add(new RegisteredService<>(serviceInterfaceClass, serviceProvider, requiredServices));
|
||||
}
|
||||
|
||||
public void load(Class<?> apiClass) {
|
||||
Arrays.stream(apiClass.getDeclaredFields())
|
||||
.filter(f -> f.accessFlags().contains(AccessFlag.STATIC))
|
||||
.filter(f -> f.isAnnotationPresent(ServiceField.class))
|
||||
.filter(f -> {
|
||||
try {
|
||||
f.setAccessible(true);
|
||||
return f.get(null) == null;
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
})
|
||||
.forEach(field -> loadServiceRecursively(apiClass, getService(field.getType())));
|
||||
}
|
||||
|
||||
public void loadServiceRecursively(Class<?> apiClass, RegisteredService<?> registeredService) {
|
||||
for (Class<?> serviceClass : registeredService.getRequiredServices()) {
|
||||
var sv = getService(serviceClass);
|
||||
loadServiceRecursively(apiClass, sv);
|
||||
}
|
||||
|
||||
var field = Arrays.stream(apiClass.getDeclaredFields())
|
||||
.filter(f -> f.accessFlags().contains(AccessFlag.STATIC))
|
||||
.filter(f -> f.isAnnotationPresent(ServiceField.class))
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new MissingServiceFieldException(apiClass, registeredService.getServiceClass()));
|
||||
try {
|
||||
if (field.get(null) != null) return;
|
||||
field.setAccessible(true);
|
||||
field.set(null, registeredService.getServiceProvider().get());
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public <T> RegisteredService<T> getService(Class<T> serviceClass) {
|
||||
return (RegisteredService<T>) registeredServices.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.filter(sv -> sv.getServiceClass() == serviceClass)
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new IllegalStateException("No registered-service for " + serviceClass.getCanonicalName() + " registered"));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package de.kentoj.scrow.provider.provider;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public abstract class AbstractServiceProvider<T> implements ServiceProvider<T> {
|
||||
|
||||
private final @Nullable T service = load();
|
||||
|
||||
abstract protected T load();
|
||||
|
||||
@Override
|
||||
public T get() {
|
||||
return service;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package de.kentoj.scrow.provider.provider;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class GenericServiceProvider<T> implements ServiceProvider<T> {
|
||||
|
||||
private final T service;
|
||||
|
||||
public GenericServiceProvider(T service) {
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
public GenericServiceProvider(Supplier<T> serviceSupplier) {
|
||||
this.service = serviceSupplier.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T get() {
|
||||
return service;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package de.kentoj.scrow.provider.provider;
|
||||
|
||||
public interface ServiceProvider<T> {
|
||||
|
||||
T get();
|
||||
|
||||
default void cleanup() {}
|
||||
}
|
||||
|
|
@ -7,21 +7,27 @@ import java.util.UUID;
|
|||
|
||||
public interface EconomyService {
|
||||
|
||||
/**
|
||||
* @throws IllegalArgumentException if amount < 0
|
||||
*/
|
||||
Mono<@NotNull Integer> getCoins(UUID playerId);
|
||||
|
||||
/**
|
||||
* @param playerId uuid of player
|
||||
* @throws IllegalArgumentException if amount < 0
|
||||
*/
|
||||
Mono<@NotNull Void> depositCoins(UUID playerId, int amount);
|
||||
|
||||
/**
|
||||
* @param playerId uuid of player
|
||||
* @return true on success, false on insufficient funds
|
||||
* @throws IllegalArgumentException if amount < 0
|
||||
*/
|
||||
Mono<@NotNull Boolean> tryWithdrawCoins(UUID playerId, int amount);
|
||||
|
||||
/**
|
||||
* @param playerId uuid of player
|
||||
* @throws IllegalArgumentException if amount < 0
|
||||
*/
|
||||
Mono<@NotNull Void> setCoins(UUID playerId, int amount);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
package de.kentoj.scrow.services.friends;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
|
||||
public interface FriendRequest {
|
||||
UUID getFrom();
|
||||
UUID getTo();
|
||||
Instant getCreatedAt();
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package de.kentoj.scrow.services.friends;
|
||||
|
||||
import de.kentoj.scrow.util.pair.Tuple2;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
|
||||
public interface Friendship {
|
||||
Tuple2<UUID, UUID> getPlayerIds();
|
||||
Instant getCreatedAt();
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package de.kentoj.scrow.util.pair;
|
||||
|
||||
import lombok.Value;
|
||||
|
||||
@Value
|
||||
public class Tuple2<A, B> {
|
||||
A first;
|
||||
B second;
|
||||
}
|
||||
10
core-api/src/main/java/de/kentoj/scrow/util/pair/Tuple3.java
Normal file
10
core-api/src/main/java/de/kentoj/scrow/util/pair/Tuple3.java
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
package de.kentoj.scrow.util.pair;
|
||||
|
||||
import lombok.Value;
|
||||
|
||||
@Value
|
||||
public class Tuple3<A, B, C> {
|
||||
A first;
|
||||
B second;
|
||||
C third;
|
||||
}
|
||||
11
core-api/src/main/java/de/kentoj/scrow/util/pair/Tuple4.java
Normal file
11
core-api/src/main/java/de/kentoj/scrow/util/pair/Tuple4.java
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
package de.kentoj.scrow.util.pair;
|
||||
|
||||
import lombok.Value;
|
||||
|
||||
@Value
|
||||
public class Tuple4<A, B, C, D> {
|
||||
A first;
|
||||
B second;
|
||||
C third;
|
||||
D fourth;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue