From a35e83a424ace2b0a66a3cc1d28f0f433f62619c Mon Sep 17 00:00:00 2001 From: William Date: Wed, 10 Apr 2024 14:34:19 +0100 Subject: [PATCH] feat: Move flight status into its own data type, use lombok for data class (#273) * refactor: use lombok, separate flight, close #191 * refactor: suppress some warnings * refactor: suppress unused `from` warnings * refactor: correct bad null-annotations on Items * refactor: fix null annotation on `getStack` * refactor: override methods for getting flight status * docs: add deprecation docs for flight in gamemode data --- .../william278/husksync/BukkitHuskSync.java | 15 +- .../william278/husksync/data/BukkitData.java | 372 ++++-------------- .../husksync/data/BukkitSerializer.java | 43 +- .../husksync/data/BukkitUserDataHolder.java | 6 + .../listener/BukkitEventListener.java | 6 +- .../husksync/migrator/LegacyMigrator.java | 3 +- .../husksync/migrator/MpdbMigrator.java | 2 +- .../husksync/util/BukkitLegacyConverter.java | 6 +- .../husksync/util/BukkitMapPersister.java | 5 +- .../net/william278/husksync/data/Data.java | 72 +++- .../william278/husksync/data/DataHolder.java | 9 + .../husksync/data/DataSnapshot.java | 16 + .../william278/husksync/data/Identifier.java | 3 +- .../husksync/data/UserDataHolder.java | 5 + .../husksync/database/PostgresDatabase.java | 1 - gradle.properties | 2 +- 16 files changed, 196 insertions(+), 370 deletions(-) diff --git a/bukkit/src/main/java/net/william278/husksync/BukkitHuskSync.java b/bukkit/src/main/java/net/william278/husksync/BukkitHuskSync.java index 4e228b80..b07a36b6 100644 --- a/bukkit/src/main/java/net/william278/husksync/BukkitHuskSync.java +++ b/bukkit/src/main/java/net/william278/husksync/BukkitHuskSync.java @@ -38,10 +38,7 @@ import net.william278.husksync.command.BukkitCommand; import net.william278.husksync.config.Locales; import net.william278.husksync.config.Server; import net.william278.husksync.config.Settings; -import net.william278.husksync.data.BukkitSerializer; -import net.william278.husksync.data.Data; -import net.william278.husksync.data.Identifier; -import net.william278.husksync.data.Serializer; +import net.william278.husksync.data.*; import net.william278.husksync.database.Database; import net.william278.husksync.database.MongoDbDatabase; import net.william278.husksync.database.MySqlDatabase; @@ -144,12 +141,13 @@ public class BukkitHuskSync extends JavaPlugin implements HuskSync, BukkitTask.S registerSerializer(Identifier.ENDER_CHEST, new BukkitSerializer.EnderChest(this)); registerSerializer(Identifier.ADVANCEMENTS, new BukkitSerializer.Advancements(this)); registerSerializer(Identifier.LOCATION, new BukkitSerializer.Location(this)); - registerSerializer(Identifier.HEALTH, new BukkitSerializer.Health(this)); - registerSerializer(Identifier.HUNGER, new BukkitSerializer.Hunger(this)); - registerSerializer(Identifier.GAME_MODE, new BukkitSerializer.GameMode(this)); + registerSerializer(Identifier.HEALTH, new BukkitSerializer.Json<>(this, BukkitData.Health.class)); + registerSerializer(Identifier.HUNGER, new BukkitSerializer.Json<>(this, BukkitData.Hunger.class)); + registerSerializer(Identifier.GAME_MODE, new BukkitSerializer.Json<>(this, BukkitData.GameMode.class)); + registerSerializer(Identifier.FLIGHT_STATUS, new BukkitSerializer.Json<>(this, BukkitData.FlightStatus.class)); registerSerializer(Identifier.POTION_EFFECTS, new BukkitSerializer.PotionEffects(this)); registerSerializer(Identifier.STATISTICS, new BukkitSerializer.Statistics(this)); - registerSerializer(Identifier.EXPERIENCE, new BukkitSerializer.Experience(this)); + registerSerializer(Identifier.EXPERIENCE, new BukkitSerializer.Json<>(this, BukkitData.Experience.class)); registerSerializer(Identifier.PERSISTENT_DATA, new BukkitSerializer.PersistentData(this)); }); @@ -168,7 +166,6 @@ public class BukkitHuskSync extends JavaPlugin implements HuskSync, BukkitTask.S case MYSQL, MARIADB -> new MySqlDatabase(this); case POSTGRES -> new PostgresDatabase(this); case MONGO -> new MongoDbDatabase(this); - default -> throw new IllegalStateException("Invalid database type"); }; this.database.initialize(); }); diff --git a/bukkit/src/main/java/net/william278/husksync/data/BukkitData.java b/bukkit/src/main/java/net/william278/husksync/data/BukkitData.java index d4514520..6e88e000 100644 --- a/bukkit/src/main/java/net/william278/husksync/data/BukkitData.java +++ b/bukkit/src/main/java/net/william278/husksync/data/BukkitData.java @@ -24,12 +24,12 @@ import com.google.common.collect.Maps; import com.google.gson.annotations.SerializedName; import de.tr7zw.changeme.nbtapi.NBTCompound; import de.tr7zw.changeme.nbtapi.NBTPersistentDataContainer; +import lombok.*; import net.william278.desertwell.util.ThrowingConsumer; import net.william278.husksync.BukkitHuskSync; import net.william278.husksync.HuskSync; import net.william278.husksync.adapter.Adaptable; import net.william278.husksync.user.BukkitUser; -import org.apache.commons.lang.NotImplementedException; import org.bukkit.*; import org.bukkit.advancement.AdvancementProgress; import org.bukkit.attribute.Attribute; @@ -44,6 +44,7 @@ import org.bukkit.potion.PotionEffectType; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.Range; import java.util.*; import java.util.logging.Level; @@ -61,19 +62,20 @@ public abstract class BukkitData implements Data { public abstract void apply(@NotNull BukkitUser user, @NotNull BukkitHuskSync plugin) throws IllegalStateException; + @Getter public static abstract class Items extends BukkitData implements Data.Items { - private final ItemStack[] contents; + private final @Nullable ItemStack @NotNull [] contents; - private Items(@NotNull ItemStack[] contents) { + private Items(@Nullable ItemStack @NotNull [] contents) { this.contents = Arrays.stream(contents) .map(i -> i == null || i.getType() == Material.AIR ? null : i) .toArray(ItemStack[]::new); } - @NotNull + @Nullable @Override - public Stack[] getStack() { + public Stack @NotNull [] getStack() { return Arrays.stream(contents) .map(stack -> stack != null ? new Stack( stack.getType().getKey().toString(), @@ -103,7 +105,7 @@ public abstract class BukkitData implements Data { this.setContents(((BukkitData.Items) contents).getContents()); } - public void setContents(@NotNull ItemStack[] contents) { + public void setContents(@Nullable ItemStack @NotNull [] contents) { // Ensure the array is the correct length for the inventory if (contents.length != this.contents.length) { contents = Arrays.copyOf(contents, this.contents.length); @@ -111,11 +113,6 @@ public abstract class BukkitData implements Data { System.arraycopy(contents, 0, this.contents, 0, this.contents.length); } - @NotNull - public ItemStack[] getContents() { - return contents; - } - @Override public boolean equals(Object obj) { if (obj instanceof BukkitData.Items items) { @@ -124,9 +121,13 @@ public abstract class BukkitData implements Data { return false; } + @Setter + @Getter public static class Inventory extends BukkitData.Items implements Data.Items.Inventory { public static final int INVENTORY_SLOT_COUNT = 41; + + @Range(from = 0, to = 8) private int heldItemSlot; private Inventory(@NotNull ItemStack[] contents, int heldItemSlot) { @@ -168,19 +169,6 @@ public abstract class BukkitData implements Data { } } - @Override - public int getHeldItemSlot() { - return heldItemSlot; - } - - @Override - public void setHeldItemSlot(int heldItemSlot) throws IllegalArgumentException { - if (heldItemSlot < 0 || heldItemSlot > 8) { - throw new IllegalArgumentException("Held item slot must be between 0 and 8"); - } - this.heldItemSlot = heldItemSlot; - } - } public static class EnderChest extends BukkitData.Items implements Data.Items.EnderChest { @@ -226,21 +214,20 @@ public abstract class BukkitData implements Data { @Override public void apply(@NotNull BukkitUser user, @NotNull BukkitHuskSync plugin) throws IllegalStateException { - throw new NotImplementedException("A generic item array cannot be applied to a player"); + throw new UnsupportedOperationException("A generic item array cannot be applied to a player"); } } } + @Getter + @Setter + @AllArgsConstructor(access = AccessLevel.PRIVATE) public static class PotionEffects extends BukkitData implements Data.PotionEffects { private final Collection effects; - private PotionEffects(@NotNull Collection effects) { - this.effects = effects; - } - @NotNull public static BukkitData.PotionEffects from(@NotNull Collection effects) { return new BukkitData.PotionEffects(effects); @@ -297,21 +284,16 @@ public abstract class BukkitData implements Data { .toList(); } - @NotNull - public Collection getEffects() { - return effects; - } - } + @Getter + @Setter + @AllArgsConstructor(access = AccessLevel.PRIVATE) + @NoArgsConstructor(access = AccessLevel.PRIVATE) public static class Advancements extends BukkitData implements Data.Advancements { private List completed; - private Advancements(@NotNull List advancements) { - this.completed = advancements; - } - // Iterate through the server advancement set and add all advancements to the list @NotNull public static BukkitData.Advancements adapt(@NotNull Player player) { @@ -392,20 +374,14 @@ public abstract class BukkitData implements Data { Bukkit.getServer().advancementIterator().forEachRemaining(consumer); } - @NotNull - @Override - public List getCompleted() { - return completed; - } - - @Override - public void setCompleted(@NotNull List completed) { - this.completed = completed; - } - } + @Getter + @Setter + @AllArgsConstructor(access = AccessLevel.PRIVATE) + @NoArgsConstructor(access = AccessLevel.PRIVATE) public static class Location extends BukkitData implements Data.Location, Adaptable { + @SerializedName("x") private double x; @SerializedName("y") @@ -419,19 +395,6 @@ public abstract class BukkitData implements Data { @SerializedName("world") private World world; - private Location(double x, double y, double z, float yaw, float pitch, @NotNull World world) { - this.x = x; - this.y = y; - this.z = z; - this.yaw = yaw; - this.pitch = pitch; - this.world = world; - } - - @SuppressWarnings("unused") - private Location() { - } - @NotNull public static BukkitData.Location from(double x, double y, double z, float yaw, float pitch, @NotNull World world) { @@ -466,90 +429,17 @@ public abstract class BukkitData implements Data { } } - @Override - public double getX() { - return x; - } - - @Override - public void setX(double x) { - this.x = x; - } - - @Override - public double getY() { - return y; - } - - @Override - public void setY(double y) { - this.y = y; - } - - @Override - public double getZ() { - return z; - } - - @Override - public void setZ(double z) { - this.z = z; - } - - @Override - public float getYaw() { - return yaw; - } - - @Override - public void setYaw(float yaw) { - this.yaw = yaw; - } - - @Override - public float getPitch() { - return pitch; - } - - @Override - public void setPitch(float pitch) { - this.pitch = pitch; - } - - @NotNull - @Override - public World getWorld() { - return world; - } - - @Override - public void setWorld(@NotNull World world) { - this.world = world; - } - } // TODO: Consider using Paper's new-ish API for this instead (when it's merged) + @AllArgsConstructor(access = AccessLevel.PRIVATE) + @NoArgsConstructor(access = AccessLevel.PRIVATE) public static class Statistics extends BukkitData implements Data.Statistics { private Map genericStatistics; private Map> blockStatistics; private Map> itemStatistics; private Map> entityStatistics; - private Statistics(@NotNull Map genericStatistics, - @NotNull Map> blockStatistics, - @NotNull Map> itemStatistics, - @NotNull Map> entityStatistics) { - this.genericStatistics = genericStatistics; - this.blockStatistics = blockStatistics; - this.itemStatistics = itemStatistics; - this.entityStatistics = entityStatistics; - } - - @SuppressWarnings("unused") - private Statistics() { - } - @NotNull public static BukkitData.Statistics adapt(@NotNull Player player) { return new BukkitData.Statistics( @@ -753,13 +643,11 @@ public abstract class BukkitData implements Data { } + @Getter + @AllArgsConstructor(access = AccessLevel.PRIVATE) public static class PersistentData extends BukkitData implements Data.PersistentData { private final NBTCompound persistentData; - private PersistentData(@NotNull NBTCompound persistentData) { - this.persistentData = persistentData; - } - @NotNull public static BukkitData.PersistentData adapt(@NotNull PersistentDataContainer persistentData) { return new BukkitData.PersistentData(new NBTPersistentDataContainer(persistentData)); @@ -779,13 +667,13 @@ public abstract class BukkitData implements Data { container.mergeCompound(persistentData); } - @NotNull - public NBTCompound getPersistentData() { - return persistentData; - } } + @Getter + @Setter + @AllArgsConstructor(access = AccessLevel.PRIVATE) + @NoArgsConstructor(access = AccessLevel.PRIVATE) public static class Health extends BukkitData implements Data.Health, Adaptable { @SerializedName("health") private double health; @@ -794,16 +682,6 @@ public abstract class BukkitData implements Data { @SerializedName("health_scale") private double healthScale; - private Health(double health, double maxHealth, double healthScale) { - this.health = health; - this.maxHealth = maxHealth; - this.healthScale = healthScale; - } - - @SuppressWarnings("unused") - private Health() { - } - @NotNull public static BukkitData.Health from(double health, double maxHealth, double healthScale) { return new BukkitData.Health(health, maxHealth, healthScale); @@ -881,38 +759,12 @@ public abstract class BukkitData implements Data { ); } - @Override - public double getHealth() { - return health; - } - - @Override - public void setHealth(double health) { - this.health = health; - } - - @Override - public double getMaxHealth() { - return maxHealth; - } - - @Override - public void setMaxHealth(double maxHealth) { - this.maxHealth = maxHealth; - } - - @Override - public double getHealthScale() { - return healthScale; - } - - @Override - public void setHealthScale(double healthScale) { - this.healthScale = healthScale; - } - } + @Getter + @Setter + @AllArgsConstructor(access = AccessLevel.PRIVATE) + @NoArgsConstructor(access = AccessLevel.PRIVATE) public static class Hunger extends BukkitData implements Data.Hunger, Adaptable { @SerializedName("food_level") @@ -922,16 +774,6 @@ public abstract class BukkitData implements Data { @SerializedName("exhaustion") private float exhaustion; - private Hunger(int foodLevel, float saturation, float exhaustion) { - this.foodLevel = foodLevel; - this.saturation = saturation; - this.exhaustion = exhaustion; - } - - @SuppressWarnings("unused") - private Hunger() { - } - @NotNull public static BukkitData.Hunger adapt(@NotNull Player player) { return from(player.getFoodLevel(), player.getSaturation(), player.getExhaustion()); @@ -950,37 +792,12 @@ public abstract class BukkitData implements Data { player.setExhaustion(exhaustion); } - @Override - public int getFoodLevel() { - return foodLevel; - } - - @Override - public void setFoodLevel(int foodLevel) { - this.foodLevel = foodLevel; - } - - @Override - public float getSaturation() { - return saturation; - } - - @Override - public void setSaturation(float saturation) { - this.saturation = saturation; - } - - @Override - public float getExhaustion() { - return exhaustion; - } - - @Override - public void setExhaustion(float exhaustion) { - this.exhaustion = exhaustion; - } } + @Getter + @Setter + @AllArgsConstructor(access = AccessLevel.PRIVATE) + @NoArgsConstructor(access = AccessLevel.PRIVATE) public static class Experience extends BukkitData implements Data.Experience, Adaptable { @SerializedName("total_experience") @@ -992,16 +809,6 @@ public abstract class BukkitData implements Data { @SerializedName("exp_progress") private float expProgress; - private Experience(int totalExperience, int expLevel, float expProgress) { - this.totalExperience = totalExperience; - this.expLevel = expLevel; - this.expProgress = expProgress; - } - - @SuppressWarnings("unused") - private Experience() { - } - @NotNull public static BukkitData.Experience from(int totalExperience, int expLevel, float expProgress) { return new BukkitData.Experience(totalExperience, expLevel, expProgress); @@ -1020,100 +827,67 @@ public abstract class BukkitData implements Data { player.setExp(expProgress); } - @Override - public int getTotalExperience() { - return totalExperience; - } - - @Override - public void setTotalExperience(int totalExperience) { - this.totalExperience = totalExperience; - } - - @Override - public int getExpLevel() { - return expLevel; - } - - @Override - public void setExpLevel(int expLevel) { - this.expLevel = expLevel; - } - - @Override - public float getExpProgress() { - return expProgress; - } - - @Override - public void setExpProgress(float expProgress) { - this.expProgress = expProgress; - } - } + @Getter + @Setter + @AllArgsConstructor(access = AccessLevel.PRIVATE) + @NoArgsConstructor(access = AccessLevel.PRIVATE) public static class GameMode extends BukkitData implements Data.GameMode, Adaptable { @SerializedName("game_mode") private String gameMode; - @SerializedName("allow_flight") - private boolean allowFlight; - @SerializedName("is_flying") - private boolean isFlying; - private GameMode(@NotNull String gameMode, boolean allowFlight, boolean isFlying) { - this.gameMode = gameMode; - this.allowFlight = allowFlight; - this.isFlying = isFlying; + @NotNull + public static BukkitData.GameMode from(@NotNull String gameMode) { + return new BukkitData.GameMode(gameMode); } @NotNull + @Deprecated(forRemoval = true, since = "3.5") + @SuppressWarnings("unused") public static BukkitData.GameMode from(@NotNull String gameMode, boolean allowFlight, boolean isFlying) { - return new BukkitData.GameMode(gameMode, allowFlight, isFlying); + return new BukkitData.GameMode(gameMode); } @NotNull public static BukkitData.GameMode adapt(@NotNull Player player) { - return from(player.getGameMode().name(), player.getAllowFlight(), player.isFlying()); + return from(player.getGameMode().name()); } @Override public void apply(@NotNull BukkitUser user, @NotNull BukkitHuskSync plugin) throws IllegalStateException { - final Player player = user.getPlayer(); - player.setGameMode(org.bukkit.GameMode.valueOf(gameMode)); - player.setAllowFlight(allowFlight); - player.setFlying(allowFlight && isFlying); + user.getPlayer().setGameMode(org.bukkit.GameMode.valueOf(gameMode)); } - @NotNull - @Override - public String getGameMode() { - return gameMode; - } + } - @Override - public void setGameMode(@NotNull String gameMode) { - this.gameMode = gameMode; - } + @Getter + @Setter + @AllArgsConstructor(access = AccessLevel.PRIVATE) + @NoArgsConstructor(access = AccessLevel.PRIVATE) + public static class FlightStatus extends BukkitData implements Data.FlightStatus, Adaptable { - @Override - public boolean getAllowFlight() { - return allowFlight; - } + @SerializedName("allow_flight") + private boolean allowFlight; + @SerializedName("is_flying") + private boolean flying; - @Override - public void setAllowFlight(boolean allowFlight) { - this.allowFlight = allowFlight; + @NotNull + public static BukkitData.FlightStatus from(boolean allowFlight, boolean flying) { + return new BukkitData.FlightStatus(allowFlight, allowFlight && flying); } - @Override - public boolean getIsFlying() { - return isFlying; + @NotNull + public static BukkitData.FlightStatus adapt(@NotNull Player player) { + return from(player.getAllowFlight(), player.isFlying()); } @Override - public void setIsFlying(boolean isFlying) { - this.isFlying = isFlying; + public void apply(@NotNull BukkitUser user, @NotNull BukkitHuskSync plugin) throws IllegalStateException { + final Player player = user.getPlayer(); + player.setAllowFlight(allowFlight); + player.setFlying(allowFlight && flying); } } diff --git a/bukkit/src/main/java/net/william278/husksync/data/BukkitSerializer.java b/bukkit/src/main/java/net/william278/husksync/data/BukkitSerializer.java index 0f6e0232..1c62b7db 100644 --- a/bukkit/src/main/java/net/william278/husksync/data/BukkitSerializer.java +++ b/bukkit/src/main/java/net/william278/husksync/data/BukkitSerializer.java @@ -23,6 +23,8 @@ import com.google.gson.reflect.TypeToken; import de.tr7zw.changeme.nbtapi.NBT; import de.tr7zw.changeme.nbtapi.NBTContainer; import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; import net.william278.husksync.HuskSync; import net.william278.husksync.adapter.Adaptable; import net.william278.husksync.api.HuskSyncAPI; @@ -34,14 +36,11 @@ import java.util.List; import static net.william278.husksync.data.BukkitData.Items.Inventory.INVENTORY_SLOT_COUNT; +@AllArgsConstructor(access = AccessLevel.PRIVATE) public class BukkitSerializer { protected final HuskSync plugin; - private BukkitSerializer(@NotNull HuskSync plugin) { - this.plugin = plugin; - } - @SuppressWarnings("unused") public BukkitSerializer(@NotNull HuskSyncAPI api) { this.plugin = api.getPlugin(); @@ -208,43 +207,11 @@ public class BukkitSerializer { } - public static class Health extends Json implements Serializer { - - public Health(@NotNull HuskSync plugin) { - super(plugin, BukkitData.Health.class); - } - - } - - public static class Hunger extends Json implements Serializer { - - public Hunger(@NotNull HuskSync plugin) { - super(plugin, BukkitData.Hunger.class); - } - - } - - public static class Experience extends Json implements Serializer { - - public Experience(@NotNull HuskSync plugin) { - super(plugin, BukkitData.Experience.class); - } - - } - - public static class GameMode extends Json implements Serializer { - - public GameMode(@NotNull HuskSync plugin) { - super(plugin, BukkitData.GameMode.class); - } - - } - - public static abstract class Json extends BukkitSerializer implements Serializer { + public static class Json extends BukkitSerializer implements Serializer { private final Class type; - protected Json(@NotNull HuskSync plugin, Class type) { + public Json(@NotNull HuskSync plugin, Class type) { super(plugin); this.type = type; } diff --git a/bukkit/src/main/java/net/william278/husksync/data/BukkitUserDataHolder.java b/bukkit/src/main/java/net/william278/husksync/data/BukkitUserDataHolder.java index 1d85a1be..3c818bb8 100644 --- a/bukkit/src/main/java/net/william278/husksync/data/BukkitUserDataHolder.java +++ b/bukkit/src/main/java/net/william278/husksync/data/BukkitUserDataHolder.java @@ -128,6 +128,12 @@ public interface BukkitUserDataHolder extends UserDataHolder { return Optional.of(BukkitData.GameMode.adapt(getBukkitPlayer())); } + @NotNull + @Override + default Optional getFlightStatus() { + return Optional.of(BukkitData.FlightStatus.adapt(getBukkitPlayer())); + } + @NotNull @Override default Optional getPersistentData() { diff --git a/bukkit/src/main/java/net/william278/husksync/listener/BukkitEventListener.java b/bukkit/src/main/java/net/william278/husksync/listener/BukkitEventListener.java index 8b7cfb20..4766f577 100644 --- a/bukkit/src/main/java/net/william278/husksync/listener/BukkitEventListener.java +++ b/bukkit/src/main/java/net/william278/husksync/listener/BukkitEventListener.java @@ -40,11 +40,7 @@ import org.bukkit.event.entity.ProjectileLaunchEvent; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryOpenEvent; import org.bukkit.event.inventory.PrepareItemCraftEvent; -import org.bukkit.event.player.PlayerCommandPreprocessEvent; -import org.bukkit.event.player.PlayerDropItemEvent; -import org.bukkit.event.player.PlayerInteractEntityEvent; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.event.player.PlayerArmorStandManipulateEvent; +import org.bukkit.event.player.*; import org.bukkit.event.server.MapInitializeEvent; import org.bukkit.event.world.WorldSaveEvent; import org.bukkit.inventory.ItemStack; diff --git a/bukkit/src/main/java/net/william278/husksync/migrator/LegacyMigrator.java b/bukkit/src/main/java/net/william278/husksync/migrator/LegacyMigrator.java index 793a4250..f53a1d0c 100644 --- a/bukkit/src/main/java/net/william278/husksync/migrator/LegacyMigrator.java +++ b/bukkit/src/main/java/net/william278/husksync/migrator/LegacyMigrator.java @@ -334,7 +334,8 @@ public class LegacyMigrator extends Migrator { .health(BukkitData.Health.from(health, maxHealth, healthScale)) .hunger(BukkitData.Hunger.from(hunger, saturation, saturationExhaustion)) .experience(BukkitData.Experience.from(totalExp, expLevel, expProgress)) - .gameMode(BukkitData.GameMode.from(gameMode, isFlying, isFlying)) + .gameMode(BukkitData.GameMode.from(gameMode)) + .flightStatus(BukkitData.FlightStatus.from(isFlying, isFlying)) // Build & pack into new format .saveCause(DataSnapshot.SaveCause.LEGACY_MIGRATION).buildAndPack(); diff --git a/bukkit/src/main/java/net/william278/husksync/migrator/MpdbMigrator.java b/bukkit/src/main/java/net/william278/husksync/migrator/MpdbMigrator.java index 2acfe508..4fb2d8db 100644 --- a/bukkit/src/main/java/net/william278/husksync/migrator/MpdbMigrator.java +++ b/bukkit/src/main/java/net/william278/husksync/migrator/MpdbMigrator.java @@ -320,7 +320,7 @@ public class MpdbMigrator extends Migrator { .inventory(BukkitData.Items.Inventory.from(inventory.getContents(), 0)) .enderChest(BukkitData.Items.EnderChest.adapt(enderChest)) .experience(BukkitData.Experience.from(totalExp, expLevel, expProgress)) - .gameMode(BukkitData.GameMode.from("SURVIVAL", false, false)) + .gameMode(BukkitData.GameMode.from("SURVIVAL")) .saveCause(DataSnapshot.SaveCause.MPDB_MIGRATION) .buildAndPack(); } diff --git a/bukkit/src/main/java/net/william278/husksync/util/BukkitLegacyConverter.java b/bukkit/src/main/java/net/william278/husksync/util/BukkitLegacyConverter.java index 52bb300a..29feb1cc 100644 --- a/bukkit/src/main/java/net/william278/husksync/util/BukkitLegacyConverter.java +++ b/bukkit/src/main/java/net/william278/husksync/util/BukkitLegacyConverter.java @@ -107,7 +107,11 @@ public class BukkitLegacyConverter extends LegacyConverter { } if (shouldImport(Identifier.GAME_MODE)) { containers.put(Identifier.GAME_MODE, BukkitData.GameMode.from( - status.getString("game_mode"), + status.getString("game_mode") + )); + } + if (shouldImport(Identifier.FLIGHT_STATUS)) { + containers.put(Identifier.FLIGHT_STATUS, BukkitData.FlightStatus.from( status.getBoolean("is_flying"), status.getBoolean("is_flying") )); diff --git a/bukkit/src/main/java/net/william278/husksync/util/BukkitMapPersister.java b/bukkit/src/main/java/net/william278/husksync/util/BukkitMapPersister.java index bf92a39c..74903faa 100644 --- a/bukkit/src/main/java/net/william278/husksync/util/BukkitMapPersister.java +++ b/bukkit/src/main/java/net/william278/husksync/util/BukkitMapPersister.java @@ -37,6 +37,7 @@ import org.bukkit.inventory.meta.MapMeta; import org.bukkit.map.*; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.awt.*; import java.io.File; @@ -75,8 +76,8 @@ public interface BukkitMapPersister { * @param items the array of {@link ItemStack}s to apply persisted locked maps to * @return the array of {@link ItemStack}s with persisted locked maps applied */ - @NotNull - default ItemStack[] setMapViews(@NotNull ItemStack[] items) { + @Nullable + default ItemStack @NotNull [] setMapViews(@Nullable ItemStack @NotNull [] items) { if (!getPlugin().getSettings().getSynchronization().isPersistLockedMaps()) { return items; } diff --git a/common/src/main/java/net/william278/husksync/data/Data.java b/common/src/main/java/net/william278/husksync/data/Data.java index e192a4fb..029dc785 100644 --- a/common/src/main/java/net/william278/husksync/data/Data.java +++ b/common/src/main/java/net/william278/husksync/data/Data.java @@ -51,8 +51,8 @@ public interface Data { */ interface Items extends Data { - @NotNull - Stack[] getStack(); + @Nullable + Stack @NotNull [] getStack(); default int getSlotCount() { return getStack().length; @@ -76,6 +76,9 @@ public interface Data { */ interface Inventory extends Items { + String ITEMS_TAG = "items"; + String HELD_ITEM_SLOT_TAG = "held_item_slot"; + int getHeldItemSlot(); void setHeldItemSlot(int heldItemSlot) throws IllegalArgumentException; @@ -341,12 +344,7 @@ public interface Data { } /** - * A data container holding data for: - *
    - *
  • Game mode
  • - *
  • Allow flight
  • - *
  • Is flying
  • - *
+ * Data container holding data for the player's current game mode */ interface GameMode extends Data { @@ -355,13 +353,65 @@ public interface Data { void setGameMode(@NotNull String gameMode); - boolean getAllowFlight(); + /** + * Get if the player can fly. + * + * @return {@code false} since v3.5 + * @deprecated Moved to its own data type. This will always return {@code false}. + * Use {@link FlightStatus#isAllowFlight()} instead + */ + @Deprecated(forRemoval = true, since = "3.5") + default boolean getAllowFlight() { + return false; + } + + /** + * Set if the player can fly. + * + * @deprecated Moved to its own data type. + * Use {@link FlightStatus#setAllowFlight(boolean)} instead + */ + @Deprecated(forRemoval = true, since = "3.5") + default void setAllowFlight(boolean allowFlight) { + } + + /** + * Get if the player is flying. + * + * @return {@code false} since v3.5 + * @deprecated Moved to its own data type. This will always return {@code false}. + * Use {@link FlightStatus#isFlying()} instead + */ + @Deprecated(forRemoval = true, since = "3.5") + default boolean getIsFlying() { + return false; + } + + /** + * Set if the player is flying. + * + * @deprecated Moved to its own data type. + * Use {@link FlightStatus#setFlying(boolean)} instead + */ + @Deprecated(forRemoval = true, since = "3.5") + default void setIsFlying(boolean isFlying) { + } + + } + + /** + * Data container holding data for the player's flight status + * + * @since 3.5 + */ + interface FlightStatus extends Data { + boolean isAllowFlight(); void setAllowFlight(boolean allowFlight); - boolean getIsFlying(); + boolean isFlying(); - void setIsFlying(boolean isFlying); + void setFlying(boolean isFlying); } diff --git a/common/src/main/java/net/william278/husksync/data/DataHolder.java b/common/src/main/java/net/william278/husksync/data/DataHolder.java index 2fa1cae8..a864b7dc 100644 --- a/common/src/main/java/net/william278/husksync/data/DataHolder.java +++ b/common/src/main/java/net/william278/husksync/data/DataHolder.java @@ -128,6 +128,15 @@ public interface DataHolder { getData().put(Identifier.GAME_MODE, gameMode); } + @NotNull + default Optional getFlightStatus() { + return Optional.ofNullable((Data.FlightStatus) getData().get(Identifier.FLIGHT_STATUS)); + } + + default void setFlightStatus(@NotNull Data.FlightStatus flightStatus) { + getData().put(Identifier.FLIGHT_STATUS, flightStatus); + } + @NotNull default Optional getPersistentData() { return Optional.ofNullable((Data.PersistentData) getData().get(Identifier.PERSISTENT_DATA)); diff --git a/common/src/main/java/net/william278/husksync/data/DataSnapshot.java b/common/src/main/java/net/william278/husksync/data/DataSnapshot.java index b2bb5cfa..bae6865b 100644 --- a/common/src/main/java/net/william278/husksync/data/DataSnapshot.java +++ b/common/src/main/java/net/william278/husksync/data/DataSnapshot.java @@ -47,6 +47,7 @@ import java.util.stream.Collectors; * * @since 3.0 */ +@SuppressWarnings({"LombokSetterMayBeUsed", "LombokGetterMayBeUsed"}) @NoArgsConstructor(access = AccessLevel.PRIVATE) public class DataSnapshot { @@ -688,6 +689,21 @@ public class DataSnapshot { return data(Identifier.GAME_MODE, gameMode); } + /** + * Set the flight status of the snapshot + *

+ * Equivalent to {@code data(Identifier.FLIGHT_STATUS, flightStatus)} + *

+ * + * @param flightStatus The flight status + * @return The builder + * @since 3.5 + */ + @NotNull + public Builder flightStatus(@NotNull Data.FlightStatus flightStatus) { + return data(Identifier.FLIGHT_STATUS, flightStatus); + } + /** * Set the persistent data container of the snapshot *

diff --git a/common/src/main/java/net/william278/husksync/data/Identifier.java b/common/src/main/java/net/william278/husksync/data/Identifier.java index 1279cdd9..8582024d 100644 --- a/common/src/main/java/net/william278/husksync/data/Identifier.java +++ b/common/src/main/java/net/william278/husksync/data/Identifier.java @@ -43,6 +43,7 @@ public class Identifier { public static Identifier HUNGER = huskSync("hunger", true); public static Identifier EXPERIENCE = huskSync("experience", true); public static Identifier GAME_MODE = huskSync("game_mode", true); + public static Identifier FLIGHT_STATUS = huskSync("flight_status", true); public static Identifier PERSISTENT_DATA = huskSync("persistent_data", true); private final Key key; @@ -114,7 +115,7 @@ public class Identifier { public static Map getConfigMap() { return Map.ofEntries(Stream.of( INVENTORY, ENDER_CHEST, POTION_EFFECTS, ADVANCEMENTS, LOCATION, - STATISTICS, HEALTH, HUNGER, EXPERIENCE, GAME_MODE, PERSISTENT_DATA + STATISTICS, HEALTH, HUNGER, EXPERIENCE, GAME_MODE, FLIGHT_STATUS, PERSISTENT_DATA ) .map(Identifier::getConfigEntry) .toArray(Map.Entry[]::new)); diff --git a/common/src/main/java/net/william278/husksync/data/UserDataHolder.java b/common/src/main/java/net/william278/husksync/data/UserDataHolder.java index 44e01b6a..ad5b01e6 100644 --- a/common/src/main/java/net/william278/husksync/data/UserDataHolder.java +++ b/common/src/main/java/net/william278/husksync/data/UserDataHolder.java @@ -171,6 +171,11 @@ public interface UserDataHolder extends DataHolder { this.setData(Identifier.GAME_MODE, gameMode); } + @Override + default void setFlightStatus(@NotNull Data.FlightStatus flightStatus) { + this.setData(Identifier.FLIGHT_STATUS, flightStatus); + } + @Override default void setPersistentData(@NotNull Data.PersistentData persistentData) { this.setData(Identifier.PERSISTENT_DATA, persistentData); diff --git a/common/src/main/java/net/william278/husksync/database/PostgresDatabase.java b/common/src/main/java/net/william278/husksync/database/PostgresDatabase.java index 468bc6ca..fb949830 100644 --- a/common/src/main/java/net/william278/husksync/database/PostgresDatabase.java +++ b/common/src/main/java/net/william278/husksync/database/PostgresDatabase.java @@ -28,7 +28,6 @@ import net.william278.husksync.user.User; import org.jetbrains.annotations.Blocking; import org.jetbrains.annotations.NotNull; -import java.io.ByteArrayInputStream; import java.io.IOException; import java.sql.*; import java.time.OffsetDateTime; diff --git a/gradle.properties b/gradle.properties index 954dfa62..dd106028 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ org.gradle.jvmargs='-Dfile.encoding=UTF-8' org.gradle.daemon=true javaVersion=17 -plugin_version=3.4.1 +plugin_version=3.5 plugin_archive=husksync plugin_description=A modern, cross-server player data synchronization system