mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-19 14:41:34 +01:00
Comments + inventory can now cache the items packet
This commit is contained in:
parent
f99e06957b
commit
01052528d0
@ -1,5 +1,6 @@
|
|||||||
package net.minestom.server.inventory;
|
package net.minestom.server.inventory;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
import net.minestom.server.Viewable;
|
import net.minestom.server.Viewable;
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
import net.minestom.server.inventory.click.ClickType;
|
import net.minestom.server.inventory.click.ClickType;
|
||||||
@ -9,13 +10,14 @@ import net.minestom.server.inventory.click.InventoryClickResult;
|
|||||||
import net.minestom.server.inventory.condition.InventoryCondition;
|
import net.minestom.server.inventory.condition.InventoryCondition;
|
||||||
import net.minestom.server.item.ItemStack;
|
import net.minestom.server.item.ItemStack;
|
||||||
import net.minestom.server.item.StackingRule;
|
import net.minestom.server.item.StackingRule;
|
||||||
import net.minestom.server.network.PacketWriterUtils;
|
|
||||||
import net.minestom.server.network.packet.server.play.OpenWindowPacket;
|
import net.minestom.server.network.packet.server.play.OpenWindowPacket;
|
||||||
import net.minestom.server.network.packet.server.play.SetSlotPacket;
|
import net.minestom.server.network.packet.server.play.SetSlotPacket;
|
||||||
import net.minestom.server.network.packet.server.play.WindowItemsPacket;
|
import net.minestom.server.network.packet.server.play.WindowItemsPacket;
|
||||||
import net.minestom.server.network.packet.server.play.WindowPropertyPacket;
|
import net.minestom.server.network.packet.server.play.WindowPropertyPacket;
|
||||||
|
import net.minestom.server.network.player.PlayerConnection;
|
||||||
import net.minestom.server.utils.ArrayUtils;
|
import net.minestom.server.utils.ArrayUtils;
|
||||||
import net.minestom.server.utils.MathUtils;
|
import net.minestom.server.utils.MathUtils;
|
||||||
|
import net.minestom.server.utils.PacketUtils;
|
||||||
import net.minestom.server.utils.inventory.PlayerInventoryUtils;
|
import net.minestom.server.utils.inventory.PlayerInventoryUtils;
|
||||||
import net.minestom.server.utils.item.ItemStackUtils;
|
import net.minestom.server.utils.item.ItemStackUtils;
|
||||||
import net.minestom.server.utils.validate.Check;
|
import net.minestom.server.utils.validate.Check;
|
||||||
@ -47,6 +49,11 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View
|
|||||||
private List<InventoryCondition> inventoryConditions = new CopyOnWriteArrayList<>();
|
private List<InventoryCondition> inventoryConditions = new CopyOnWriteArrayList<>();
|
||||||
private InventoryClickProcessor clickProcessor = new InventoryClickProcessor();
|
private InventoryClickProcessor clickProcessor = new InventoryClickProcessor();
|
||||||
|
|
||||||
|
// Cached windows packet
|
||||||
|
private ByteBuf windowItemsBuffer;
|
||||||
|
// True if the buffer above is up to date, false otherwise
|
||||||
|
private boolean windowItemsBufferUpdated;
|
||||||
|
|
||||||
public Inventory(InventoryType inventoryType, String title) {
|
public Inventory(InventoryType inventoryType, String title) {
|
||||||
this.id = generateId();
|
this.id = generateId();
|
||||||
this.inventoryType = inventoryType;
|
this.inventoryType = inventoryType;
|
||||||
@ -68,14 +75,29 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View
|
|||||||
return newInventoryId;
|
return newInventoryId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the inventory type
|
||||||
|
*
|
||||||
|
* @return the inventory type
|
||||||
|
*/
|
||||||
public InventoryType getInventoryType() {
|
public InventoryType getInventoryType() {
|
||||||
return inventoryType;
|
return inventoryType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the inventory title
|
||||||
|
*
|
||||||
|
* @return the inventory title
|
||||||
|
*/
|
||||||
public String getTitle() {
|
public String getTitle() {
|
||||||
return title;
|
return title;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the inventory title
|
||||||
|
*
|
||||||
|
* @param title the new inventory title
|
||||||
|
*/
|
||||||
public void setTitle(String title) {
|
public void setTitle(String title) {
|
||||||
this.title = title;
|
this.title = title;
|
||||||
|
|
||||||
@ -89,6 +111,13 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View
|
|||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get this window id
|
||||||
|
* <p>
|
||||||
|
* This is the id that the client will send to identify the affected inventory
|
||||||
|
*
|
||||||
|
* @return the window id
|
||||||
|
*/
|
||||||
public byte getWindowId() {
|
public byte getWindowId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
@ -103,16 +132,16 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized boolean addItemStack(ItemStack itemStack) {
|
public synchronized boolean addItemStack(ItemStack itemStack) {
|
||||||
StackingRule stackingRule = itemStack.getStackingRule();
|
final StackingRule stackingRule = itemStack.getStackingRule();
|
||||||
for (int i = 0; i < getSize(); i++) {
|
for (int i = 0; i < getSize(); i++) {
|
||||||
ItemStack item = getItemStack(i);
|
ItemStack item = getItemStack(i);
|
||||||
StackingRule itemStackingRule = item.getStackingRule();
|
final StackingRule itemStackingRule = item.getStackingRule();
|
||||||
if (itemStackingRule.canBeStacked(itemStack, item)) {
|
if (itemStackingRule.canBeStacked(itemStack, item)) {
|
||||||
int itemAmount = itemStackingRule.getAmount(item);
|
final int itemAmount = itemStackingRule.getAmount(item);
|
||||||
if (itemAmount == stackingRule.getMaxSize())
|
if (itemAmount == stackingRule.getMaxSize())
|
||||||
continue;
|
continue;
|
||||||
int itemStackAmount = itemStackingRule.getAmount(itemStack);
|
final int itemStackAmount = itemStackingRule.getAmount(itemStack);
|
||||||
int totalAmount = itemStackAmount + itemAmount;
|
final int totalAmount = itemStackAmount + itemAmount;
|
||||||
if (!stackingRule.canApply(itemStack, totalAmount)) {
|
if (!stackingRule.canApply(itemStack, totalAmount)) {
|
||||||
item = itemStackingRule.apply(item, itemStackingRule.getMaxSize());
|
item = itemStackingRule.apply(item, itemStackingRule.getMaxSize());
|
||||||
|
|
||||||
@ -160,7 +189,11 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View
|
|||||||
* Refresh the inventory for all viewers
|
* Refresh the inventory for all viewers
|
||||||
*/
|
*/
|
||||||
public void update() {
|
public void update() {
|
||||||
PacketWriterUtils.writeAndSend(getViewers(), createWindowItemsPacket());
|
final ByteBuf packetBuffer = getWindowItemsBuffer();
|
||||||
|
getViewers().forEach(player -> {
|
||||||
|
final PlayerConnection playerConnection = player.getPlayerConnection();
|
||||||
|
playerConnection.sendPacket(packetBuffer, true);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -173,7 +206,9 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View
|
|||||||
if (!getViewers().contains(player))
|
if (!getViewers().contains(player))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
PacketWriterUtils.writeAndSend(player, createWindowItemsPacket());
|
final PlayerConnection playerConnection = player.getPlayerConnection();
|
||||||
|
final ByteBuf packetBuffer = getWindowItemsBuffer();
|
||||||
|
playerConnection.sendPacket(packetBuffer, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -184,7 +219,7 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View
|
|||||||
@Override
|
@Override
|
||||||
public boolean addViewer(Player player) {
|
public boolean addViewer(Player player) {
|
||||||
final boolean result = this.viewers.add(player);
|
final boolean result = this.viewers.add(player);
|
||||||
PacketWriterUtils.writeAndSend(player, createWindowItemsPacket());
|
update(player);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,6 +263,14 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View
|
|||||||
this.cursorPlayersItem.put(player, cursorItem);
|
this.cursorPlayersItem.put(player, cursorItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert safely an item into the inventory
|
||||||
|
* <p>
|
||||||
|
* This will update the slot for all viewers
|
||||||
|
*
|
||||||
|
* @param slot the internal slot id
|
||||||
|
* @param itemStack the item to insert
|
||||||
|
*/
|
||||||
private synchronized void safeItemInsert(int slot, ItemStack itemStack) {
|
private synchronized void safeItemInsert(int slot, ItemStack itemStack) {
|
||||||
itemStack = ItemStackUtils.notNull(itemStack);
|
itemStack = ItemStackUtils.notNull(itemStack);
|
||||||
setItemStackInternal(slot, itemStack);
|
setItemStackInternal(slot, itemStack);
|
||||||
@ -236,13 +279,47 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View
|
|||||||
setSlotPacket.slot = (short) slot;
|
setSlotPacket.slot = (short) slot;
|
||||||
setSlotPacket.itemStack = itemStack;
|
setSlotPacket.itemStack = itemStack;
|
||||||
sendPacketToViewers(setSlotPacket);
|
sendPacketToViewers(setSlotPacket);
|
||||||
|
|
||||||
|
// The inventory changed, buffer will be updated once requested again
|
||||||
|
this.windowItemsBufferUpdated = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setItemStackInternal(int slot, ItemStack itemStack) {
|
protected void setItemStackInternal(int slot, ItemStack itemStack) {
|
||||||
itemStacks[slot] = itemStack;
|
itemStacks[slot] = itemStack;
|
||||||
}
|
}
|
||||||
|
|
||||||
private WindowItemsPacket createWindowItemsPacket() {
|
/**
|
||||||
|
* Get the window items packet as a buffer containing all the
|
||||||
|
* current inventory's items
|
||||||
|
* <p>
|
||||||
|
* The cached window items buffer will be updated if needed
|
||||||
|
*
|
||||||
|
* @return a {@link WindowItemsPacket} buffer
|
||||||
|
*/
|
||||||
|
private ByteBuf getWindowItemsBuffer() {
|
||||||
|
if (!windowItemsBufferUpdated) {
|
||||||
|
refreshWindowItemsBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
return windowItemsBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refresh the inventory {@link WindowItemsPacket} buffer
|
||||||
|
*/
|
||||||
|
private void refreshWindowItemsBuffer() {
|
||||||
|
final WindowItemsPacket windowItemsPacket = createNewWindowItemsPacket();
|
||||||
|
final ByteBuf packetBuffer = PacketUtils.writePacket(windowItemsPacket);
|
||||||
|
this.windowItemsBuffer = packetBuffer;
|
||||||
|
this.windowItemsBufferUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a complete new {@link WindowItemsPacket}
|
||||||
|
*
|
||||||
|
* @return a new {@link WindowItemsPacket} packet
|
||||||
|
*/
|
||||||
|
private WindowItemsPacket createNewWindowItemsPacket() {
|
||||||
WindowItemsPacket windowItemsPacket = new WindowItemsPacket();
|
WindowItemsPacket windowItemsPacket = new WindowItemsPacket();
|
||||||
windowItemsPacket.windowId = getWindowId();
|
windowItemsPacket.windowId = getWindowId();
|
||||||
windowItemsPacket.items = getItemStacks();
|
windowItemsPacket.items = getItemStacks();
|
||||||
|
@ -17,9 +17,13 @@ public abstract class PlayerConnection {
|
|||||||
|
|
||||||
private Player player;
|
private Player player;
|
||||||
//Could be null. Only used for Mojang Auth
|
//Could be null. Only used for Mojang Auth
|
||||||
@Getter @Setter private String loginUsername;
|
@Getter
|
||||||
|
@Setter
|
||||||
|
private String loginUsername;
|
||||||
//Could be null. Only used for Mojang Auth
|
//Could be null. Only used for Mojang Auth
|
||||||
@Getter @Setter private byte[] nonce = new byte[4];
|
@Getter
|
||||||
|
@Setter
|
||||||
|
private byte[] nonce = new byte[4];
|
||||||
private ConnectionState connectionState;
|
private ConnectionState connectionState;
|
||||||
private boolean online;
|
private boolean online;
|
||||||
|
|
||||||
@ -29,7 +33,9 @@ public abstract class PlayerConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public abstract void enableCompression(int threshold);
|
public abstract void enableCompression(int threshold);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Send a raw {@link ByteBuf} to the client
|
||||||
*
|
*
|
||||||
* @param buffer The buffer to send.
|
* @param buffer The buffer to send.
|
||||||
* @param copy Should be true unless your only using the ByteBuf once.
|
* @param copy Should be true unless your only using the ByteBuf once.
|
||||||
@ -37,14 +43,23 @@ public abstract class PlayerConnection {
|
|||||||
public abstract void sendPacket(ByteBuf buffer, boolean copy);
|
public abstract void sendPacket(ByteBuf buffer, boolean copy);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Write a raw {@link ByteBuf} to the client
|
||||||
*
|
*
|
||||||
* @param buffer The buffer to send.
|
* @param buffer The buffer to send.
|
||||||
* @param copy Should be true unless your only using the ByteBuf once.
|
* @param copy Should be true unless your only using the ByteBuf once.
|
||||||
*/
|
*/
|
||||||
public abstract void writePacket(ByteBuf buffer, boolean copy);
|
public abstract void writePacket(ByteBuf buffer, boolean copy);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serialize the packet and send it to the client
|
||||||
|
*
|
||||||
|
* @param serverPacket the packet to send
|
||||||
|
*/
|
||||||
public abstract void sendPacket(ServerPacket serverPacket);
|
public abstract void sendPacket(ServerPacket serverPacket);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flush all waiting packets
|
||||||
|
*/
|
||||||
public abstract void flush();
|
public abstract void flush();
|
||||||
|
|
||||||
public abstract SocketAddress getRemoteAddress();
|
public abstract SocketAddress getRemoteAddress();
|
||||||
@ -54,14 +69,31 @@ public abstract class PlayerConnection {
|
|||||||
*/
|
*/
|
||||||
public abstract void disconnect();
|
public abstract void disconnect();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the player linked to this connection
|
||||||
|
*
|
||||||
|
* @return the player
|
||||||
|
*/
|
||||||
public Player getPlayer() {
|
public Player getPlayer() {
|
||||||
return player;
|
return player;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the player linked to this connection
|
||||||
|
* <p>
|
||||||
|
* WARNING: unsafe
|
||||||
|
*
|
||||||
|
* @param player the player
|
||||||
|
*/
|
||||||
public void setPlayer(Player player) {
|
public void setPlayer(Player player) {
|
||||||
this.player = player;
|
this.player = player;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get if the client is still connected to the server
|
||||||
|
*
|
||||||
|
* @return true if the player is online, false otherwise
|
||||||
|
*/
|
||||||
public boolean isOnline() {
|
public boolean isOnline() {
|
||||||
return online;
|
return online;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user