mirror of
https://github.com/Minestom/Minestom.git
synced 2025-02-08 08:21:50 +01:00
Share more data between PlayerInventory & Inventory
Signed-off-by: TheMode <themode@outlook.fr>
This commit is contained in:
parent
1c9528908c
commit
51d290cae9
@ -2,20 +2,43 @@ package net.minestom.server.inventory;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import net.minestom.server.data.Data;
|
||||
import net.minestom.server.data.DataContainer;
|
||||
import net.minestom.server.inventory.click.InventoryClickProcessor;
|
||||
import net.minestom.server.inventory.condition.InventoryCondition;
|
||||
import net.minestom.server.item.ItemStack;
|
||||
import net.minestom.server.item.StackingRule;
|
||||
import net.minestom.server.utils.validate.Check;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
/**
|
||||
* Represents an inventory where items can be modified/retrieved.
|
||||
*/
|
||||
public abstract class AbstractInventory {
|
||||
public abstract class AbstractInventory implements DataContainer {
|
||||
|
||||
private final int size;
|
||||
protected final ItemStack[] itemStacks;
|
||||
|
||||
// list of conditions/callbacks assigned to this inventory
|
||||
protected final List<InventoryCondition> inventoryConditions = new CopyOnWriteArrayList<>();
|
||||
// the click processor which process all the clicks in the inventory
|
||||
protected final InventoryClickProcessor clickProcessor = new InventoryClickProcessor();
|
||||
|
||||
private Data data;
|
||||
|
||||
protected AbstractInventory(int size) {
|
||||
this.size = size;
|
||||
this.itemStacks = new ItemStack[getSize()];
|
||||
|
||||
Arrays.fill(itemStacks, ItemStack.AIR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an {@link ItemStack} at the specified slot and send relevant update to the viewer(s).
|
||||
@ -35,7 +58,7 @@ public abstract class AbstractInventory {
|
||||
* @param itemStack the item to add
|
||||
* @return true if the item has been successfully fully added, false otherwise
|
||||
*/
|
||||
public boolean addItemStack(@NotNull ItemStack itemStack) {
|
||||
public synchronized boolean addItemStack(@NotNull ItemStack itemStack) {
|
||||
Int2ObjectMap<ItemStack> itemChangesMap = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
final StackingRule stackingRule = itemStack.getStackingRule();
|
||||
@ -235,7 +258,7 @@ public abstract class AbstractInventory {
|
||||
return itemStacks.stream().allMatch(this::canTakeItemStack);
|
||||
}
|
||||
|
||||
public void replaceItemStack(int slot, @NotNull UnaryOperator<@NotNull ItemStack> operator) {
|
||||
public synchronized void replaceItemStack(int slot, @NotNull UnaryOperator<@NotNull ItemStack> operator) {
|
||||
var currentItem = getItemStack(slot);
|
||||
setItemStack(slot, operator.apply(currentItem));
|
||||
}
|
||||
@ -243,7 +266,14 @@ public abstract class AbstractInventory {
|
||||
/**
|
||||
* Clears the inventory and send relevant update to the viewer(s).
|
||||
*/
|
||||
public abstract void clear();
|
||||
public synchronized void clear() {
|
||||
// Clear the item array
|
||||
Arrays.fill(itemStacks, ItemStack.AIR);
|
||||
// Send the cleared inventory to viewers
|
||||
update();
|
||||
}
|
||||
|
||||
public abstract void update();
|
||||
|
||||
/**
|
||||
* Gets the {@link ItemStack} at the specified slot.
|
||||
@ -252,7 +282,9 @@ public abstract class AbstractInventory {
|
||||
* @return the item in the slot {@code slot}
|
||||
*/
|
||||
@NotNull
|
||||
public abstract ItemStack getItemStack(int slot);
|
||||
public ItemStack getItemStack(int slot) {
|
||||
return itemStacks[slot];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all the {@link ItemStack} in the inventory.
|
||||
@ -263,14 +295,18 @@ public abstract class AbstractInventory {
|
||||
* @return an array containing all the inventory's items
|
||||
*/
|
||||
@NotNull
|
||||
public abstract ItemStack[] getItemStacks();
|
||||
public ItemStack[] getItemStacks() {
|
||||
return itemStacks.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the size of the inventory.
|
||||
*
|
||||
* @return the inventory's size
|
||||
*/
|
||||
public abstract int getSize();
|
||||
public int getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the size of the "inner inventory" (which includes only "usable" slots).
|
||||
@ -287,14 +323,18 @@ public abstract class AbstractInventory {
|
||||
* @return a modifiable {@link List} containing all the inventory conditions
|
||||
*/
|
||||
@NotNull
|
||||
public abstract List<InventoryCondition> getInventoryConditions();
|
||||
public List<InventoryCondition> getInventoryConditions() {
|
||||
return inventoryConditions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new {@link InventoryCondition} to this inventory.
|
||||
*
|
||||
* @param inventoryCondition the inventory condition to add
|
||||
*/
|
||||
public abstract void addInventoryCondition(@NotNull InventoryCondition inventoryCondition);
|
||||
public void addInventoryCondition(@NotNull InventoryCondition inventoryCondition) {
|
||||
this.inventoryConditions.add(inventoryCondition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Places all the items of {@code itemStacks} into the internal array.
|
||||
@ -313,4 +353,15 @@ public abstract class AbstractInventory {
|
||||
setItemStack(i, itemStack);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Data getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setData(@Nullable Data data) {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,10 @@
|
||||
package net.minestom.server.inventory;
|
||||
|
||||
import net.minestom.server.Viewable;
|
||||
import net.minestom.server.data.Data;
|
||||
import net.minestom.server.data.DataContainer;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.inventory.click.ClickType;
|
||||
import net.minestom.server.inventory.click.InventoryClickLoopHandler;
|
||||
import net.minestom.server.inventory.click.InventoryClickProcessor;
|
||||
import net.minestom.server.inventory.click.InventoryClickResult;
|
||||
import net.minestom.server.inventory.condition.InventoryCondition;
|
||||
import net.minestom.server.item.ItemStack;
|
||||
import net.minestom.server.network.packet.server.play.OpenWindowPacket;
|
||||
import net.minestom.server.network.packet.server.play.SetSlotPacket;
|
||||
@ -19,17 +15,12 @@ import net.minestom.server.utils.MathUtils;
|
||||
import net.minestom.server.utils.inventory.PlayerInventoryUtils;
|
||||
import net.minestom.server.utils.validate.Check;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
/**
|
||||
* Represents an inventory which can be viewed by a collection of {@link Player}.
|
||||
@ -37,7 +28,7 @@ import java.util.function.UnaryOperator;
|
||||
* You can create one with {@link Inventory#Inventory(InventoryType, String)} or by making your own subclass.
|
||||
* It can then be opened using {@link Player#openInventory(Inventory)}.
|
||||
*/
|
||||
public class Inventory extends AbstractInventory implements InventoryClickHandler, Viewable, DataContainer {
|
||||
public class Inventory extends AbstractInventory implements InventoryClickHandler, Viewable {
|
||||
|
||||
// incremented each time an inventory is created (used in the window packets)
|
||||
private static final AtomicInteger LAST_INVENTORY_ID = new AtomicInteger();
|
||||
@ -49,37 +40,21 @@ public class Inventory extends AbstractInventory implements InventoryClickHandle
|
||||
// the title of this inventory)
|
||||
private String title;
|
||||
|
||||
// the size based on the inventory type
|
||||
private final int size;
|
||||
|
||||
private final int offset;
|
||||
|
||||
// the items in this inventory
|
||||
private final ItemStack[] itemStacks;
|
||||
// the players currently viewing this inventory
|
||||
private final Set<Player> viewers = new CopyOnWriteArraySet<>();
|
||||
private final Set<Player> unmodifiableViewers = Collections.unmodifiableSet(viewers);
|
||||
// (player -> cursor item) map, used by the click listeners
|
||||
private final ConcurrentHashMap<Player, ItemStack> cursorPlayersItem = new ConcurrentHashMap<>();
|
||||
|
||||
// list of conditions/callbacks assigned to this inventory
|
||||
private final List<InventoryCondition> inventoryConditions = new CopyOnWriteArrayList<>();
|
||||
// the click processor which process all the clicks in the inventory
|
||||
private final InventoryClickProcessor clickProcessor = new InventoryClickProcessor();
|
||||
|
||||
private Data data;
|
||||
|
||||
public Inventory(@NotNull InventoryType inventoryType, @NotNull String title) {
|
||||
super(inventoryType.getSize());
|
||||
this.id = generateId();
|
||||
this.inventoryType = inventoryType;
|
||||
this.title = title;
|
||||
|
||||
this.size = inventoryType.getSize();
|
||||
|
||||
this.offset = size;
|
||||
|
||||
this.itemStacks = new ItemStack[size];
|
||||
Arrays.fill(itemStacks, ItemStack.AIR);
|
||||
this.offset = getSize();
|
||||
}
|
||||
|
||||
private static byte generateId() {
|
||||
@ -147,58 +122,10 @@ public class Inventory extends AbstractInventory implements InventoryClickHandle
|
||||
safeItemInsert(slot, itemStack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean addItemStack(@NotNull ItemStack itemStack) {
|
||||
// Make the method synchronized
|
||||
return super.addItemStack(itemStack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void replaceItemStack(int slot, @NotNull UnaryOperator<@NotNull ItemStack> operator) {
|
||||
// Make the method synchronized
|
||||
super.replaceItemStack(slot, operator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void clear() {
|
||||
// Clear the item array
|
||||
Arrays.fill(itemStacks, ItemStack.AIR);
|
||||
// Send the cleared inventory to viewers
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ItemStack getItemStack(int slot) {
|
||||
return itemStacks[slot];
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ItemStack[] getItemStacks() {
|
||||
return itemStacks.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<InventoryCondition> getInventoryConditions() {
|
||||
return inventoryConditions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addInventoryCondition(@NotNull InventoryCondition inventoryCondition) {
|
||||
this.inventoryConditions.add(inventoryCondition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes the inventory for all viewers.
|
||||
*/
|
||||
@Override
|
||||
public void update() {
|
||||
sendPacketToViewers(createNewWindowItemsPacket());
|
||||
}
|
||||
@ -604,15 +531,4 @@ public class Inventory extends AbstractInventory implements InventoryClickHandle
|
||||
update(player);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Data getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setData(@Nullable Data data) {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,11 @@
|
||||
package net.minestom.server.inventory;
|
||||
|
||||
import net.minestom.server.data.Data;
|
||||
import net.minestom.server.data.DataContainer;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.event.item.ArmorEquipEvent;
|
||||
import net.minestom.server.event.player.PlayerAddItemStackEvent;
|
||||
import net.minestom.server.event.player.PlayerSetItemStackEvent;
|
||||
import net.minestom.server.inventory.click.ClickType;
|
||||
import net.minestom.server.inventory.click.InventoryClickLoopHandler;
|
||||
import net.minestom.server.inventory.click.InventoryClickProcessor;
|
||||
import net.minestom.server.inventory.click.InventoryClickResult;
|
||||
import net.minestom.server.inventory.condition.InventoryCondition;
|
||||
import net.minestom.server.item.ItemStack;
|
||||
@ -18,60 +15,34 @@ import net.minestom.server.network.packet.server.play.WindowItemsPacket;
|
||||
import net.minestom.server.utils.MathUtils;
|
||||
import net.minestom.server.utils.validate.Check;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
import static net.minestom.server.utils.inventory.PlayerInventoryUtils.*;
|
||||
|
||||
/**
|
||||
* Represents the inventory of a {@link Player}, retrieved with {@link Player#getInventory()}.
|
||||
*/
|
||||
public class PlayerInventory extends AbstractInventory implements InventoryClickHandler, EquipmentHandler, DataContainer {
|
||||
public class PlayerInventory extends AbstractInventory implements InventoryClickHandler, EquipmentHandler {
|
||||
|
||||
public static final int INVENTORY_SIZE = 46;
|
||||
public static final int INNER_INVENTORY_SIZE = 36;
|
||||
|
||||
protected final Player player;
|
||||
protected final ItemStack[] itemStacks = new ItemStack[INVENTORY_SIZE];
|
||||
private ItemStack cursorItem = ItemStack.AIR;
|
||||
|
||||
private final List<InventoryCondition> inventoryConditions = new CopyOnWriteArrayList<>();
|
||||
private final InventoryClickProcessor clickProcessor = new InventoryClickProcessor();
|
||||
|
||||
private Data data;
|
||||
|
||||
public PlayerInventory(@NotNull Player player) {
|
||||
super(INVENTORY_SIZE);
|
||||
this.player = player;
|
||||
Arrays.fill(itemStacks, ItemStack.AIR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack getItemStack(int slot) {
|
||||
return this.itemStacks[slot];
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack[] getItemStacks() {
|
||||
return itemStacks.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull List<InventoryCondition> getInventoryConditions() {
|
||||
return inventoryConditions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addInventoryCondition(@NotNull InventoryCondition inventoryCondition) {
|
||||
// fix packet slot to inventory slot conversion
|
||||
InventoryCondition condition = (p, slot, clickType, inventoryConditionResult) -> {
|
||||
final int convertedSlot = convertPlayerInventorySlot(slot, OFFSET);
|
||||
inventoryCondition.accept(p, convertedSlot, clickType, inventoryConditionResult);
|
||||
};
|
||||
|
||||
this.inventoryConditions.add(condition);
|
||||
super.addInventoryCondition(condition);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -97,29 +68,13 @@ public class PlayerInventory extends AbstractInventory implements InventoryClick
|
||||
return super.addItemStack(itemStack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void replaceItemStack(int slot, @NotNull UnaryOperator<@NotNull ItemStack> operator) {
|
||||
// Make the method synchronized
|
||||
super.replaceItemStack(slot, operator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void clear() {
|
||||
// Clear the item array
|
||||
Arrays.fill(itemStacks, ItemStack.AIR);
|
||||
|
||||
// Send the cleared inventory to the inventory's owner
|
||||
update();
|
||||
|
||||
super.clear();
|
||||
// Update equipments
|
||||
this.player.sendPacketToViewersAndSelf(player.getEquipmentsPacket());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSize() {
|
||||
return INVENTORY_SIZE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInnerSize() {
|
||||
return INNER_INVENTORY_SIZE;
|
||||
@ -195,6 +150,7 @@ public class PlayerInventory extends AbstractInventory implements InventoryClick
|
||||
* Refreshes the player inventory by sending a {@link WindowItemsPacket} containing all.
|
||||
* the inventory items
|
||||
*/
|
||||
@Override
|
||||
public void update() {
|
||||
player.getPlayerConnection().sendPacket(createWindowItemsPacket());
|
||||
}
|
||||
@ -499,15 +455,4 @@ public class PlayerInventory extends AbstractInventory implements InventoryClick
|
||||
|
||||
return !clickResult.isCancel();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Data getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setData(@Nullable Data data) {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user