Merge pull request #3 from Minestom/master

Update PR 3
This commit is contained in:
MrBretzel 2021-04-21 23:54:32 +02:00 committed by GitHub
commit 189b8fd552
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 154 additions and 257 deletions

View File

@ -91,7 +91,7 @@ public final class UpdateManager {
}
// Flush all waiting packets
AsyncUtils.runAsync(() -> connectionManager.getOnlinePlayers().stream()
AsyncUtils.runAsync(() -> connectionManager.getOnlinePlayers().parallelStream()
.filter(player -> player.getPlayerConnection() instanceof NettyPlayerConnection)
.map(player -> (NettyPlayerConnection) player.getPlayerConnection())
.forEach(NettyPlayerConnection::flush));

View File

@ -60,7 +60,7 @@ public class ArgumentWord extends Argument<String> {
// Check restrictions (acting as literal)
if (hasRestrictions()) {
for (String r : restrictions) {
if (input.equalsIgnoreCase(r))
if (input.equals(r))
return input;
}
throw new ArgumentSyntaxException("Word needs to be in the restriction list", input, RESTRICTION_ERROR);

View File

@ -55,8 +55,7 @@ public abstract class AbstractInventory implements InventoryClickHandler, DataCo
public synchronized <T> @NotNull T processItemStack(@NotNull ItemStack itemStack,
@NotNull TransactionType type,
@NotNull TransactionOption<T> option) {
var pair = type.process(this, itemStack);
return option.fill(this, pair.left(), pair.right());
return option.fill(type, this, itemStack);
}
public synchronized <T> @NotNull List<@NotNull T> processItemStacks(@NotNull List<@NotNull ItemStack> itemStacks,

View File

@ -4,7 +4,6 @@ import net.kyori.adventure.text.Component;
import net.minestom.server.Viewable;
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.InventoryClickResult;
import net.minestom.server.item.ItemStack;
import net.minestom.server.network.packet.server.play.OpenWindowPacket;
@ -338,51 +337,21 @@ public class Inventory extends AbstractInventory implements Viewable {
final ItemStack clicked = isInWindow ? getItemStack(slot) : playerInventory.getItemStack(clickSlot);
final ItemStack cursor = getCursorItem(player); // Isn't used in the algorithm
final InventoryClickResult clickResult;
if (isInWindow) {
clickResult = clickProcessor.shiftClick(this, player, slot, clicked, cursor,
// Player inventory loop
new InventoryClickLoopHandler(0, PlayerInventory.INVENTORY_SIZE, 1,
PlayerInventoryUtils::convertToPacketSlot,
index -> isClickInWindow(index) ?
getItemStack(index) :
playerInventory.getItemStack(PlayerInventoryUtils.convertSlot(index, offset)),
(index, itemStack) -> {
if (isClickInWindow(index)) {
setItemStack(index, itemStack);
} else {
playerInventory.setItemStack(PlayerInventoryUtils.convertSlot(index, offset), itemStack);
}
}));
} else {
clickResult = clickProcessor.shiftClick(null, player, slot, clicked, cursor,
// Window loop
new InventoryClickLoopHandler(0, getSize(), 1,
i -> i,
index -> isClickInWindow(index) ?
getItemStack(index) :
playerInventory.getItemStack(PlayerInventoryUtils.convertSlot(index, offset)),
(index, itemStack) -> {
if (isClickInWindow(index)) {
setItemStack(index, itemStack);
} else {
playerInventory.setItemStack(PlayerInventoryUtils.convertSlot(index, offset), itemStack);
}
}));
}
final InventoryClickResult clickResult = clickProcessor.shiftClick(
isInWindow ? playerInventory : this,
isInWindow ? this : null,
player, slot, clicked, cursor);
if (clickResult == null)
return false;
if (clickResult.doRefresh()) {
updateFromClick(clickResult, player);
if (isInWindow) {
setItemStack(slot, clickResult.getClicked());
} else {
playerInventory.setItemStack(clickSlot, clickResult.getClicked());
}
refreshPlayerCursorItem(player, clickResult.getCursor());
playerInventory.update();
update();
return !clickResult.isCancel();
}
@ -498,17 +467,8 @@ public class Inventory extends AbstractInventory implements Viewable {
final ItemStack cursor = getCursorItem(player);
final boolean isInWindow = isClickInWindow(slot);
final InventoryClickResult clickResult = clickProcessor.doubleClick(isInWindow ? this : null, player, slot, cursor,
// Start by looping through the opened inventory
new InventoryClickLoopHandler(0, getSize(), 1,
i -> i,
this::getItemStack,
this::setItemStack),
// Looping through player inventory
new InventoryClickLoopHandler(0, PlayerInventory.INVENTORY_SIZE, 1,
PlayerInventoryUtils::convertToPacketSlot,
index -> playerInventory.getItemStack(index, PlayerInventoryUtils.OFFSET),
(index, itemStack) -> playerInventory.setItemStack(index, PlayerInventoryUtils.OFFSET, itemStack)));
final InventoryClickResult clickResult = clickProcessor.doubleClick(isInWindow ? this : playerInventory,
this, player, slot, cursor);
if (clickResult == null)
return false;

View File

@ -3,7 +3,6 @@ package net.minestom.server.inventory;
import net.minestom.server.entity.Player;
import net.minestom.server.event.item.ArmorEquipEvent;
import net.minestom.server.inventory.click.ClickType;
import net.minestom.server.inventory.click.InventoryClickLoopHandler;
import net.minestom.server.inventory.click.InventoryClickResult;
import net.minestom.server.inventory.condition.InventoryCondition;
import net.minestom.server.item.ItemStack;
@ -339,26 +338,17 @@ public class PlayerInventory extends AbstractInventory implements EquipmentHandl
public boolean shiftClick(@NotNull Player player, int slot) {
final ItemStack cursor = getCursorItem();
final ItemStack clicked = getItemStack(slot, OFFSET);
final boolean hotBarClick = convertToPacketSlot(slot) < 9;
final InventoryClickResult clickResult = clickProcessor.shiftClick(null, player, slot, clicked, cursor,
new InventoryClickLoopHandler(0, itemStacks.length, 1,
i -> {
if (hotBarClick) {
return i < 9 ? i + 9 : i - 9;
} else {
return convertPlayerInventorySlot(i, OFFSET);
}
},
index -> getItemStack(index, OFFSET),
(index, itemStack) -> setItemStack(index, OFFSET, itemStack)));
final boolean hotBarClick = convertSlot(slot, OFFSET) < 9;
final int start = hotBarClick ? 9 : 0;
final int end = hotBarClick ? getSize() - 9 : 8;
final InventoryClickResult clickResult = clickProcessor.shiftClick(this,
start, end, 1,
player, slot, clicked, cursor);
if (clickResult == null)
return false;
if (clickResult.doRefresh())
update();
setItemStack(slot, OFFSET, clickResult.getClicked());
setCursorItem(clickResult.getCursor());
return !clickResult.isCancel();
@ -415,12 +405,7 @@ public class PlayerInventory extends AbstractInventory implements EquipmentHandl
@Override
public boolean doubleClick(@NotNull Player player, int slot) {
final ItemStack cursor = getCursorItem();
final InventoryClickResult clickResult = clickProcessor.doubleClick(null, player, slot, cursor,
new InventoryClickLoopHandler(0, itemStacks.length, 1,
i -> i < 9 ? i + 9 : i - 9,
index -> itemStacks[index],
this::setItemStack));
final InventoryClickResult clickResult = clickProcessor.doubleClick(this, null, player, slot, cursor);
if (clickResult == null)
return false;
@ -428,6 +413,7 @@ public class PlayerInventory extends AbstractInventory implements EquipmentHandl
if (clickResult.doRefresh())
update();
setItemStack(slot, OFFSET, clickResult.getClicked());
setCursorItem(clickResult.getCursor());
return !clickResult.isCancel();

View File

@ -44,4 +44,11 @@ public interface TransactionOption<T> {
@NotNull T fill(@NotNull AbstractInventory inventory,
@NotNull ItemStack result,
@NotNull Map<@NotNull Integer, @NotNull ItemStack> itemChangesMap);
default @NotNull T fill(@NotNull TransactionType type,
@NotNull AbstractInventory inventory,
@NotNull ItemStack itemStack) {
var pair = type.process(inventory, itemStack);
return fill(inventory, pair.left(), pair.right());
}
}

View File

@ -19,13 +19,13 @@ public interface TransactionType {
* Adds an item to the inventory.
* Can either take an air slot or be stacked.
*/
TransactionType ADD = (inventory, itemStack) -> {
TransactionType ADD = (inventory, itemStack, slotPredicate, start, end, step) -> {
Int2ObjectMap<ItemStack> itemChangesMap = new Int2ObjectOpenHashMap<>();
final StackingRule stackingRule = itemStack.getStackingRule();
// Check filled slot (not air)
for (int i = 0; i < inventory.getInnerSize(); i++) {
for (int i = start; i < end; i += step) {
ItemStack inventoryItem = inventory.getItemStack(i);
if (inventoryItem.isAir()) {
continue;
@ -34,6 +34,12 @@ public interface TransactionType {
final int itemAmount = stackingRule.getAmount(inventoryItem);
if (itemAmount == stackingRule.getMaxSize())
continue;
if (!slotPredicate.test(i, inventoryItem)) {
// Cancelled transaction
continue;
}
final int itemStackAmount = stackingRule.getAmount(itemStack);
final int totalAmount = itemStackAmount + itemAmount;
if (!stackingRule.canApply(itemStack, totalAmount)) {
@ -50,11 +56,17 @@ public interface TransactionType {
}
// Check air slot to fill
for (int i = 0; i < inventory.getInnerSize(); i++) {
for (int i = start; i < end; i += step) {
ItemStack inventoryItem = inventory.getItemStack(i);
if (!inventoryItem.isAir()) {
continue;
}
if (!slotPredicate.test(i, inventoryItem)) {
// Cancelled transaction
continue;
}
// Fill the slot
itemChangesMap.put(i, itemStack);
itemStack = stackingRule.apply(itemStack, 0);
@ -68,15 +80,20 @@ public interface TransactionType {
* Takes an item from the inventory.
* Can either transform items to air or reduce their amount.
*/
TransactionType TAKE = (inventory, itemStack) -> {
TransactionType TAKE = (inventory, itemStack, slotPredicate, start, end, step) -> {
Int2ObjectMap<ItemStack> itemChangesMap = new Int2ObjectOpenHashMap<>();
final StackingRule stackingRule = itemStack.getStackingRule();
for (int i = 0; i < inventory.getInnerSize(); i++) {
for (int i = start; i < end; i += step) {
ItemStack inventoryItem = inventory.getItemStack(i);
if (inventoryItem.isAir()) {
continue;
}
if (stackingRule.canBeStacked(itemStack, inventoryItem)) {
if (!slotPredicate.test(i, inventoryItem)) {
// Cancelled transaction
continue;
}
final int itemAmount = stackingRule.getAmount(inventoryItem);
final int itemStackAmount = stackingRule.getAmount(itemStack);
if (itemStackAmount < itemAmount) {
@ -97,6 +114,23 @@ public interface TransactionType {
};
@NotNull Pair<ItemStack, Map<Integer, ItemStack>> process(@NotNull AbstractInventory inventory,
@NotNull ItemStack itemStack);
@NotNull ItemStack itemStack,
@NotNull SlotPredicate slotPredicate,
int start, int end, int step);
default @NotNull Pair<ItemStack, Map<Integer, ItemStack>> process(@NotNull AbstractInventory inventory,
@NotNull ItemStack itemStack,
@NotNull SlotPredicate slotPredicate) {
return process(inventory, itemStack, slotPredicate, 0, inventory.getInnerSize(), 1);
}
default @NotNull Pair<ItemStack, Map<Integer, ItemStack>> process(@NotNull AbstractInventory inventory,
@NotNull ItemStack itemStack) {
return process(inventory, itemStack, (slot, itemStack1) -> true);
}
@FunctionalInterface
interface SlotPredicate {
boolean test(int slot, @NotNull ItemStack itemStack);
}
}

View File

@ -1,53 +0,0 @@
package net.minestom.server.inventory.click;
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
import it.unimi.dsi.fastutil.ints.Int2ObjectFunction;
import net.minestom.server.item.ItemStack;
import java.util.function.BiConsumer;
public class InventoryClickLoopHandler {
private final int start;
private final int end;
private final int step;
private final Int2IntFunction indexModifier;
private final Int2ObjectFunction<ItemStack> itemGetter;
private final BiConsumer<Integer, ItemStack> itemSetter;
public InventoryClickLoopHandler(int start, int end, int step,
Int2IntFunction indexModifier,
Int2ObjectFunction<ItemStack> itemGetter,
BiConsumer<Integer, ItemStack> itemSetter) {
this.start = start;
this.end = end;
this.step = step;
this.indexModifier = indexModifier;
this.itemGetter = itemGetter;
this.itemSetter = itemSetter;
}
public int getStart() {
return start;
}
public int getEnd() {
return end;
}
public int getStep() {
return step;
}
public Int2IntFunction getIndexModifier() {
return indexModifier;
}
public Int2ObjectFunction<ItemStack> getItemGetter() {
return itemGetter;
}
public BiConsumer<Integer, ItemStack> getItemSetter() {
return itemSetter;
}
}

View File

@ -1,31 +1,37 @@
package net.minestom.server.inventory.click;
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
import it.unimi.dsi.fastutil.ints.Int2ObjectFunction;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet;
import net.minestom.server.entity.Player;
import net.minestom.server.event.inventory.InventoryClickEvent;
import net.minestom.server.event.inventory.InventoryPreClickEvent;
import net.minestom.server.inventory.AbstractInventory;
import net.minestom.server.inventory.Inventory;
import net.minestom.server.inventory.TransactionOption;
import net.minestom.server.inventory.TransactionType;
import net.minestom.server.inventory.condition.InventoryCondition;
import net.minestom.server.inventory.condition.InventoryConditionResult;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.StackingRule;
import net.minestom.server.utils.inventory.PlayerInventoryUtils;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
@ApiStatus.Internal
public class InventoryClickProcessor {
// Dragging maps
private final Map<Player, IntSet> leftDraggingMap = new HashMap<>();
private final Map<Player, IntSet> rightDraggingMap = new HashMap<>();
private final Map<Player, IntSet> leftDraggingMap = new ConcurrentHashMap<>();
private final Map<Player, IntSet> rightDraggingMap = new ConcurrentHashMap<>();
@NotNull
public InventoryClickResult leftClick(@Nullable Inventory inventory, @NotNull Player player, int slot,
@ -167,9 +173,8 @@ public class InventoryClickProcessor {
return clickResult;
}
@Nullable
public InventoryClickResult shiftClick(@Nullable Inventory inventory, @NotNull Player player, int slot,
@NotNull ItemStack clicked, @NotNull ItemStack cursor, @NotNull InventoryClickLoopHandler... loopHandlers) {
public @Nullable InventoryClickResult shiftClick(AbstractInventory targetInventory, @Nullable Inventory inventory, @NotNull Player player, int slot,
@NotNull ItemStack clicked, @NotNull ItemStack cursor) {
InventoryClickResult clickResult = startCondition(inventory, player, slot, ClickType.START_SHIFT_CLICK, clicked, cursor);
if (clickResult.isCancel()) {
@ -179,72 +184,36 @@ public class InventoryClickProcessor {
if (clicked.isAir())
return null;
final StackingRule clickedRule = clicked.getStackingRule();
var pair = TransactionType.ADD.process(targetInventory, clicked, (index, itemStack) -> {
InventoryClickResult result = startCondition(inventory, player, index, ClickType.SHIFT_CLICK, itemStack, cursor);
return !result.isCancel();
});
boolean filled = false;
ItemStack resultClicked = clicked;
ItemStack itemResult = TransactionOption.ALL.fill(targetInventory, pair.left(), pair.right());
clickResult.setClicked(itemResult);
return clickResult;
}
for (InventoryClickLoopHandler loopHandler : loopHandlers) {
final Int2IntFunction indexModifier = loopHandler.getIndexModifier();
final Int2ObjectFunction<ItemStack> itemGetter = loopHandler.getItemGetter();
final BiConsumer<Integer, ItemStack> itemSetter = loopHandler.getItemSetter();
public @Nullable InventoryClickResult shiftClick(@NotNull AbstractInventory targetInventory, int start, int end, int step, @NotNull Player player, int slot,
@NotNull ItemStack clicked, @NotNull ItemStack cursor) {
InventoryClickResult clickResult = startCondition(null, player, slot, ClickType.START_SHIFT_CLICK, clicked, cursor);
for (int i = loopHandler.getStart(); i < loopHandler.getEnd(); i += loopHandler.getStep()) {
final int index = indexModifier.apply(i);
if (index == slot)
continue;
ItemStack item = itemGetter.apply(index);
final StackingRule itemRule = item.getStackingRule();
if (itemRule.canBeStacked(item, clicked)) {
clickResult = startCondition(inventory, player, index, ClickType.SHIFT_CLICK, item, cursor);
if (clickResult.isCancel())
break;
final int amount = itemRule.getAmount(item);
if (!clickedRule.canApply(clicked, amount + 1))
continue;
final int totalAmount = clickedRule.getAmount(resultClicked) + amount;
if (!clickedRule.canApply(clicked, totalAmount)) {
item = itemRule.apply(item, itemRule.getMaxSize());
itemSetter.accept(index, item);
resultClicked = clickedRule.apply(resultClicked, totalAmount - clickedRule.getMaxSize());
filled = false;
callClickEvent(player, inventory, index, ClickType.SHIFT_CLICK, item, cursor);
continue;
} else {
resultClicked = clickedRule.apply(resultClicked, totalAmount);
itemSetter.accept(index, resultClicked);
item = itemRule.apply(item, 0);
itemSetter.accept(slot, item);
filled = true;
callClickEvent(player, inventory, index, ClickType.SHIFT_CLICK, item, cursor);
break;
}
} else if (item.isAir()) {
clickResult = startCondition(inventory, player, index, ClickType.SHIFT_CLICK, item, cursor);
if (clickResult.isCancel())
break;
// Switch
itemSetter.accept(index, resultClicked);
itemSetter.accept(slot, ItemStack.AIR);
filled = true;
break;
}
}
if (!filled) {
itemSetter.accept(slot, resultClicked);
}
if (clickResult.isCancel()) {
return clickResult;
}
if (clicked.isAir())
return null;
var pair = TransactionType.ADD.process(targetInventory, clicked, (index, itemStack) -> {
if (index == slot) // Prevent item lose/duplication
return false;
InventoryClickResult result = startCondition(null, player, index, ClickType.SHIFT_CLICK, itemStack, cursor);
return !result.isCancel();
}, start, end, step);
ItemStack itemResult = TransactionOption.ALL.fill(targetInventory, pair.left(), pair.right());
clickResult.setClicked(itemResult);
return clickResult;
}
@ -369,8 +338,8 @@ public class InventoryClickProcessor {
}
@Nullable
public InventoryClickResult doubleClick(@Nullable Inventory inventory, @NotNull Player player, int slot,
@NotNull ItemStack cursor, @NotNull InventoryClickLoopHandler... loopHandlers) {
public InventoryClickResult doubleClick(@NotNull AbstractInventory clickedInventory, @Nullable Inventory inventory, @NotNull Player player, int slot,
@NotNull final ItemStack cursor) {
InventoryClickResult clickResult = startCondition(inventory, player, slot, ClickType.START_DOUBLE_CLICK, ItemStack.AIR, cursor);
if (clickResult.isCancel()) {
@ -381,49 +350,46 @@ public class InventoryClickProcessor {
return null;
final StackingRule cursorRule = cursor.getStackingRule();
int amount = cursorRule.getAmount(cursor);
final int amount = cursorRule.getAmount(cursor);
final int remainingAmount = cursorRule.getMaxSize() - amount;
if (!cursorRule.canApply(cursor, amount + 1))
return null;
ItemStack remain = cursorRule.apply(cursor, remainingAmount);
for (InventoryClickLoopHandler loopHandler : loopHandlers) {
final Int2IntFunction indexModifier = loopHandler.getIndexModifier();
final Int2ObjectFunction<ItemStack> itemGetter = loopHandler.getItemGetter();
final BiConsumer<Integer, ItemStack> itemSetter = loopHandler.getItemSetter();
BiFunction<AbstractInventory, ItemStack, ItemStack> func = (inv, rest) -> {
var pair = TransactionType.TAKE.process(inv, rest, (index, itemStack) -> {
if (index == slot) // Prevent item lose/duplication
return false;
InventoryClickResult result = startCondition(inventory, player, index, ClickType.DOUBLE_CLICK, itemStack, cursor);
return !result.isCancel();
});
var itemResult = pair.left();
var map = pair.right();
return TransactionOption.ALL.fill(inv, itemResult, map);
};
for (int i = loopHandler.getStart(); i < loopHandler.getEnd(); i += loopHandler.getStep()) {
final int index = indexModifier.apply(i);
if (index == slot)
continue;
var playerInventory = player.getInventory();
ItemStack item = itemGetter.apply(index);
final StackingRule itemRule = item.getStackingRule();
if (!cursorRule.canApply(cursor, amount + 1))
break;
if (cursorRule.canBeStacked(cursor, item)) {
clickResult = startCondition(inventory, player, index, ClickType.DOUBLE_CLICK, item, cursor);
if (clickResult.isCancel())
break;
final int totalAmount = amount + cursorRule.getAmount(item);
if (!cursorRule.canApply(cursor, totalAmount)) {
cursor = cursorRule.apply(cursor, cursorRule.getMaxSize());
item = itemRule.apply(item, totalAmount - itemRule.getMaxSize());
} else {
cursor = cursorRule.apply(cursor, totalAmount);
item = itemRule.apply(item, 0);
}
itemSetter.accept(index, item);
amount = cursorRule.getAmount(cursor);
callClickEvent(player, inventory, index, ClickType.DOUBLE_CLICK, item, cursor);
}
if (Objects.equals(clickedInventory, inventory)) {
// Clicked inside inventory
remain = func.apply(inventory, remain);
if (!remain.isAir()) {
remain = func.apply(playerInventory, remain);
}
} else if (inventory != null && clickedInventory == playerInventory) {
// Clicked inside player inventory, but with another inventory open
remain = func.apply(playerInventory, remain);
if (!remain.isAir()) {
remain = func.apply(inventory, remain);
}
} else {
// Clicked inside player inventory
remain = func.apply(playerInventory, remain);
}
clickResult.setCursor(cursor);
final int tookAmount = remainingAmount - cursorRule.getAmount(remain);
ItemStack resultCursor = cursorRule.apply(cursor, amount + tookAmount);
clickResult.setCursor(resultCursor);
return clickResult;
}

View File

@ -71,10 +71,7 @@ public class ClientChannel extends SimpleChannelInboundHandler<InboundPacket> {
// Release tick buffer
if (playerConnection instanceof NettyPlayerConnection) {
final ByteBuf tickBuffer = ((NettyPlayerConnection) playerConnection).getTickBuffer();
synchronized (tickBuffer) {
tickBuffer.release();
}
((NettyPlayerConnection) playerConnection).releaseTickBuffer();
}
}
}

View File

@ -62,7 +62,8 @@ public class NettyPlayerConnection extends PlayerConnection {
private PlayerSkin bungeeSkin;
private final static int INITIAL_BUFFER_SIZE = 65_535; // 2^16-1
private final ByteBuf tickBuffer = BufUtils.getBuffer(true);
private final Object tickBufferLock = new Object();
private volatile ByteBuf tickBuffer = BufUtils.getBuffer(true);
public NettyPlayerConnection(@NotNull SocketChannel channel) {
super();
@ -119,7 +120,7 @@ public class NettyPlayerConnection extends PlayerConnection {
if (getPlayer() != null) {
// Flush happen during #update()
if (serverPacket instanceof CacheablePacket && MinecraftServer.hasPacketCaching()) {
synchronized (tickBuffer) {
synchronized (tickBufferLock) {
if (tickBuffer.refCnt() == 0)
return;
CacheablePacket.writeCache(tickBuffer, serverPacket);
@ -141,7 +142,7 @@ public class NettyPlayerConnection extends PlayerConnection {
public void write(@NotNull Object message, boolean skipTranslating) {
if (message instanceof FramedPacket) {
final FramedPacket framedPacket = (FramedPacket) message;
synchronized (tickBuffer) {
synchronized (tickBufferLock) {
if (tickBuffer.refCnt() == 0)
return;
final ByteBuf body = framedPacket.getBody();
@ -155,14 +156,14 @@ public class NettyPlayerConnection extends PlayerConnection {
serverPacket = ((ComponentHoldingServerPacket) serverPacket).copyWithOperator(component -> AdventureSerializer.translate(component, getPlayer()));
}
synchronized (tickBuffer) {
synchronized (tickBufferLock) {
if (tickBuffer.refCnt() == 0)
return;
PacketUtils.writeFramedPacket(tickBuffer, serverPacket);
}
return;
} else if (message instanceof ByteBuf) {
synchronized (tickBuffer) {
synchronized (tickBufferLock) {
if (tickBuffer.refCnt() == 0)
return;
tickBuffer.writeBytes((ByteBuf) message);
@ -193,11 +194,11 @@ public class NettyPlayerConnection extends PlayerConnection {
// Retrieve safe copy
final ByteBuf copy;
synchronized (tickBuffer) {
synchronized (tickBufferLock) {
if (tickBuffer.refCnt() == 0)
return;
copy = tickBuffer.copy();
tickBuffer.clear();
copy = tickBuffer;
tickBuffer = tickBuffer.alloc().buffer(tickBuffer.writerIndex());
}
// Write copied buffer to netty
@ -379,10 +380,10 @@ public class NettyPlayerConnection extends PlayerConnection {
}
}
@NotNull
public ByteBuf getTickBuffer() {
return tickBuffer;
public void releaseTickBuffer() {
synchronized (tickBufferLock) {
tickBuffer.release();
}
}
public byte[] getNonce() {