Fixed soulbound items being lost when logging off

This commit is contained in:
Jules 2024-06-21 16:29:12 -07:00
parent 56f5e580d0
commit cef7d0163a
3 changed files with 29 additions and 26 deletions

View File

@ -189,7 +189,6 @@ public class MMOItems extends MMOPlugin {
Bukkit.getPluginManager().registerEvents(dropTableManager, this);
// Load Dist module
// Load MMOCore-Bukkit module
try {
Class.forName("net.Indyuce.mmoitems.MMOItemsBukkit").getConstructor(MMOItems.class).newInstance(this);
@ -268,7 +267,7 @@ public class MMOItems extends MMOPlugin {
playerDataManager.close();
// Drop abandoned items
DeathItemsHandler.getActive().forEach(info -> info.giveItems(true));
DeathItemsHandler.getActive().forEach(DeathItemsHandler::dropItems);
// Close inventories
for (Player player : Bukkit.getOnlinePlayers())

View File

@ -1,14 +1,15 @@
package net.Indyuce.mmoitems.api;
import java.util.*;
import net.Indyuce.mmoitems.MMOItems;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
public class DeathItemsHandler {
/**
@ -21,12 +22,14 @@ public class DeathItemsHandler {
* lost. the plugin saves the last location of the player to drop the items
* when the server shuts down this way they are 'saved'
*/
private final Player player;
private final Location lastLocation;
private final UUID playerId;
/**
* Used to store which items must be given back to which player
*/
private static final Map<UUID, DeathItemsHandler> INFO = new WeakHashMap<>();
private static final Map<UUID, DeathItemsHandler> PLAYER_INFO = new WeakHashMap<>();
/**
* Instanced when a player dies if some Soulbound items must be kept in the
@ -37,7 +40,8 @@ public class DeathItemsHandler {
* player respawns again.
*/
public DeathItemsHandler(@NotNull Player player) {
this.player = player;
this.playerId = player.getUniqueId();
this.lastLocation = player.getLocation();
}
public void registerItem(@NotNull ItemStack item) {
@ -45,25 +49,24 @@ public class DeathItemsHandler {
}
public void registerIfNecessary() {
if (!items.isEmpty()) INFO.put(player.getUniqueId(), this);
if (!items.isEmpty()) PLAYER_INFO.put(playerId, this);
}
/**
* @param forceDrop Should the items all drop on the ground
* Drops items on the ground. Called when the player
* has not respawned yet and items need to be disposed of!
* TODO save it inside of configuration files and stop using this method. Give items back when joining
*/
public void giveItems(boolean forceDrop) {
public void dropItems() {
for (ItemStack drop : items)
lastLocation.getWorld().dropItem(lastLocation, drop);
}
// Drop all items on the ground
if (forceDrop) for (ItemStack drop : items)
player.getWorld().dropItem(player.getLocation(), drop);
// First try to add them to inventory
else {
public void giveItems(@NotNull Player player) {
final ItemStack[] toArray = this.items.toArray(new ItemStack[0]);
for (ItemStack drop : player.getInventory().addItem(toArray).values())
player.getWorld().dropItem(player.getLocation(), drop);
}
}
/**
* Tries to add the items to the player's inventory, or drops them
@ -73,15 +76,16 @@ public class DeathItemsHandler {
* @param player Target player respawning
*/
public static void readAndRemove(@NotNull Player player) {
final @Nullable DeathItemsHandler handler = INFO.remove(player.getUniqueId());
if (handler != null) Bukkit.getScheduler().runTaskLater(MMOItems.plugin, () -> handler.giveItems(false), 10);
final @Nullable DeathItemsHandler handler = PLAYER_INFO.remove(player.getUniqueId());
if (handler != null) Bukkit.getScheduler().runTaskLater(MMOItems.plugin, () -> handler.giveItems(player), 10);
}
/**
* @return Soulbound info of players who have not clicked the respawn button
* and yet have items cached in server RAM
*/
@NotNull
public static Collection<DeathItemsHandler> getActive() {
return INFO.values();
return PLAYER_INFO.values();
}
}

View File

@ -3,7 +3,7 @@ config-version: 8
# Notifies players with the 'mmoitems.update-notify' perm node when
# they join the server if a new update is available for download.
# Requires /reload when changed.
# Changes apply on server restart.
update-notify: true
# Enable/disable the plugin iterating over the whole player inventory
@ -68,7 +68,7 @@ default:
range: 16
recoil: 0.1
# Restart server when changing this option
# Changes apply on server restart.
dropped-items:
# Items glow based on their tier
@ -375,7 +375,7 @@ item-revision:
# Offset is the distance traveled on X and Y coordinates
# Height is the Y velocity coordinate. Lootsplosions
# only trigger with MythicMobs monsters.
# Requires a SERVER reload when changed.
# Changes apply on server restart.
lootsplosion:
enabled: true
color: true