1313import org .mvplugins .multiverse .external .jetbrains .annotations .NotNull ;
1414import org .mvplugins .multiverse .external .jetbrains .annotations .Nullable ;
1515import org .mvplugins .multiverse .inventories .MultiverseInventories ;
16+ import org .mvplugins .multiverse .inventories .config .InventoriesConfig ;
1617import org .mvplugins .multiverse .inventories .handleshare .SingleShareReader ;
1718import org .mvplugins .multiverse .inventories .handleshare .SingleShareWriter ;
1819import org .mvplugins .multiverse .inventories .profile .container .ProfileContainer ;
2122import org .mvplugins .multiverse .inventories .profile .key .ContainerType ;
2223import org .mvplugins .multiverse .inventories .profile .key .ProfileType ;
2324import org .mvplugins .multiverse .inventories .profile .key .ProfileTypes ;
25+ import org .mvplugins .multiverse .inventories .share .Sharable ;
2426import org .mvplugins .multiverse .inventories .share .Sharables ;
2527
2628import java .util .concurrent .CompletableFuture ;
@@ -38,14 +40,17 @@ public final class InventoryDataProvider {
3840
3941 private final ProfileContainerStoreProvider profileContainerStoreProvider ;
4042 private final MultiverseInventories inventories ;
43+ private final InventoriesConfig inventoriesConfig ;
4144
4245 @ Inject
4346 InventoryDataProvider (
4447 @ NotNull ProfileContainerStoreProvider profileContainerStoreProvider ,
45- @ NotNull MultiverseInventories inventories
48+ @ NotNull MultiverseInventories inventories ,
49+ @ NotNull InventoriesConfig inventoriesConfig
4650 ) {
4751 this .profileContainerStoreProvider = profileContainerStoreProvider ;
4852 this .inventories = inventories ;
53+ this .inventoriesConfig = inventoriesConfig ;
4954 }
5055
5156 /**
@@ -193,38 +198,28 @@ private CompletableFuture<PlayerInventoryData> loadInventoryDataFromProfileStora
193198 ItemStack offHand = SingleShareReader .of (inventories , targetPlayer , worldName , profileTypeToUse , Sharables .OFF_HAND ).read ().join ();
194199
195200 // Non-inventory data
196- double storedHealth = SingleShareReader .of (inventories , targetPlayer , worldName , profileTypeToUse , Sharables .HEALTH )
197- .read ().join ();
198- double storedMaxHealth = SingleShareReader .of (inventories , targetPlayer , worldName , profileTypeToUse , Sharables .MAX_HEALTH )
199- .read ().join ();
200- int storedLevel = SingleShareReader .of (inventories , targetPlayer , worldName , profileTypeToUse , Sharables .LEVEL )
201- .read ().join ();
202- float storedExp = SingleShareReader .of (inventories , targetPlayer , worldName , profileTypeToUse , Sharables .EXPERIENCE )
203- .read ().join ();
204- int storedFoodLevel = SingleShareReader .of (inventories , targetPlayer , worldName , profileTypeToUse , Sharables .FOOD_LEVEL )
205- .read ().join ();
206- float storedSaturationLevel = SingleShareReader .of (inventories , targetPlayer , worldName , profileTypeToUse , Sharables .SATURATION )
207- .read ().join ();
208- Location storedLocationObject = SingleShareReader .of (inventories , targetPlayer , worldName , profileTypeToUse , Sharables .LAST_LOCATION )
209- .read ().join ();
210-
211- // Note that this is here for debugging purposes
212- // If the player leaves a world or logs off, Sharables.LAST_LOCATION appears to read null
213- // storedLocationObject
201+ double storedHealth = getSharableValue (Sharables .HEALTH , targetPlayer , worldName , profileTypeToUse , 20.0 );
202+ double storedMaxHealth = getSharableValue (Sharables .MAX_HEALTH , targetPlayer , worldName , profileTypeToUse , 20.0 );
203+ int storedLevel = getSharableValue (Sharables .LEVEL , targetPlayer , worldName , profileTypeToUse , 0 );
204+ float storedExp = getSharableValue (Sharables .EXPERIENCE , targetPlayer , worldName , profileTypeToUse , 0.0f );
205+ int storedFoodLevel = getSharableValue (Sharables .FOOD_LEVEL , targetPlayer , worldName , profileTypeToUse , 20 );
206+ float storedSaturationLevel = getSharableValue (Sharables .SATURATION , targetPlayer , worldName , profileTypeToUse , 5.0f );
214207 String storedLastLocation ;
215- if (storedLocationObject == null ) {
216- storedLastLocation = "N/A (No Location Data)" ;
217- } else if (storedLocationObject .getWorld () == null ) {
218- storedLastLocation = String .format ("N/A (World Null: %.1f, %.1f, %.1f)" ,
219- storedLocationObject .getX (),
220- storedLocationObject .getY (),
221- storedLocationObject .getZ ());
222- } else {
223- storedLastLocation = String .format ("%s (%.1f, %.1f, %.1f)" ,
224- storedLocationObject .getWorld ().getName (),
225- storedLocationObject .getX (),
226- storedLocationObject .getY (),
227- storedLocationObject .getZ ());
208+
209+ // Check if LAST_LOCATION is enabled in config
210+ if (!inventoriesConfig .getActiveOptionalShares ().contains (Sharables .LAST_LOCATION )) {
211+ storedLastLocation = "Disabled in config" ;
212+ } else { // if the location is null or the world is null
213+ Location storedLocationObject = SingleShareReader .of (inventories , targetPlayer , worldName , profileTypeToUse , Sharables .LAST_LOCATION ).read ().join ();
214+ if (storedLocationObject == null || storedLocationObject .getWorld () == null ) {
215+ storedLastLocation = "N/A (No Location Data)" ;
216+ } else { // if the location is valid, print the coordinates and the world
217+ storedLastLocation = String .format ("%s (%.1f, %.1f, %.1f)" ,
218+ storedLocationObject .getWorld ().getName (),
219+ storedLocationObject .getX (),
220+ storedLocationObject .getY (),
221+ storedLocationObject .getZ ());
222+ }
228223 }
229224
230225 return new PlayerInventoryData (
@@ -264,6 +259,30 @@ private PlayerProfile loadMVInvPlayerProfile(ProfileContainer container, Offline
264259 return null ;
265260 }
266261
262+ /**
263+ * Helper method to safely read a sharable value, returning a default if disabled or not found.
264+ * @param sharable The Sharable to read.
265+ * @param targetPlayer The OfflinePlayer.
266+ * @param worldName The world name.
267+ * @param profileType The profile type.
268+ * @param defaultValue The default value to return if sharable is disabled or data is null.
269+ * @param <T> The type of the sharable value.
270+ * @return The sharable value or the default value.
271+ */
272+ private <T > T getSharableValue (@ NotNull Sharable <T > sharable ,
273+ @ NotNull OfflinePlayer targetPlayer ,
274+ @ NotNull String worldName ,
275+ @ NotNull ProfileType profileType ,
276+ @ NotNull T defaultValue ) {
277+ try {
278+ T value = SingleShareReader .of (inventories , targetPlayer , worldName , profileType , sharable ).read ().join ();
279+ return value != null ? value : defaultValue ;
280+ } catch (CompletionException e ) {
281+ Logging .warning ("Failed to read sharable '" + sharable .getNames ()[0 ] + "' for player " + targetPlayer .getName () + " in world " + worldName + ": " + e .getCause ().getMessage ());
282+ return defaultValue ;
283+ }
284+ }
285+
267286 /**
268287 * Asynchronously saves a player's inventory data to their Multiverse-Inventories profile.
269288 * If the player is online and in the target world, their live inventory is also updated.
0 commit comments