Как запускать код на стороне сервера?

Версия Minecraft
1.16.5
API
Forge
87
4
11
У меня есть код, который выдает предмет игроку, но это происходит только на стороне клиента. Этот код находится в классе, который расширяет ContainerScreen, if (!level.isClientSide) не помогает. В коде команды give не нашел ничего полезного. Как решить эту проблему?
Вот код:
Java:
protected void giveButtonPressed(){
    if (!inventory.player.level.isClientSide) {
        inventory.add(new ItemStack(getItemByStrID(menu.nbtData.getString("itemID")), quantity));
    }
}
Заранее спасибо :)
 
Решение
Ну, ты ещё можешь просто через пакет выполнить то, что тебе нужно. Если через гуи, то так обычно и делается, например жмёшь кнопку - отправляешь пакет с клиента на сервер, где уже выполняется.
30
2
5
Ну, ты ещё можешь просто через пакет выполнить то, что тебе нужно. Если через гуи, то так обычно и делается, например жмёшь кнопку - отправляешь пакет с клиента на сервер, где уже выполняется.
 
87
4
11
Ну, ты ещё можешь просто через пакет выполнить то, что тебе нужно. Если через гуи, то так обычно и делается, например жмёшь кнопку - отправляешь пакет с клиента на сервер, где уже выполняется.
Тогда появляется вопрос: как записать ItemStack в ByteBuf? Нашел решение только для 1.7.10, там использовался ByteBufUtils, но на 1.16.5 у него есть только один метод: getContentDump()
 
87
4
11
Ну, ты ещё можешь просто через пакет выполнить то, что тебе нужно. Если через гуи, то так обычно и делается, например жмёшь кнопку - отправляешь пакет с клиента на сервер, где уже выполняется.
Что именно нужно обработать через пакет?
 
1,371
112
241
По нажатию кнопки отсылаешь пакет на сервер. Этот пакет приходит в тайл/контейнер. После получения пакета отправляешь пакет с сервера на клиент, содержащий в себе предмет. При получении пакета на клиенте вставляешь в клиентский контейнер предмет и обновляешь гуи.
 
87
4
11
По нажатию кнопки отсылаешь пакет на сервер. Этот пакет приходит в тайл/контейнер. После получения пакета отправляешь пакет с сервера на клиент, содержащий в себе предмет. При получении пакета на клиенте вставляешь в клиентский контейнер предмет и обновляешь гуи.
Звучит страшно😱, сейчас буду пробовать. То есть я отправляю пакет на сервер, в котором содержится предмет/тип предмета и в TileEntity добавляю его в инвентарь? Если да, то как через ByteBuf передать предмет/тип предмета? Пробовал через ByteBufUtils, но на 1.16.5 не работает.
 
87
4
11
Я всё сделал!!! Отправляется пакет после нажатия на кнопку, через него вызывается метод, в котором добавляется предмет!
Вот код:
Java:
public class BuyBtnMessagePacket {

    public final ItemStack sellItemStack;
    public final String playerUUID;
    public final int quantity;

    public BuyBtnMessagePacket(ItemStack itemStack, String playerUUID, int quantity) {
        this.sellItemStack = itemStack;
        this.playerUUID = playerUUID;
        this.quantity = quantity;
    }

    public BuyBtnMessagePacket(PacketBuffer byteBuf){
        this(byteBuf.readItem(), byteBuf.readUtf(), byteBuf.readInt());
    }
    public void encode(PacketBuffer byteBuf){
        byteBuf.writeItem(this.sellItemStack);
        byteBuf.writeUtf(this.playerUUID);
        byteBuf.writeInt(this.quantity);
    }

    public boolean handle(Supplier<NetworkEvent.Context> ctx) {
        final AtomicBoolean success = new AtomicBoolean(false);
        ctx.get().enqueueWork(() -> {
            PlayerEntity playerEntity = ctx.get().getSender().getLevel().getPlayerByUUID(UUID.fromString(this.playerUUID));
            PlayerInventory playerInventory = playerEntity.inventory;
            buyButtonPressed(playerInventory, sellItemStack, quantity);
            success.set(true);
        });

        ctx.get().setPacketHandled(true);
        return success.get();
    }

}
Пожайлуста, дайте знать, если может быть пакетхак.
Всем огромное спасибо за помощь :0 Особенно mudblood и _SupCM!
 
Последнее редактирование:
1,074
72
372
Неплохо для новичка, однако есть проблемы:
  • Вылетит NPE если игрока с указанным UUID нет на сервере.
  • UUID записывается в пакет в виде двух long (most&least), строка весит больше.
  • Использовать Int для передачи количества тоже слишком жирно. short хватит за глаза или byte, если кол-во не более 64 ед.

Пожайлуста, дайте знать, если может быть пакетхак.
Зачем передавать предмет с клиента на сервер вообще? Для справки: все предметы находятся на сервере, с ними взаимодействуют путём указания номера слота в инвентаре.
 
87
4
11
Неплохо для новичка
Спасибо) По UUID вообще проблем нет. Только игрок с таким же UUID сможет выдать себе предмет.
Зачем передавать предмет с клиента на сервер вообще? Для справки: все предметы находятся на сервере, с ними взаимодействуют путём указания номера слота в инвентаре.
ItemStack я беру из класса, который расширяет ContainerScreen. Мне сказали то что он клиентский, и как я понял, оттуда его только через пакет получить. В принципе у меня ID предмета записан в NBT TileEntity могу его оттуда брать, но мне тогда в PacketBuf надо еще BlockPos передавать. В любом случае, думаю так будет нормально.
 
Последнее редактирование:
Сверху