api header support, team api integration

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

View File

@ -3,4 +3,5 @@ dependencies {
compileOnly 'io.papermc.paper:paper-api:1.21.1-R0.1-SNAPSHOT' compileOnly 'io.papermc.paper:paper-api:1.21.1-R0.1-SNAPSHOT'
compileOnly 'org.geysermc.floodgate:api:2.2.2-SNAPSHOT' compileOnly 'org.geysermc.floodgate:api:2.2.2-SNAPSHOT'
implementation 'org.apache.httpcomponents:httpclient:4.5.14'
} }

View File

@ -1,4 +1,4 @@
package eu.mhsl.craftattack.spawn.core.util.api; package eu.mhsl.craftattack.spawn.common.api;
import eu.mhsl.craftattack.spawn.core.config.Configuration; import eu.mhsl.craftattack.spawn.core.config.Configuration;
import org.apache.http.client.utils.URIBuilder; import org.apache.http.client.utils.URIBuilder;
@ -8,7 +8,7 @@ import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.util.Objects; import java.util.Objects;
public class WebsiteApiUtil { public class CraftAttackApi {
private final static ConfigurationSection apiConfig = Objects.requireNonNull(Configuration.cfg.getConfigurationSection("api")); private final static ConfigurationSection apiConfig = Objects.requireNonNull(Configuration.cfg.getConfigurationSection("api"));
public final static String basePath = apiConfig.getString("baseurl"); public final static String basePath = apiConfig.getString("baseurl");
public final static String apiSecret = apiConfig.getString("secret"); public final static String apiSecret = apiConfig.getString("secret");

View File

@ -1,8 +1,8 @@
package eu.mhsl.craftattack.spawn.core.api.client.repositories; package eu.mhsl.craftattack.spawn.common.api.repositories;
import eu.mhsl.craftattack.spawn.core.api.client.HttpRepository; import eu.mhsl.craftattack.spawn.core.api.client.HttpRepository;
import eu.mhsl.craftattack.spawn.core.api.client.ReqResp; import eu.mhsl.craftattack.spawn.core.api.client.ReqResp;
import eu.mhsl.craftattack.spawn.core.util.api.WebsiteApiUtil; import eu.mhsl.craftattack.spawn.common.api.CraftAttackApi;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@ -11,7 +11,7 @@ import java.util.UUID;
public class ReportRepository extends HttpRepository { public class ReportRepository extends HttpRepository {
public ReportRepository() { public ReportRepository() {
super(WebsiteApiUtil.getBaseUri(), WebsiteApiUtil::withAuthorizationSecret); super(CraftAttackApi.getBaseUri(), new RequestModifier(CraftAttackApi::withAuthorizationSecret, null));
} }
public record ReportCreationInfo(@NotNull UUID reporter, @Nullable UUID reported, String reason) { public record ReportCreationInfo(@NotNull UUID reporter, @Nullable UUID reported, String reason) {

View File

@ -2,7 +2,7 @@ package eu.mhsl.craftattack.spawn.common.appliances.metaGameplay.report;
import eu.mhsl.craftattack.spawn.core.Main; import eu.mhsl.craftattack.spawn.core.Main;
import eu.mhsl.craftattack.spawn.core.api.client.ReqResp; import eu.mhsl.craftattack.spawn.core.api.client.ReqResp;
import eu.mhsl.craftattack.spawn.core.api.client.repositories.ReportRepository; import eu.mhsl.craftattack.spawn.common.api.repositories.ReportRepository;
import eu.mhsl.craftattack.spawn.core.appliance.Appliance; import eu.mhsl.craftattack.spawn.core.appliance.Appliance;
import eu.mhsl.craftattack.spawn.core.appliance.ApplianceCommand; import eu.mhsl.craftattack.spawn.core.appliance.ApplianceCommand;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;

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 class HttpStatus {
public static final int OK = 200; 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.HttpClient;
import java.net.http.HttpRequest; import java.net.http.HttpRequest;
import java.net.http.HttpResponse; import java.net.http.HttpResponse;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer; import java.util.function.Consumer;
@RepositoryLoader.Abstraction @RepositoryLoader.Abstraction
public abstract class HttpRepository extends Repository { 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) { 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); super(basePath);
this.baseUriBuilder = baseUriBuilder == null this.baseRequestModifier = baseRequestModifier == null
? uriBuilder -> { ? List.of()
} : List.of(baseRequestModifier);
: baseUriBuilder;
} }
protected <TInput, TOutput> ReqResp<TOutput> post(String command, TInput data, Class<TOutput> outputType) { 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) { private URI getUri(String command, Consumer<URIBuilder> parameters) {
try { try {
URIBuilder builder = new URIBuilder(this.basePath + "/" + command); 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); parameters.accept(builder);
return builder.build(); return builder.build();
} catch(URISyntaxException e) { } catch(URISyntaxException e) {
@ -67,14 +77,22 @@ public abstract class HttpRepository extends Repository {
} }
private HttpRequest.Builder getRequestBuilder(URI endpoint) { private HttpRequest.Builder getRequestBuilder(URI endpoint) {
return HttpRequest.newBuilder() HttpRequest.Builder builder = HttpRequest.newBuilder()
.uri(endpoint) .uri(endpoint)
.header("User-Agent", Main.instance().getServer().getBukkitVersion()) .header("User-Agent", Main.instance().getServer().getBukkitVersion())
.header("Content-Type", "application/json"); .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) { private <TResponse> ReqResp<TResponse> execute(HttpRequest request, Class<TResponse> clazz) {
ReqResp<String> rawResponse = this.sendHttp(request); 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)); 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; 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 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

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

View File

@ -1,4 +1,4 @@
package eu.mhsl.craftattack.spawn.core.util.api; package eu.mhsl.craftattack.spawn.craftattack.api;
import eu.mhsl.craftattack.spawn.core.config.Configuration; import eu.mhsl.craftattack.spawn.core.config.Configuration;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
@ -7,7 +7,7 @@ import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.util.Objects; import java.util.Objects;
public class EventApiUtil { public class EventServerApi {
private final static ConfigurationSection apiConfig = Objects.requireNonNull(Configuration.cfg.getConfigurationSection("event")); private final static ConfigurationSection apiConfig = Objects.requireNonNull(Configuration.cfg.getConfigurationSection("event"));
public final static String basePath = apiConfig.getString("api"); public final static String basePath = apiConfig.getString("api");

View File

@ -1,14 +1,14 @@
package eu.mhsl.craftattack.spawn.core.api.client.repositories; package eu.mhsl.craftattack.spawn.craftattack.api.repositories;
import eu.mhsl.craftattack.spawn.core.api.client.HttpRepository; import eu.mhsl.craftattack.spawn.core.api.client.HttpRepository;
import eu.mhsl.craftattack.spawn.core.api.client.ReqResp; import eu.mhsl.craftattack.spawn.core.api.client.ReqResp;
import eu.mhsl.craftattack.spawn.core.util.api.EventApiUtil; import eu.mhsl.craftattack.spawn.craftattack.api.EventServerApi;
import java.util.UUID; import java.util.UUID;
public class EventRepository extends HttpRepository { public class EventRepository extends HttpRepository {
public EventRepository() { public EventRepository() {
super(EventApiUtil.getBaseUri()); super(EventServerApi.getBaseUri());
} }
public record CreatedRoom(UUID uuid) { public record CreatedRoom(UUID uuid) {

View File

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

View File

@ -1,14 +1,14 @@
package eu.mhsl.craftattack.spawn.core.api.client.repositories; package eu.mhsl.craftattack.spawn.craftattack.api.repositories;
import eu.mhsl.craftattack.spawn.core.api.client.HttpRepository; import eu.mhsl.craftattack.spawn.core.api.client.HttpRepository;
import eu.mhsl.craftattack.spawn.core.api.client.ReqResp; import eu.mhsl.craftattack.spawn.core.api.client.ReqResp;
import eu.mhsl.craftattack.spawn.core.util.api.WebsiteApiUtil; import eu.mhsl.craftattack.spawn.common.api.CraftAttackApi;
import java.util.UUID; import java.util.UUID;
public class WhitelistRepository extends HttpRepository { public class WhitelistRepository extends HttpRepository {
public WhitelistRepository() { public WhitelistRepository() {
super(WebsiteApiUtil.getBaseUri(), WebsiteApiUtil::withAuthorizationSecret); super(CraftAttackApi.getBaseUri(), new RequestModifier(CraftAttackApi::withAuthorizationSecret, null));
} }
public record UserData( public record UserData(

View File

@ -2,14 +2,14 @@ package eu.mhsl.craftattack.spawn.craftattack.appliances.metaGameplay.event;
import eu.mhsl.craftattack.spawn.core.Main; import eu.mhsl.craftattack.spawn.core.Main;
import eu.mhsl.craftattack.spawn.core.api.client.ReqResp; import eu.mhsl.craftattack.spawn.core.api.client.ReqResp;
import eu.mhsl.craftattack.spawn.core.api.client.repositories.EventRepository; import eu.mhsl.craftattack.spawn.craftattack.api.repositories.EventRepository;
import eu.mhsl.craftattack.spawn.core.api.server.HttpServer; import eu.mhsl.craftattack.spawn.core.api.server.HttpServer;
import eu.mhsl.craftattack.spawn.core.appliance.Appliance; import eu.mhsl.craftattack.spawn.core.appliance.Appliance;
import eu.mhsl.craftattack.spawn.core.appliance.ApplianceCommand; import eu.mhsl.craftattack.spawn.core.appliance.ApplianceCommand;
import eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.customAdvancements.Advancements; import eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.customAdvancements.Advancements;
import eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.customAdvancements.CustomAdvancements; import eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.customAdvancements.CustomAdvancements;
import eu.mhsl.craftattack.spawn.core.util.IteratorUtil; import eu.mhsl.craftattack.spawn.core.util.IteratorUtil;
import eu.mhsl.craftattack.spawn.core.util.api.HttpStatus; import eu.mhsl.craftattack.spawn.core.api.HttpStatus;
import eu.mhsl.craftattack.spawn.core.util.entity.DisplayVillager; import eu.mhsl.craftattack.spawn.core.util.entity.DisplayVillager;
import eu.mhsl.craftattack.spawn.core.util.listener.DismissInventoryOpenFromHolder; import eu.mhsl.craftattack.spawn.core.util.listener.DismissInventoryOpenFromHolder;
import eu.mhsl.craftattack.spawn.core.util.listener.PlayerInteractAtEntityEventListener; import eu.mhsl.craftattack.spawn.core.util.listener.PlayerInteractAtEntityEventListener;

View File

@ -2,10 +2,10 @@ package eu.mhsl.craftattack.spawn.craftattack.appliances.metaGameplay.feedback;
import eu.mhsl.craftattack.spawn.core.Main; import eu.mhsl.craftattack.spawn.core.Main;
import eu.mhsl.craftattack.spawn.core.api.client.ReqResp; import eu.mhsl.craftattack.spawn.core.api.client.ReqResp;
import eu.mhsl.craftattack.spawn.core.api.client.repositories.FeedbackRepository; import eu.mhsl.craftattack.spawn.craftattack.api.repositories.FeedbackRepository;
import eu.mhsl.craftattack.spawn.core.appliance.Appliance; import eu.mhsl.craftattack.spawn.core.appliance.Appliance;
import eu.mhsl.craftattack.spawn.core.appliance.ApplianceCommand; import eu.mhsl.craftattack.spawn.core.appliance.ApplianceCommand;
import eu.mhsl.craftattack.spawn.core.util.api.HttpStatus; import eu.mhsl.craftattack.spawn.core.api.HttpStatus;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.ComponentBuilder; import net.kyori.adventure.text.ComponentBuilder;
import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.TextComponent;

View File

@ -2,10 +2,10 @@ package eu.mhsl.craftattack.spawn.craftattack.appliances.tooling.whitelist;
import eu.mhsl.craftattack.spawn.core.Main; import eu.mhsl.craftattack.spawn.core.Main;
import eu.mhsl.craftattack.spawn.core.api.client.ReqResp; import eu.mhsl.craftattack.spawn.core.api.client.ReqResp;
import eu.mhsl.craftattack.spawn.core.api.client.repositories.WhitelistRepository; import eu.mhsl.craftattack.spawn.craftattack.api.repositories.WhitelistRepository;
import eu.mhsl.craftattack.spawn.core.api.server.HttpServer; import eu.mhsl.craftattack.spawn.core.api.server.HttpServer;
import eu.mhsl.craftattack.spawn.core.appliance.Appliance; import eu.mhsl.craftattack.spawn.core.appliance.Appliance;
import eu.mhsl.craftattack.spawn.core.util.api.HttpStatus; import eu.mhsl.craftattack.spawn.core.api.HttpStatus;
import eu.mhsl.craftattack.spawn.core.util.server.Floodgate; import eu.mhsl.craftattack.spawn.core.util.server.Floodgate;
import eu.mhsl.craftattack.spawn.core.util.text.DisconnectInfo; import eu.mhsl.craftattack.spawn.core.util.text.DisconnectInfo;
import eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.outlawed.Outlawed; import eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.outlawed.Outlawed;

View File

@ -0,0 +1,28 @@
package eu.mhsl.craftattack.spawn.varo.api;
import eu.mhsl.craftattack.spawn.core.config.Configuration;
import org.bukkit.configuration.ConfigurationSection;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.http.HttpRequest;
import java.util.Objects;
public class VaroApi {
private final static ConfigurationSection apiConfig = Objects.requireNonNull(Configuration.cfg.getConfigurationSection("varoApi"));
public final static String basePath = apiConfig.getString("endpoint");
public final static String apiSecret = apiConfig.getString("auth");
public static URI getBaseUri() {
Objects.requireNonNull(basePath);
try {
return new URI(basePath);
} catch(URISyntaxException e) {
throw new RuntimeException(e);
}
}
public static void authorizationHeader(HttpRequest.Builder builder) {
builder.header("Authorization", apiSecret);
}
}

View File

@ -0,0 +1,36 @@
package eu.mhsl.craftattack.spawn.varo.api.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.varo.api.VaroApi;
import java.util.List;
import java.util.UUID;
public class TeamRepository extends HttpRepository {
public TeamRepository() {
super(VaroApi.getBaseUri(), new RequestModifier(null, VaroApi::authorizationHeader));
}
public record Team(
String name,
String color,
Object lastJoined,
Object strikeWeight,
List<User> users
) {
public record User(
UUID uuid,
boolean dead
) {}
}
public ReqResp<List<Team>> getTeams() {
var resp = this.get("team", Object.class);
System.out.println(resp.toString());
return resp
.convertToTypeToken(new TypeToken<List<Team>>() {}.getType())
.cast();
}
}

View File

@ -4,6 +4,7 @@ import eu.mhsl.craftattack.spawn.core.Main;
import eu.mhsl.craftattack.spawn.core.appliance.Appliance; import eu.mhsl.craftattack.spawn.core.appliance.Appliance;
import eu.mhsl.craftattack.spawn.core.util.text.DisconnectInfo; import eu.mhsl.craftattack.spawn.core.util.text.DisconnectInfo;
import eu.mhsl.craftattack.spawn.common.appliances.metaGameplay.displayName.DisplayName; import eu.mhsl.craftattack.spawn.common.appliances.metaGameplay.displayName.DisplayName;
import eu.mhsl.craftattack.spawn.varo.api.repositories.TeamRepository;
import eu.mhsl.craftattack.spawn.varo.appliances.metaGameplay.joinProtection.JoinProtection; import eu.mhsl.craftattack.spawn.varo.appliances.metaGameplay.joinProtection.JoinProtection;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
@ -18,19 +19,19 @@ import org.jetbrains.annotations.Nullable;
import java.util.*; import java.util.*;
public class Teams extends Appliance implements DisplayName.Prefixed, DisplayName.Colored { public class Teams extends Appliance implements DisplayName.Prefixed, DisplayName.Colored {
private Set<VaroTeam> teams = new HashSet<>() {{ private List<VaroTeam> teams = List.of();
this.add(new VaroTeam(
new HashSet<>() {{ public Teams() {
this.add(new VaroTeam.Member(UUID.fromString("3a0a699c-7f0c-319b-839c-ccc8cac8ae63"), false)); this.refreshTeamList();
this.add(new VaroTeam.Member(UUID.fromString("959ed433-14ea-38fe-918b-75b7d09466af"), true)); }
}},
"Die Admins",
"#0E0E0E"
));
}};
public void refreshTeamList() { public void refreshTeamList() {
this.teams = this.queryRepository(TeamRepository.class).getTeams().data().stream()
.map(team -> new VaroTeam(
team.users().stream().map(user -> new VaroTeam.Member(user.uuid(), user.dead())).toList(),
team.name(),
team.color()
)).toList();
} }
public boolean canLogin(UUID playerId) { public boolean canLogin(UUID playerId) {
@ -58,16 +59,14 @@ public class Teams extends Appliance implements DisplayName.Prefixed, DisplayNam
VaroTeam team = this.getTeamFromPlayer(joinedPlayer.getUniqueId()); VaroTeam team = this.getTeamFromPlayer(joinedPlayer.getUniqueId());
Bukkit.getScheduler().scheduleSyncDelayedTask( Bukkit.getScheduler().scheduleSyncDelayedTask(
Main.instance(), Main.instance(),
() -> { () -> team.members.stream()
team.members.stream() .filter(member -> !member.isDead)
.filter(member -> !member.isDead) .filter(member -> {
.filter(member -> { Player p = Bukkit.getPlayer(member.player.getUniqueId());
Player p = Bukkit.getPlayer(member.player.getUniqueId()); return p == null || !p.isOnline();
return p == null || !p.isOnline(); })
}) .findAny()
.findAny() .ifPresent(member -> team.kickTeam(disconnectInfo)),
.ifPresent(member -> team.kickTeam(disconnectInfo));
},
Ticks.TICKS_PER_SECOND * (JoinProtection.resistanceDuration / 2) Ticks.TICKS_PER_SECOND * (JoinProtection.resistanceDuration / 2)
); );
} }

View File

@ -5,8 +5,8 @@ import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Set;
import java.util.UUID; import java.util.UUID;
class VaroTeam { class VaroTeam {
@ -26,18 +26,18 @@ class VaroTeam {
} }
public boolean isFree(int countdownSeconds) { public boolean isFree(int countdownSeconds) {
return this.timestampSince < System.currentTimeMillis() - (countdownSeconds * 1000); return this.timestampSince < System.currentTimeMillis() - (countdownSeconds * 1000L);
} }
} }
public final Set<Member> members; public final List<Member> members;
public final UUID teamUuid; public final UUID teamUuid;
public final String name; public final String name;
public final String color; public final String color;
public JoinCountdown joinCountdown; public JoinCountdown joinCountdown;
public VaroTeam(Set<Member> members, String name, String color) { public VaroTeam(List<Member> members, String name, String color) {
this.teamUuid = UUID.randomUUID(); this.teamUuid = UUID.randomUUID();
this.members = members; this.members = members;
this.name = name; this.name = name;