add deletion of banned player claims and option to delete inactive player data

This commit is contained in:
Flemmli97 2021-08-04 23:52:36 +02:00
parent 3a2b84214b
commit 9067126f11
10 changed files with 116 additions and 27 deletions

View File

@ -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() {

View File

@ -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);

View File

@ -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();
}

View File

@ -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<UUID, OfflinePlayerData> collectAllPlayerData(MinecraftServer server) {
Path dir = ConfigHandler.getPlayerSavePath(server);
Map<UUID, OfflinePlayerData> 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<UUID, OfflinePlayerData> 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();
}
}
}

View File

@ -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<UUID, OfflinePlayerData> inActivePlayerData = null;
public static void initInactivePlayers(MinecraftServer server) {
inActivePlayerData = new HashMap<>();
LocalDateTime now = LocalDateTime.now();
Map<UUID, OfflinePlayerData> 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<UUID, OfflinePlayerData> collectAllPlayerData(MinecraftServer server) {
Path dir = ConfigHandler.getPlayerSavePath(server);
Map<UUID, OfflinePlayerData> 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;
}
}
}

View File

@ -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()) {

View File

@ -22,7 +22,8 @@
"IItemAccessor",
"IHungerAccessor",
"FrostWalkerMixin",
"LightningFireEntityMixin"
"LightningFireEntityMixin",
"BannedEntryAccessor"
],
"server": [
],

View File

@ -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);
}
}

View File

@ -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();
}

View File

@ -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);
}