From 9067126f111a4273c089c95a861794e9c36bccda Mon Sep 17 00:00:00 2001 From: Flemmli97 Date: Wed, 4 Aug 2021 23:52:36 +0200 Subject: [PATCH] add deletion of banned player claims and option to delete inactive player data --- .../flemmli97/flan/claim/ClaimStorage.java | 3 +- .../github/flemmli97/flan/config/Config.java | 6 ++ .../flan/mixin/BannedEntryAccessor.java | 14 +++++ .../flan/player/OfflinePlayerData.java | 43 ++++++-------- .../flan/player/PlayerDataHandler.java | 59 +++++++++++++++++++ .../flemmli97/flan/player/TeleportUtils.java | 2 +- common/src/main/resources/flan.mixins.json | 3 +- .../io/github/flemmli97/flan/FlanFabric.java | 6 ++ .../io/github/flemmli97/flan/FlanForge.java | 1 + .../flan/forgeevent/ServerEvents.java | 6 ++ 10 files changed, 116 insertions(+), 27 deletions(-) create mode 100644 common/src/main/java/io/github/flemmli97/flan/mixin/BannedEntryAccessor.java create mode 100644 common/src/main/java/io/github/flemmli97/flan/player/PlayerDataHandler.java diff --git a/common/src/main/java/io/github/flemmli97/flan/claim/ClaimStorage.java b/common/src/main/java/io/github/flemmli97/flan/claim/ClaimStorage.java index 6c1e492..83c1fe8 100644 --- a/common/src/main/java/io/github/flemmli97/flan/claim/ClaimStorage.java +++ b/common/src/main/java/io/github/flemmli97/flan/claim/ClaimStorage.java @@ -18,6 +18,7 @@ import io.github.flemmli97.flan.player.EnumDisplayType; import io.github.flemmli97.flan.player.EnumEditMode; import io.github.flemmli97.flan.player.OfflinePlayerData; import io.github.flemmli97.flan.player.PlayerClaimData; +import io.github.flemmli97.flan.player.PlayerDataHandler; import it.unimi.dsi.fastutil.longs.Long2ObjectArrayMap; import net.minecraft.server.MinecraftServer; import net.minecraft.server.command.ServerCommandSource; @@ -68,7 +69,7 @@ public class ClaimStorage implements IPermissionStorage { public ClaimStorage(MinecraftServer server, ServerWorld world) { this.globalClaim = new GlobalClaim(world); this.read(server, world); - OfflinePlayerData.deleteUnusedClaims(server, this, world); + PlayerDataHandler.deleteUnusedClaims(server, this, world); } public UUID generateUUID() { diff --git a/common/src/main/java/io/github/flemmli97/flan/config/Config.java b/common/src/main/java/io/github/flemmli97/flan/config/Config.java index 1bb1dff..dd2783b 100644 --- a/common/src/main/java/io/github/flemmli97/flan/config/Config.java +++ b/common/src/main/java/io/github/flemmli97/flan/config/Config.java @@ -63,6 +63,8 @@ public class Config { public int inactivityTime = 30; public int inactivityBlocksMax = 2000; + public boolean deletePlayerFile = false; + public int bannedDeletionTime = 30; public boolean log; @@ -181,6 +183,8 @@ public class Config { this.dropTicks = ConfigHandler.fromJson(obj, "dropTicks", this.dropTicks); this.inactivityTime = ConfigHandler.fromJson(obj, "inactivityTimeDays", this.inactivityTime); this.inactivityBlocksMax = ConfigHandler.fromJson(obj, "inactivityBlocksMax", this.inactivityBlocksMax); + this.deletePlayerFile = ConfigHandler.fromJson(obj, "deletePlayerFile", this.deletePlayerFile); + this.bannedDeletionTime = ConfigHandler.fromJson(obj, "bannedDeletionTime", this.bannedDeletionTime); } catch (IOException e) { e.printStackTrace(); } @@ -240,6 +244,8 @@ public class Config { obj.addProperty("dropTicks", this.dropTicks); obj.addProperty("inactivityTimeDays", this.inactivityTime); obj.addProperty("inactivityBlocksMax", this.inactivityBlocksMax); + obj.addProperty("deletePlayerFile", this.deletePlayerFile); + obj.addProperty("bannedDeletionTime", this.bannedDeletionTime); try { FileWriter writer = new FileWriter(this.config); ConfigHandler.GSON.toJson(obj, writer); diff --git a/common/src/main/java/io/github/flemmli97/flan/mixin/BannedEntryAccessor.java b/common/src/main/java/io/github/flemmli97/flan/mixin/BannedEntryAccessor.java new file mode 100644 index 0000000..70ad0b1 --- /dev/null +++ b/common/src/main/java/io/github/flemmli97/flan/mixin/BannedEntryAccessor.java @@ -0,0 +1,14 @@ +package io.github.flemmli97.flan.mixin; + +import net.minecraft.server.BanEntry; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import java.util.Date; + +@Mixin(BanEntry.class) +public interface BannedEntryAccessor { + + @Accessor("creationDate") + Date getCreationDate(); +} diff --git a/common/src/main/java/io/github/flemmli97/flan/player/OfflinePlayerData.java b/common/src/main/java/io/github/flemmli97/flan/player/OfflinePlayerData.java index 00e8ffe..ff58141 100644 --- a/common/src/main/java/io/github/flemmli97/flan/player/OfflinePlayerData.java +++ b/common/src/main/java/io/github/flemmli97/flan/player/OfflinePlayerData.java @@ -3,11 +3,14 @@ package io.github.flemmli97.flan.player; import com.google.gson.JsonObject; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonWriter; +import com.mojang.authlib.GameProfile; import io.github.flemmli97.flan.Flan; import io.github.flemmli97.flan.api.data.IPlayerData; import io.github.flemmli97.flan.claim.Claim; import io.github.flemmli97.flan.claim.ClaimStorage; import io.github.flemmli97.flan.config.ConfigHandler; +import io.github.flemmli97.flan.mixin.BannedEntryAccessor; +import net.minecraft.server.BannedPlayerEntry; import net.minecraft.server.MinecraftServer; import net.minecraft.server.world.ServerWorld; @@ -16,9 +19,8 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.time.LocalDateTime; +import java.time.ZoneId; import java.util.Collection; -import java.util.HashMap; -import java.util.Map; import java.util.UUID; public class OfflinePlayerData implements IPlayerData { @@ -110,30 +112,23 @@ public class OfflinePlayerData implements IPlayerData { } } - public static Map collectAllPlayerData(MinecraftServer server) { - Path dir = ConfigHandler.getPlayerSavePath(server); - Map playerDatas = new HashMap<>(); - if (Files.exists(dir)) { - for (String name : dir.toFile().list((d, name) -> name.endsWith(".json"))) { - UUID uuid = UUID.fromString(name.replace(".json", "")); - playerDatas.put(uuid, new OfflinePlayerData(server, uuid)); - } + public boolean isExpired(LocalDateTime now) { + GameProfile prof = this.server.getUserCache().getByUuid(this.owner); + BannedPlayerEntry entry = prof != null ? this.server.getPlayerManager().getUserBanList().get(prof) : null; + boolean banned = entry != null && entry.getExpiryDate() == null; + if (banned) { + LocalDateTime bannedTime = LocalDateTime.ofInstant(((BannedEntryAccessor) entry).getCreationDate().toInstant(), ZoneId.systemDefault()); + return ConfigHandler.config.bannedDeletionTime != -1 && now.isAfter(bannedTime.plusDays(ConfigHandler.config.bannedDeletionTime)); } - return playerDatas; + return ConfigHandler.config.inactivityTime != -1 && now.isAfter(this.lastOnline.plusDays(ConfigHandler.config.inactivityTime)) && this.claimBlocks + this.additionalClaimBlocks < ConfigHandler.config.inactivityBlocksMax; } - public static void deleteUnusedClaims(MinecraftServer server, ClaimStorage storage, ServerWorld world) { - if (ConfigHandler.config.inactivityTime == -1) - return; - Map playerData = collectAllPlayerData(server); - LocalDateTime now = LocalDateTime.now(); - playerData.forEach((uuid, data) -> { - if (now.isAfter(data.lastOnline.plusDays(ConfigHandler.config.inactivityTime)) - && data.claimBlocks + data.additionalClaimBlocks < ConfigHandler.config.inactivityBlocksMax) { - Flan.log("{} Deleting all claims for inactive player {} last seen {}", world.getRegistryKey(), data.owner, data.lastOnline); - storage.allClaimsFromPlayer(data.owner) - .forEach(claim -> storage.deleteClaim(claim, true, EnumEditMode.DEFAULT, world)); - } - }); + public void deleteFile() { + try { + Files.delete(this.save); + } catch (IOException e) { + Flan.error("Couldn't delete file player data of {}", this.owner); + e.printStackTrace(); + } } } diff --git a/common/src/main/java/io/github/flemmli97/flan/player/PlayerDataHandler.java b/common/src/main/java/io/github/flemmli97/flan/player/PlayerDataHandler.java new file mode 100644 index 0000000..727af1d --- /dev/null +++ b/common/src/main/java/io/github/flemmli97/flan/player/PlayerDataHandler.java @@ -0,0 +1,59 @@ +package io.github.flemmli97.flan.player; + +import io.github.flemmli97.flan.Flan; +import io.github.flemmli97.flan.claim.ClaimStorage; +import io.github.flemmli97.flan.config.ConfigHandler; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.world.ServerWorld; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.time.LocalDateTime; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +public class PlayerDataHandler { + + private static Map inActivePlayerData = null; + + public static void initInactivePlayers(MinecraftServer server) { + inActivePlayerData = new HashMap<>(); + LocalDateTime now = LocalDateTime.now(); + Map playerData = collectAllPlayerData(server); + playerData.forEach((uuid, data) -> { + if (data.isExpired(now)) + inActivePlayerData.put(uuid, data); + }); + Flan.log("Collected player data to delete {}", inActivePlayerData); + } + + public static Map collectAllPlayerData(MinecraftServer server) { + Path dir = ConfigHandler.getPlayerSavePath(server); + Map playerDatas = new HashMap<>(); + if (Files.exists(dir)) { + for (String name : dir.toFile().list((d, name) -> name.endsWith(".json"))) { + UUID uuid = UUID.fromString(name.replace(".json", "")); + playerDatas.put(uuid, new OfflinePlayerData(server, uuid)); + } + } + return playerDatas; + } + + public static void deleteUnusedClaims(MinecraftServer server, ClaimStorage storage, ServerWorld world) { + if (inActivePlayerData == null) + initInactivePlayers(server); + inActivePlayerData.forEach((uuid, data) -> { + Flan.log("{} Deleting all claims for inactive player {} last seen {}", world.getRegistryKey(), data.owner, data.lastOnline); + storage.allClaimsFromPlayer(data.owner) + .forEach(claim -> storage.deleteClaim(claim, true, EnumEditMode.DEFAULT, world)); + }); + } + + public static void deleteInactivePlayerData(MinecraftServer server) { + if (ConfigHandler.config.deletePlayerFile && inActivePlayerData != null) { + inActivePlayerData.forEach((uuid, data) -> data.deleteFile()); + inActivePlayerData = null; + } + } +} diff --git a/common/src/main/java/io/github/flemmli97/flan/player/TeleportUtils.java b/common/src/main/java/io/github/flemmli97/flan/player/TeleportUtils.java index f80b3ac..9cb411d 100644 --- a/common/src/main/java/io/github/flemmli97/flan/player/TeleportUtils.java +++ b/common/src/main/java/io/github/flemmli97/flan/player/TeleportUtils.java @@ -31,7 +31,7 @@ public class TeleportUtils { Vec3d dest = new Vec3d(ret.x, y + 1, ret.z); if (player.world.getBlockCollisions(player, player.getBoundingBox().offset(dest.subtract(player.getPos())), (state, p) -> true).allMatch(VoxelShape::isEmpty)) return dest; - return new Vec3d(rounded.getX() + 0.5, y+1, rounded.getZ() + 0.5); + return new Vec3d(rounded.getX() + 0.5, y + 1, rounded.getZ() + 0.5); } int[] newDim = claim.getDimensions(); switch (pos.getLeft()) { diff --git a/common/src/main/resources/flan.mixins.json b/common/src/main/resources/flan.mixins.json index 9a2d940..2d4a185 100644 --- a/common/src/main/resources/flan.mixins.json +++ b/common/src/main/resources/flan.mixins.json @@ -22,7 +22,8 @@ "IItemAccessor", "IHungerAccessor", "FrostWalkerMixin", - "LightningFireEntityMixin" + "LightningFireEntityMixin", + "BannedEntryAccessor" ], "server": [ ], diff --git a/fabric/src/main/java/io/github/flemmli97/flan/FlanFabric.java b/fabric/src/main/java/io/github/flemmli97/flan/FlanFabric.java index e1a1176..6a80e7e 100644 --- a/fabric/src/main/java/io/github/flemmli97/flan/FlanFabric.java +++ b/fabric/src/main/java/io/github/flemmli97/flan/FlanFabric.java @@ -7,6 +7,7 @@ import io.github.flemmli97.flan.event.BlockInteractEvents; import io.github.flemmli97.flan.event.EntityInteractEvents; import io.github.flemmli97.flan.event.ItemInteractEvents; import io.github.flemmli97.flan.integration.playerability.PlayerAbilityEvents; +import io.github.flemmli97.flan.player.PlayerDataHandler; import io.github.flemmli97.flan.scoreboard.ClaimCriterias; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.command.v1.CommandRegistrationCallback; @@ -29,6 +30,7 @@ public class FlanFabric implements ModInitializer { AttackEntityCallback.EVENT.register(EntityInteractEvents::attackEntity); UseItemCallback.EVENT.register(ItemInteractEvents::useItem); ServerLifecycleEvents.SERVER_STARTING.register(FlanFabric::serverLoad); + ServerLifecycleEvents.SERVER_STARTED.register(FlanFabric::serverFinishLoad); CommandRegistrationCallback.EVENT.register(CommandClaim::register); @@ -46,4 +48,8 @@ public class FlanFabric implements ModInitializer { ObjectToPermissionMap.reload(server); Flan.lockRegistry(server); } + + public static void serverFinishLoad(MinecraftServer server) { + PlayerDataHandler.deleteInactivePlayerData(server); + } } diff --git a/forge/src/main/java/io/github/flemmli97/flan/FlanForge.java b/forge/src/main/java/io/github/flemmli97/flan/FlanForge.java index dc96585..d3a4977 100644 --- a/forge/src/main/java/io/github/flemmli97/flan/FlanForge.java +++ b/forge/src/main/java/io/github/flemmli97/flan/FlanForge.java @@ -41,6 +41,7 @@ public class FlanForge { forge.addListener(ServerEvents::commands); forge.addListener(ServerEvents::savePlayer); forge.addListener(ServerEvents::readPlayer); + forge.addListener(ServerEvents::serverFinishLoad); ClaimCriterias.init(); } diff --git a/forge/src/main/java/io/github/flemmli97/flan/forgeevent/ServerEvents.java b/forge/src/main/java/io/github/flemmli97/flan/forgeevent/ServerEvents.java index a85db87..00523be 100644 --- a/forge/src/main/java/io/github/flemmli97/flan/forgeevent/ServerEvents.java +++ b/forge/src/main/java/io/github/flemmli97/flan/forgeevent/ServerEvents.java @@ -5,9 +5,11 @@ import io.github.flemmli97.flan.api.permission.ObjectToPermissionMap; import io.github.flemmli97.flan.commands.CommandClaim; import io.github.flemmli97.flan.config.ConfigHandler; import io.github.flemmli97.flan.event.PlayerEvents; +import io.github.flemmli97.flan.player.PlayerDataHandler; import net.minecraftforge.event.RegisterCommandsEvent; import net.minecraftforge.event.entity.player.PlayerEvent; import net.minecraftforge.fml.event.server.FMLServerAboutToStartEvent; +import net.minecraftforge.fml.event.server.FMLServerStartedEvent; public class ServerEvents { @@ -17,6 +19,10 @@ public class ServerEvents { Flan.lockRegistry(event.getServer()); } + public static void serverFinishLoad(FMLServerStartedEvent event) { + PlayerDataHandler.deleteInactivePlayerData(event.getServer()); + } + public static void commands(RegisterCommandsEvent event) { CommandClaim.register(event.getDispatcher(), false); }