66import org .bukkit .Material ;
77import org .bukkit .World ;
88import org .bukkit .advancement .AdvancementProgress ;
9+ import org .bukkit .entity .EntityType ;
910import org .bukkit .inventory .Inventory ;
1011import org .mvplugins .multiverse .core .economy .MVEconomist ;
1112import org .mvplugins .multiverse .core .teleportation .AsyncSafetyTeleporter ;
@@ -820,13 +821,59 @@ public boolean updatePlayer(Player player, ProfileData profile) {
820821 new SharableHandler <>() {
821822 @ Override
822823 public void updateProfile (ProfileData profile , Player player ) {
823- Map <String , Integer > playerStats = new HashMap <>();
824+ Map <String , Object > playerStats = new HashMap <>();
824825 for (Statistic stat : Statistic .values ()) {
825- if (stat .getType () == Statistic .Type .UNTYPED ) {
826- int val = player .getStatistic (stat );
827- // no need to save values of 0, that's the default!
828- if (val != 0 ) {
829- playerStats .put (stat .name (), val );
826+ switch (stat .getType ()) {
827+ case UNTYPED -> {
828+ int val = player .getStatistic (stat );
829+ if (val != 0 ) {
830+ playerStats .put (stat .name (), val );
831+ }
832+ }
833+ case ITEM -> {
834+ Map <String , Integer > itemStats = new HashMap <>();
835+ for (Material mat : Material .values ()) {
836+ if (!mat .isItem ()) {
837+ continue ;
838+ }
839+ int val = player .getStatistic (stat , mat );
840+ if (val != 0 ) {
841+ itemStats .put (mat .getKey ().toString (), val );
842+ }
843+ }
844+ if (!itemStats .isEmpty ()) {
845+ playerStats .put (stat .name (), itemStats );
846+ }
847+ }
848+ case BLOCK -> {
849+ Map <String , Integer > blockStats = new HashMap <>();
850+ for (Material mat : Material .values ()) {
851+ if (!mat .isBlock ()) {
852+ continue ;
853+ }
854+ int val = player .getStatistic (stat , mat );
855+ if (val != 0 ) {
856+ playerStats .put (mat .getKey ().toString (), val );
857+ }
858+ }
859+ if (!blockStats .isEmpty ()) {
860+ playerStats .put (stat .name (), blockStats );
861+ }
862+ }
863+ case ENTITY -> {
864+ Map <String , Integer > entityStats = new HashMap <>();
865+ for (EntityType entityType : EntityType .values ()) {
866+ if (entityType == EntityType .UNKNOWN ) {
867+ continue ;
868+ }
869+ int val = player .getStatistic (stat , entityType );
870+ if (val != 0 ) {
871+ entityStats .put (entityType .getKey ().toString (), val );
872+ }
873+ }
874+ if (!entityStats .isEmpty ()) {
875+ playerStats .put (stat .name (), entityStats );
876+ }
830877 }
831878 }
832879 }
@@ -835,24 +882,99 @@ public void updateProfile(ProfileData profile, Player player) {
835882
836883 @ Override
837884 public boolean updatePlayer (Player player , ProfileData profile ) {
838- Map <String , Integer > playerStats = profile .get (GAME_STATISTICS );
885+ Map <String , Object > playerStats = profile .get (GAME_STATISTICS );
886+ boolean hasData = true ;
839887 if (playerStats == null ) {
840- // Set all to 0
841- for (Statistic stat : Statistic .values ()) {
842- if (stat .getType () == Statistic .Type .UNTYPED ) {
843- player .setStatistic (stat , 0 );
844- }
845- }
846- return false ;
888+ playerStats = Collections .emptyMap ();
889+ hasData = false ;
847890 }
848891
849892 for (Statistic stat : Statistic .values ()) {
850- if (stat .getType () == Statistic .Type .UNTYPED ) {
851- player .setStatistic (stat , playerStats .getOrDefault (stat .name (), 0 ));
893+ Object value = playerStats .get (stat .name ());
894+ switch (stat .getType ()) {
895+ case UNTYPED -> {
896+ if (value == null ) {
897+ player .setStatistic (stat , 0 );
898+ break ;
899+ }
900+ if (!(value instanceof Integer intValue )) {
901+ Logging .warning ("Invalid statistic value for " + stat .name () + ": " + value );
902+ break ;
903+ }
904+ Try .run (() -> player .setStatistic (stat , intValue ))
905+ .onFailure (ex -> Logging .warning ("Failed to set statistic " + stat .name () +
906+ ": " + ex .getMessage ()));
907+ }
908+ case ITEM -> {
909+ if (value == null ) {
910+ value = Collections .emptyMap ();
911+ }
912+ if (!(value instanceof Map itemMap )) {
913+ Logging .warning ("Invalid statistic value for " + stat .name () + ": " + value );
914+ break ;
915+ }
916+ for (Material mat : Material .values ()) {
917+ if (!mat .isItem ()) {
918+ continue ;
919+ }
920+ Object matValue = itemMap .getOrDefault (mat .getKey ().toString (), 0 );
921+ if (!(matValue instanceof Integer intValue )) {
922+ Logging .warning ("Invalid statistic value for " + stat .name () + " and item " + mat .name () + ": " + matValue );
923+ continue ;
924+ }
925+ Try .run (() -> player .setStatistic (stat , mat , intValue ))
926+ .onFailure (ex -> Logging .warning ("Failed to set statistic " + stat .name () +
927+ " for item " + mat .name () + ": " + ex .getMessage ()));
928+ }
929+ }
930+ case BLOCK -> {
931+ if (value == null ) {
932+ value = Collections .emptyMap ();
933+ }
934+ if (!(value instanceof Map blockMap )) {
935+ Logging .warning ("Invalid statistic value for " + stat .name () + ": " + value );
936+ break ;
937+ }
938+ for (Material mat : Material .values ()) {
939+ if (!mat .isBlock ()) {
940+ continue ;
941+ }
942+ Object matValue = blockMap .getOrDefault (mat .getKey ().toString (), 0 );
943+ if (!(matValue instanceof Integer intValue )) {
944+ Logging .warning ("Invalid statistic value for " + stat .name () + " and block " + mat .name () + ": " + matValue );
945+ continue ;
946+ }
947+ Try .run (() -> player .setStatistic (stat , mat , intValue ))
948+ .onFailure (ex -> Logging .warning ("Failed to set statistic " + stat .name () +
949+ " for block " + mat .name () + ": " + ex .getMessage ()));
950+ }
951+ }
952+ case ENTITY -> {
953+ if (value == null ) {
954+ value = Collections .emptyMap ();
955+ }
956+ if (!(value instanceof Map entityMap )) {
957+ Logging .warning ("Invalid statistic value for " + stat .name () + ": " + value );
958+ break ;
959+ }
960+ for (EntityType entityType : EntityType .values ()) {
961+ if (entityType == EntityType .UNKNOWN ) {
962+ continue ;
963+ }
964+ Object entityValue = entityMap .getOrDefault (entityType .getKey ().toString (), 0 );
965+ if (!(entityValue instanceof Integer intValue )) {
966+ Logging .warning ("Invalid statistic value for " + stat .name () + " and entity " + entityType .name () + ": " + entityValue );
967+ continue ;
968+ }
969+ Try .run (() -> player .setStatistic (stat , entityType , intValue ))
970+ .onFailure (ex -> Logging .warning ("Failed to set statistic " + stat .name () +
971+ " for entity " + entityType .name () + ": " + ex .getMessage ()));
972+ }
973+ }
852974 }
853975 }
854976
855- return true ;
977+ return hasData ;
856978 }
857979 }).defaultSerializer (new ProfileEntry (false , "game_statistics" )).altName ("game_stats" ).optional ().build ();
858980
0 commit comments