api header support, team api integration

This commit is contained in:
2025-05-30 18:34:49 +02:00
parent 8093a4a644
commit 558e6f84f1
19 changed files with 157 additions and 58 deletions

View File

@ -1,4 +1,4 @@
package eu.mhsl.craftattack.spawn.core.util.api;
package eu.mhsl.craftattack.spawn.core.api;
public class HttpStatus {
public static final int OK = 200;

View File

@ -10,23 +10,29 @@ import java.net.URISyntaxException;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
@RepositoryLoader.Abstraction
public abstract class HttpRepository extends Repository {
private final Consumer<URIBuilder> baseUriBuilder;
public record RequestModifier(
@Nullable Consumer<URIBuilder> uri,
@Nullable Consumer<HttpRequest.Builder> header
) {}
private final List<RequestModifier> baseRequestModifier;
public HttpRepository(URI basePath) {
this(basePath, null);
this(basePath, new RequestModifier(null, null));
}
public HttpRepository(URI basePath, @Nullable Consumer<URIBuilder> baseUriBuilder) {
public HttpRepository(URI basePath, RequestModifier... baseRequestModifier) {
super(basePath);
this.baseUriBuilder = baseUriBuilder == null
? uriBuilder -> {
}
: baseUriBuilder;
this.baseRequestModifier = baseRequestModifier == null
? List.of()
: List.of(baseRequestModifier);
}
protected <TInput, TOutput> ReqResp<TOutput> post(String command, TInput data, Class<TOutput> outputType) {
@ -58,7 +64,11 @@ public abstract class HttpRepository extends Repository {
private URI getUri(String command, Consumer<URIBuilder> parameters) {
try {
URIBuilder builder = new URIBuilder(this.basePath + "/" + command);
this.baseUriBuilder.accept(builder);
this.baseRequestModifier.stream()
.map(requestModifier -> requestModifier.uri)
.filter(Objects::nonNull)
.forEach(modifier -> modifier.accept(builder));
parameters.accept(builder);
return builder.build();
} catch(URISyntaxException e) {
@ -67,14 +77,22 @@ public abstract class HttpRepository extends Repository {
}
private HttpRequest.Builder getRequestBuilder(URI endpoint) {
return HttpRequest.newBuilder()
HttpRequest.Builder builder = HttpRequest.newBuilder()
.uri(endpoint)
.header("User-Agent", Main.instance().getServer().getBukkitVersion())
.header("Content-Type", "application/json");
this.baseRequestModifier.stream()
.map(requestModifier -> requestModifier.header)
.filter(Objects::nonNull)
.forEach(modifier -> modifier.accept(builder));
return builder;
}
private <TResponse> ReqResp<TResponse> execute(HttpRequest request, Class<TResponse> clazz) {
ReqResp<String> rawResponse = this.sendHttp(request);
Main.logger().info(String.format("HTTP-Repository fired %s, response: %s", request, rawResponse));
return new ReqResp<>(rawResponse.status(), this.gson.fromJson(rawResponse.data(), clazz));
}

View File

@ -1,4 +1,16 @@
package eu.mhsl.craftattack.spawn.core.api.client;
import com.google.gson.Gson;
import java.lang.reflect.Type;
public record ReqResp<TData>(int status, TData data) {
public ReqResp<?> convertToTypeToken(Type type) {
var gson = new Gson();
return new ReqResp<>(this.status, gson.fromJson(gson.toJson(this.data), type));
}
@SuppressWarnings("unchecked")
public <T> T cast() {
return (T) this;
}
}

View File

@ -1,29 +0,0 @@
package eu.mhsl.craftattack.spawn.core.api.client.repositories;
import eu.mhsl.craftattack.spawn.core.api.client.HttpRepository;
import eu.mhsl.craftattack.spawn.core.api.client.ReqResp;
import eu.mhsl.craftattack.spawn.core.util.api.EventApiUtil;
import java.util.UUID;
public class EventRepository extends HttpRepository {
public EventRepository() {
super(EventApiUtil.getBaseUri());
}
public record CreatedRoom(UUID uuid) {
}
public record QueueRoom(UUID player, UUID room) {
public record Response(String error) {
}
}
public ReqResp<CreatedRoom> createSession() {
return this.post("room", null, CreatedRoom.class);
}
public ReqResp<QueueRoom.Response> queueRoom(QueueRoom request) {
return this.post("queueRoom", request, QueueRoom.Response.class);
}
}

View File

@ -1,27 +0,0 @@
package eu.mhsl.craftattack.spawn.core.api.client.repositories;
import com.google.common.reflect.TypeToken;
import eu.mhsl.craftattack.spawn.core.api.client.HttpRepository;
import eu.mhsl.craftattack.spawn.core.api.client.ReqResp;
import eu.mhsl.craftattack.spawn.core.util.api.WebsiteApiUtil;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
import java.util.UUID;
public class FeedbackRepository extends HttpRepository {
public FeedbackRepository() {
super(WebsiteApiUtil.getBaseUri(), WebsiteApiUtil::withAuthorizationSecret);
}
public record Request(String event, List<UUID> users) {
}
public ReqResp<Map<UUID, String>> createFeedbackUrls(Request data) {
final Type responseType = new TypeToken<Map<UUID, String>>() {
}.getType();
ReqResp<Object> rawData = this.post("feedback", data, Object.class);
return new ReqResp<>(rawData.status(), this.gson.fromJson(this.gson.toJson(rawData.data()), responseType));
}
}

View File

@ -1,57 +0,0 @@
package eu.mhsl.craftattack.spawn.core.api.client.repositories;
import eu.mhsl.craftattack.spawn.core.api.client.HttpRepository;
import eu.mhsl.craftattack.spawn.core.api.client.ReqResp;
import eu.mhsl.craftattack.spawn.core.util.api.WebsiteApiUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.UUID;
public class ReportRepository extends HttpRepository {
public ReportRepository() {
super(WebsiteApiUtil.getBaseUri(), WebsiteApiUtil::withAuthorizationSecret);
}
public record ReportCreationInfo(@NotNull UUID reporter, @Nullable UUID reported, String reason) {
}
public record ReportUrl(@NotNull String url) {
}
public record PlayerReports(
List<Report> from_self,
Object to_self
) {
public record Report(
@Nullable Reporter reported,
@NotNull String subject,
boolean draft,
@NotNull String status,
@NotNull String url
) {
public record Reporter(
@NotNull String username,
@NotNull String uuid
) {
}
}
}
public ReqResp<PlayerReports> queryReports(UUID player) {
return this.get(
"report",
(parameters) -> parameters.addParameter("uuid", player.toString()),
PlayerReports.class
);
}
public ReqResp<ReportUrl> createReport(ReportCreationInfo data) {
return this.post(
"report",
data,
ReportUrl.class
);
}
}

View File

@ -1,31 +0,0 @@
package eu.mhsl.craftattack.spawn.core.api.client.repositories;
import eu.mhsl.craftattack.spawn.core.api.client.HttpRepository;
import eu.mhsl.craftattack.spawn.core.api.client.ReqResp;
import eu.mhsl.craftattack.spawn.core.util.api.WebsiteApiUtil;
import java.util.UUID;
public class WhitelistRepository extends HttpRepository {
public WhitelistRepository() {
super(WebsiteApiUtil.getBaseUri(), WebsiteApiUtil::withAuthorizationSecret);
}
public record UserData(
UUID uuid,
String username,
String firstname,
String lastname,
Long banned_until,
Long outlawed_until
) {
}
public ReqResp<UserData> getUserData(UUID userId) {
return this.get(
"user",
parameters -> parameters.addParameter("uuid", userId.toString()),
UserData.class
);
}
}

View File

@ -1,23 +0,0 @@
package eu.mhsl.craftattack.spawn.core.util.api;
import eu.mhsl.craftattack.spawn.core.config.Configuration;
import org.bukkit.configuration.ConfigurationSection;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Objects;
public class EventApiUtil {
private final static ConfigurationSection apiConfig = Objects.requireNonNull(Configuration.cfg.getConfigurationSection("event"));
public final static String basePath = apiConfig.getString("api");
public static URI getBaseUri() {
Objects.requireNonNull(basePath);
try {
return new URI(basePath);
} catch(URISyntaxException e) {
throw new RuntimeException(e);
}
}
}

View File

@ -1,28 +0,0 @@
package eu.mhsl.craftattack.spawn.core.util.api;
import eu.mhsl.craftattack.spawn.core.config.Configuration;
import org.apache.http.client.utils.URIBuilder;
import org.bukkit.configuration.ConfigurationSection;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Objects;
public class WebsiteApiUtil {
private final static ConfigurationSection apiConfig = Objects.requireNonNull(Configuration.cfg.getConfigurationSection("api"));
public final static String basePath = apiConfig.getString("baseurl");
public final static String apiSecret = apiConfig.getString("secret");
public static URI getBaseUri() {
Objects.requireNonNull(basePath);
try {
return new URI(basePath);
} catch(URISyntaxException e) {
throw new RuntimeException(e);
}
}
public static void withAuthorizationSecret(URIBuilder builder) {
builder.addParameter("secret", apiSecret);
}
}

View File

@ -77,3 +77,7 @@ shrinkingBorder:
minimumSize: 10
shrinkPerDay: 10
shrinkTime: 03:00
varoApi:
endpoint: "https://mhsl.eu/varo/api"
auth: "Basic xxx"