mirror of
https://github.com/WiIIiam278/HuskSync.git
synced 2025-12-19 14:59:21 +00:00
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
This commit is contained in:
@@ -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();
|
||||
});
|
||||
|
||||
@@ -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<PotionEffect> effects;
|
||||
|
||||
private PotionEffects(@NotNull Collection<PotionEffect> effects) {
|
||||
this.effects = effects;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static BukkitData.PotionEffects from(@NotNull Collection<PotionEffect> effects) {
|
||||
return new BukkitData.PotionEffects(effects);
|
||||
@@ -297,21 +284,16 @@ public abstract class BukkitData implements Data {
|
||||
.toList();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<PotionEffect> getEffects() {
|
||||
return effects;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public static class Advancements extends BukkitData implements Data.Advancements {
|
||||
|
||||
private List<Advancement> completed;
|
||||
|
||||
private Advancements(@NotNull List<Advancement> 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<Advancement> getCompleted() {
|
||||
return completed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCompleted(@NotNull List<Advancement> 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<Statistic, Integer> genericStatistics;
|
||||
private Map<Statistic, Map<Material, Integer>> blockStatistics;
|
||||
private Map<Statistic, Map<Material, Integer>> itemStatistics;
|
||||
private Map<Statistic, Map<EntityType, Integer>> entityStatistics;
|
||||
|
||||
private Statistics(@NotNull Map<Statistic, Integer> genericStatistics,
|
||||
@NotNull Map<Statistic, Map<Material, Integer>> blockStatistics,
|
||||
@NotNull Map<Statistic, Map<Material, Integer>> itemStatistics,
|
||||
@NotNull Map<Statistic, Map<EntityType, Integer>> 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 {
|
||||
user.getPlayer().setGameMode(org.bukkit.GameMode.valueOf(gameMode));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public static class FlightStatus extends BukkitData implements Data.FlightStatus, Adaptable {
|
||||
|
||||
@SerializedName("allow_flight")
|
||||
private boolean allowFlight;
|
||||
@SerializedName("is_flying")
|
||||
private boolean flying;
|
||||
|
||||
@NotNull
|
||||
public static BukkitData.FlightStatus from(boolean allowFlight, boolean flying) {
|
||||
return new BukkitData.FlightStatus(allowFlight, allowFlight && flying);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static BukkitData.FlightStatus adapt(@NotNull Player player) {
|
||||
return from(player.getAllowFlight(), player.isFlying());
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getGameMode() {
|
||||
return gameMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGameMode(@NotNull String gameMode) {
|
||||
this.gameMode = gameMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getAllowFlight() {
|
||||
return allowFlight;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAllowFlight(boolean allowFlight) {
|
||||
this.allowFlight = allowFlight;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getIsFlying() {
|
||||
return isFlying;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIsFlying(boolean isFlying) {
|
||||
this.isFlying = isFlying;
|
||||
player.setFlying(allowFlight && flying);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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<BukkitData.Health> implements Serializer<BukkitData.Health> {
|
||||
|
||||
public Health(@NotNull HuskSync plugin) {
|
||||
super(plugin, BukkitData.Health.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Hunger extends Json<BukkitData.Hunger> implements Serializer<BukkitData.Hunger> {
|
||||
|
||||
public Hunger(@NotNull HuskSync plugin) {
|
||||
super(plugin, BukkitData.Hunger.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Experience extends Json<BukkitData.Experience> implements Serializer<BukkitData.Experience> {
|
||||
|
||||
public Experience(@NotNull HuskSync plugin) {
|
||||
super(plugin, BukkitData.Experience.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class GameMode extends Json<BukkitData.GameMode> implements Serializer<BukkitData.GameMode> {
|
||||
|
||||
public GameMode(@NotNull HuskSync plugin) {
|
||||
super(plugin, BukkitData.GameMode.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static abstract class Json<T extends Data & Adaptable> extends BukkitSerializer implements Serializer<T> {
|
||||
public static class Json<T extends Data & Adaptable> extends BukkitSerializer implements Serializer<T> {
|
||||
|
||||
private final Class<T> type;
|
||||
|
||||
protected Json(@NotNull HuskSync plugin, Class<T> type) {
|
||||
public Json(@NotNull HuskSync plugin, Class<T> type) {
|
||||
super(plugin);
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@@ -128,6 +128,12 @@ public interface BukkitUserDataHolder extends UserDataHolder {
|
||||
return Optional.of(BukkitData.GameMode.adapt(getBukkitPlayer()));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
default Optional<Data.FlightStatus> getFlightStatus() {
|
||||
return Optional.of(BukkitData.FlightStatus.adapt(getBukkitPlayer()));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
default Optional<Data.PersistentData> getPersistentData() {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
* <ul>
|
||||
* <li>Game mode</li>
|
||||
* <li>Allow flight</li>
|
||||
* <li>Is flying</li>
|
||||
* </ul>
|
||||
* 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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -128,6 +128,15 @@ public interface DataHolder {
|
||||
getData().put(Identifier.GAME_MODE, gameMode);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
default Optional<Data.FlightStatus> 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<Data.PersistentData> getPersistentData() {
|
||||
return Optional.ofNullable((Data.PersistentData) getData().get(Identifier.PERSISTENT_DATA));
|
||||
|
||||
@@ -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
|
||||
* <p>
|
||||
* Equivalent to {@code data(Identifier.FLIGHT_STATUS, flightStatus)}
|
||||
* </p>
|
||||
*
|
||||
* @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
|
||||
* <p>
|
||||
|
||||
@@ -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<String, Boolean> 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));
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user