diff --git a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/api/repositories/WhitelistRepository.java b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/api/repositories/WhitelistRepository.java index 81aea86..cad137e 100644 --- a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/api/repositories/WhitelistRepository.java +++ b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/api/repositories/WhitelistRepository.java @@ -19,7 +19,7 @@ public class WhitelistRepository extends HttpRepository { String lastname, List strikes ) { - public record Strike(int at, int weight) { + public record Strike(long at, int weight) { } } diff --git a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/tooling/strike/Strike.java b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/tooling/strike/Strike.java deleted file mode 100644 index 59e5010..0000000 --- a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/tooling/strike/Strike.java +++ /dev/null @@ -1,21 +0,0 @@ -package eu.mhsl.craftattack.spawn.craftattack.appliances.tooling.strike; - -import eu.mhsl.craftattack.spawn.core.appliance.Appliance; - -import java.time.Duration; -import java.util.Map; - -public class Strike extends Appliance { - public Strike() { - super("strike"); - } - - private final Map strikePunishmentMap = Map.of( - 1, Duration.ofHours(1), - 2, Duration.ofHours(24), - 3, Duration.ofDays(3), - 4, Duration.ofDays(7) - ); - - -} diff --git a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/tooling/strikes/Strikes.java b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/tooling/strikes/Strikes.java new file mode 100644 index 0000000..b52ba90 --- /dev/null +++ b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/tooling/strikes/Strikes.java @@ -0,0 +1,48 @@ +package eu.mhsl.craftattack.spawn.craftattack.appliances.tooling.strikes; + +import eu.mhsl.craftattack.spawn.core.appliance.Appliance; +import eu.mhsl.craftattack.spawn.craftattack.api.repositories.WhitelistRepository; +import org.checkerframework.checker.nullness.qual.Nullable; + +import java.time.Duration; +import java.time.Instant; +import java.util.List; +import java.util.Map; + +public class Strikes extends Appliance { + public Strikes() { + super("strike"); + } + + private static final BanInfo falseInfo = new BanInfo(false, null, false); + public record BanInfo(boolean isBanned, @Nullable Instant bannedUntil, boolean isPermanent) { + } + + private final Map strikePunishmentMap = Map.of( + 1, Duration.ofHours(1), + 2, Duration.ofHours(24), + 3, Duration.ofDays(3), + 4, Duration.ofDays(7) + ); + + + public BanInfo isBanned(List strikes) { + if (strikes.isEmpty()) return falseInfo; + + int strikeCount = strikes.stream().mapToInt(WhitelistRepository.UserData.Strike::weight).sum(); + if (strikeCount < 1) return falseInfo; + if (strikeCount > this.strikePunishmentMap.size()) return new BanInfo(true, null, true); + + Instant lastPunishment = strikes.stream() + .map(strike -> Instant.ofEpochMilli(strike.at())) + .max(Instant::compareTo) + .orElse(Instant.EPOCH); + + Duration duration = this.strikePunishmentMap.get(strikeCount); + Instant bannedUntil = lastPunishment.plus(duration); + + boolean stillBanned = bannedUntil.isAfter(Instant.now()); + + return new BanInfo(stillBanned, bannedUntil, false); + } +} diff --git a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/tooling/whitelist/Whitelist.java b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/tooling/whitelist/Whitelist.java index 0e55b0a..0e5d690 100644 --- a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/tooling/whitelist/Whitelist.java +++ b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/tooling/whitelist/Whitelist.java @@ -8,21 +8,18 @@ import eu.mhsl.craftattack.spawn.core.appliance.Appliance; import eu.mhsl.craftattack.spawn.core.api.HttpStatus; import eu.mhsl.craftattack.spawn.core.util.server.Floodgate; 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.tooling.strikes.Strikes; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.Listener; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.time.Instant; -import java.time.ZoneOffset; +import javax.inject.Provider; +import java.time.ZoneId; +import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; -import java.time.temporal.ChronoUnit; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.UUID; +import java.util.*; import java.util.logging.Level; public class Whitelist extends Appliance { @@ -47,7 +44,6 @@ public class Whitelist extends Appliance { player.getUniqueId() ); } - this.queryAppliance(Outlawed.class).updateForcedStatus(player, this.timestampRelevant(0L)); // TODO String purePlayerName = Floodgate.isBedrock(player) ? Floodgate.getBedrockPlayer(player).getUsername() @@ -73,17 +69,25 @@ public class Whitelist extends Appliance { this.userData.put(uuid, user); Main.logger().info(String.format("got userdata %s", user.toString())); - if(this.timestampRelevant(0L)) { //TODO - Instant bannedDate = new Date(0 * 1000L) // TODO - .toInstant() - .plus(1, ChronoUnit.HOURS); + Strikes.BanInfo banInfo = Main.instance().getAppliance(Strikes.class).isBanned(user.strikes()); + Main.logger().info(String.format("got baninfo %s", banInfo.toString())); - DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("dd.MM.yyyy").withZone(ZoneOffset.UTC); - DateTimeFormatter timeFormat = DateTimeFormatter.ofPattern("HH:mm").withZone(ZoneOffset.UTC); + if (banInfo.isBanned()) { + Provider zoned = () -> { + Objects.requireNonNull(banInfo.bannedUntil(), "Cannot get zoned date time from null"); + return banInfo.bannedUntil().atZone(ZoneId.of("Europe/Berlin")); + }; + + DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("dd.MM.yyyy"); + DateTimeFormatter timeFormat = DateTimeFormatter.ofPattern("HH:mm"); + + String unbanText = banInfo.bannedUntil() != null + ? String.format("Dein Bann läuft am %s um %s ab!", dateFormat.format(zoned.get()), timeFormat.format(zoned.get())) + : "Bandauer ist unbekannt."; throw new DisconnectInfo.Throwable( "Du wurdest vom Server gebannt.", - String.format("Dein Bann läuft am %s um %s ab!", dateFormat.format(bannedDate), timeFormat.format(bannedDate)), + banInfo.isPermanent() ? "Dein Bann läuft nicht ab!" : unbanText, "Wende dich an einen Admin für weitere Informationen.", uuid ); @@ -94,18 +98,13 @@ public class Whitelist extends Appliance { Main.instance().getLogger().log(Level.SEVERE, e, e::getMessage); throw new DisconnectInfo.Throwable( "Interner Serverfehler", - "Deine Anmeldedaten konnten nicht abgerufen/ überprüft werden.", + "Deine Anmeldedaten konnten nicht abgerufen/überprüft werden.", "Versuche es später erneut oder kontaktiere einen Admin!", uuid ); } } - private boolean timestampRelevant(Long timestamp) { - if(timestamp == null) return false; - return timestamp > System.currentTimeMillis() / 1000L; - } - private WhitelistRepository.UserData fetchUserData(UUID uuid) throws DisconnectInfo.Throwable { ReqResp response = this.queryRepository(WhitelistRepository.class).getUserData(uuid);