Added CommandSender#isPlayer and CommandSender#isConsole

This commit is contained in:
Felix Cravic 2020-06-23 17:25:46 +02:00
parent 6ccd31e7fe
commit 9dfb9b657b
6 changed files with 88 additions and 18 deletions

View File

@ -78,9 +78,13 @@ public class Player extends LivingEntity implements CommandSender {
private PlayerSettings settings; private PlayerSettings settings;
private float exp; private float exp;
private int level; private int level;
private PlayerInventory inventory; private PlayerInventory inventory;
private short heldSlot;
private Inventory openInventory; private Inventory openInventory;
// Used internally to allow the closing of inventory within the inventory listener
private boolean didCloseInventory;
private short heldSlot;
private Position respawnPoint; private Position respawnPoint;
@ -1335,15 +1339,6 @@ public class Player extends LivingEntity implements CommandSender {
} }
} }
/**
* Get the player open inventory
*
* @return the currently open inventory, null if there is not (player inventory is not detected)
*/
public Inventory getOpenInventory() {
return openInventory;
}
/** /**
* Used to get the {@link CustomBlock} that the player is currently mining * Used to get the {@link CustomBlock} that the player is currently mining
* *
@ -1360,6 +1355,15 @@ public class Player extends LivingEntity implements CommandSender {
return Collections.unmodifiableSet(bossBars); return Collections.unmodifiableSet(bossBars);
} }
/**
* Get the player open inventory
*
* @return the currently open inventory, null if there is not (player inventory is not detected)
*/
public Inventory getOpenInventory() {
return openInventory;
}
/** /**
* Open the specified Inventory, close the previous inventory if existing * Open the specified Inventory, close the previous inventory if existing
* *
@ -1394,7 +1398,7 @@ public class Player extends LivingEntity implements CommandSender {
/** /**
* Close the current inventory if there is any * Close the current inventory if there is any
* It closes the player inventory if {@link #getOpenInventory()} returns null * It closes the player inventory (when opened) if {@link #getOpenInventory()} returns null
*/ */
public void closeInventory() { public void closeInventory() {
Inventory openInventory = getOpenInventory(); Inventory openInventory = getOpenInventory();
@ -1406,6 +1410,7 @@ public class Player extends LivingEntity implements CommandSender {
getInventory().setCursorItem(ItemStack.getAirItem()); getInventory().setCursorItem(ItemStack.getAirItem());
} else { } else {
cursorItem = openInventory.getCursorItem(this); cursorItem = openInventory.getCursorItem(this);
openInventory.setCursorItem(this, ItemStack.getAirItem());
} }
if (!cursorItem.isAir()) { if (!cursorItem.isAir()) {
// Add item to inventory if he hasn't been able to drop it // Add item to inventory if he hasn't been able to drop it
@ -1424,6 +1429,30 @@ public class Player extends LivingEntity implements CommandSender {
} }
playerConnection.sendPacket(closeWindowPacket); playerConnection.sendPacket(closeWindowPacket);
inventory.update(); inventory.update();
this.didCloseInventory = true;
}
/**
* Used internally to prevent an inventory click to be processed
* when the inventory listeners closed the inventory
* <p>
* Should only be used within an inventory listener (event or condition)
*
* @return true if the inventory has been closed, false otherwise
*/
public boolean didCloseInventory() {
return didCloseInventory;
}
/**
* Used internally to reset the didCloseInventory field
* <p>
* Shouldn't be used externally without proper understanding of its consequence
*
* @param didCloseInventory the new didCloseInventory field
*/
public void UNSAFE_changeDidCloseInventory(boolean didCloseInventory) {
this.didCloseInventory = didCloseInventory;
} }
/** /**

View File

@ -186,14 +186,34 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View
* Get the cursor item of a viewer * Get the cursor item of a viewer
* *
* @param player the player to get the cursor item from * @param player the player to get the cursor item from
* @return the player cursor item * @return the player cursor item, air item if the player is not a viewer
* @throws IllegalStateException if {@code player} is not in the viewer list
*/ */
public ItemStack getCursorItem(Player player) { public ItemStack getCursorItem(Player player) {
Check.stateCondition(!isViewer(player), "You can only get the cursor item of a viewer");
return cursorPlayersItem.getOrDefault(player, ItemStack.getAirItem()); return cursorPlayersItem.getOrDefault(player, ItemStack.getAirItem());
} }
/**
* Change the cursor item of a viewer,
* does nothing if {@param player} is not a viewer
*
* @param player the player to change the cursor item
* @param cursorItem the new player cursor item
*/
public void setCursorItem(Player player, ItemStack cursorItem) {
if (!isViewer(player))
return;
cursorItem = ItemStackUtils.notNull(cursorItem);
SetSlotPacket setSlotPacket = new SetSlotPacket();
setSlotPacket.windowId = -1;
setSlotPacket.slot = -1;
setSlotPacket.itemStack = cursorItem;
player.getPlayerConnection().sendPacket(setSlotPacket);
this.cursorPlayersItem.put(player, cursorItem);
}
private synchronized void safeItemInsert(int slot, ItemStack itemStack) { private synchronized void safeItemInsert(int slot, ItemStack itemStack) {
itemStack = ItemStackUtils.notNull(itemStack); itemStack = ItemStackUtils.notNull(itemStack);
this.itemStacks[slot] = itemStack; this.itemStacks[slot] = itemStack;

View File

@ -218,7 +218,13 @@ public class PlayerInventory implements InventoryModifier, InventoryClickHandler
* @param cursorItem the new cursor item * @param cursorItem the new cursor item
*/ */
public void setCursorItem(ItemStack cursorItem) { public void setCursorItem(ItemStack cursorItem) {
this.cursorItem = ItemStackUtils.notNull(cursorItem); cursorItem = ItemStackUtils.notNull(cursorItem);
this.cursorItem = cursorItem;
SetSlotPacket setSlotPacket = new SetSlotPacket();
setSlotPacket.windowId = -1;
setSlotPacket.slot = -1;
setSlotPacket.itemStack = cursorItem;
player.getPlayerConnection().sendPacket(setSlotPacket);
} }
/** /**
@ -233,7 +239,7 @@ public class PlayerInventory implements InventoryModifier, InventoryClickHandler
Check.argCondition(!MathUtils.isBetween(slot, 0, getSize()), Check.argCondition(!MathUtils.isBetween(slot, 0, getSize()),
"The slot " + slot + " does not exist for player"); "The slot " + slot + " does not exist for player");
Check.notNull(itemStack, "The ItemStack cannot be null, you can set air instead"); Check.notNull(itemStack, "The ItemStack cannot be null, you can set air instead");
EntityEquipmentPacket.Slot equipmentSlot; EntityEquipmentPacket.Slot equipmentSlot;
if (slot == player.getHeldSlot()) { if (slot == player.getHeldSlot()) {

View File

@ -532,6 +532,12 @@ public class InventoryClickProcessor {
} }
} }
// Cancel the click if the inventory has been closed by Player#closeInventory within an inventory listener
if (player.didCloseInventory()) {
clickResult.setCancel(true);
player.UNSAFE_changeDidCloseInventory(false);
}
} }
return clickResult; return clickResult;

View File

@ -90,6 +90,10 @@ public class WindowListener {
player.getPlayerConnection().sendPacket(windowConfirmationPacket); player.getPlayerConnection().sendPacket(windowConfirmationPacket);
} }
/**
* @param player the player to refresh the cursor item
* @param inventory the player open inventory, null if not any (could be player inventory)
*/
private static void refreshCursorItem(Player player, Inventory inventory) { private static void refreshCursorItem(Player player, Inventory inventory) {
PlayerInventory playerInventory = player.getInventory(); PlayerInventory playerInventory = player.getInventory();
@ -100,8 +104,10 @@ public class WindowListener {
cursorItem = playerInventory.getCursorItem(); cursorItem = playerInventory.getCursorItem();
} }
// Setting the window id properly seems to broke +64 stack support // Error occurred while retrieving the cursor item, stop here
//byte windowId = inventory == null ? 0 : inventory.getWindowId(); if (cursorItem == null) {
return;
}
SetSlotPacket setSlotPacket = new SetSlotPacket(); SetSlotPacket setSlotPacket = new SetSlotPacket();
setSlotPacket.windowId = -1; setSlotPacket.windowId = -1;

View File

@ -5,6 +5,9 @@ import net.minestom.server.item.ItemStack;
public class ItemStackUtils { public class ItemStackUtils {
/** /**
* Ensure that the returned ItemStack won't be null
* by replacing every null instance by a new Air one
*
* @param itemStack the ItemStack to return if not null * @param itemStack the ItemStack to return if not null
* @return {@code itemStack} if not null, {@link ItemStack#getAirItem()} otherwise * @return {@code itemStack} if not null, {@link ItemStack#getAirItem()} otherwise
*/ */