@ -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 ( @N otN ull ItemStack [ ] contents ) {
private Items ( @N ullable ItemStack @NotNull [ ] contents ) {
this . contents = Arrays . stream ( contents )
. map ( i - > i = = null | | i . getType ( ) = = Material . AIR ? null : i )
. toArray ( ItemStack [ ] : : new ) ;
}
@N otN ull
@N ullable
@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 ( @N otN ull ItemStack [ ] contents ) {
public void setContents ( @N ullable 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 NotImplemented Exception( "A generic item array cannot be applied to a player" ) ;
throw new UnsupportedOperation Exception( "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 {
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
p ublic boolean getAllowFlight ( ) {
return allowFlight ;
}
@ SerializedName( "allow_flight" )
p rivate 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 ) ;
}
}