Помогите Виртуальная книга

Статус
Закрыто для дальнейших ответов.

NukerFall

Активный участник
Пользователь
Баллы
76
Здрасте, форумчане. Недавно задался вопросом, каким образом можно открыть игроку книгу, не кладя её в инвентарь. Т.е. я хочу, чтобы, например, по команде /obk [игрок] у игрока появлялась перед глазами GUI книга с моим текстом. Возможно ли это вообще?
 
Здрасте, форумчане. Недавно задался вопросом, каким образом можно открыть игроку книгу, не кладя её в инвентарь. Т.е. я хочу, чтобы, например, по команде /obk [игрок] у игрока появлялась перед глазами GUI книга с моим текстом. Возможно ли это вообще?
Пакеты
 
Тебе нужно класть либо в правую либо в левую руку, потом оптравить пакет, либо вызвать метод EntityPlayer#a(ItemStack, EnumHand)
 
ProtocolLib + PacketWrapper.
Версия 1.13.
Использование:
Код:
        List<String> page1 = Arrays.asList(
                "Строка 1",
                "Строка 2");
        List<String> page2 = Arrays.asList(
                "Строка 3",
                "Строка 4");
        CustomBook book = new CustomBook("Название", "Автор", Arrays.asList(page1, page2));
        book.openFor(player);
Код:
import com.comphenix.packetwrapper.WrapperPlayServerCustomPayload;
import com.comphenix.protocol.wrappers.EnumWrappers;
import com.comphenix.protocol.wrappers.MinecraftKey;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.*********ventory.ItemStack;
import org.*********ventory.PlayerInventory;
import org.*********ventory.meta.BookMeta;

import java.util.ArrayList;
import java.util.List;

public class CustomBook {
    private static final WrapperPlayServerCustomPayload openBookPacket;

    static {
        //Невозможно использовать Player.sendPluginMessage(...), т.к. нельзя зарегистрировать канал от имени "minecraft"
        openBookPacket = new WrapperPlayServerCustomPayload();
        openBookPacket.setChannel(new MinecraftKey("book_open"));
        ByteBuf buf = Unpooled.buffer();
        buf.writeByte(EnumWrappers.Hand.MAIN_HAND.ordinal());
        openBookPacket.setContentsBuffer(buf);
    }

    private ItemStack stack;

    public CustomBook(String title, String author, List<List<String>> pages) {
        this.stack = new ItemStack(Material.WRITTEN_BOOK);
        BookMeta meta = (BookMeta) this.stack.getItemMeta();
        if(title != null)
            meta.setTitle(title);
        if (author != null)
            meta.setAuthor(author);
        List<String> pagesRaw = new ArrayList<>();
        for (List<String> page : pages) {
            StringBuilder lineBuilder = new StringBuilder();
            for(String line : page) {
                if(lineBuilder.length() > 0)
                    lineBuilder.append('\n');
                lineBuilder.append(line);
            }
            pagesRaw.add(lineBuilder.toString());
        }
        meta.setPages(pagesRaw);
        this.stack.setItemMeta(meta);
    }

    public void openFor(Player player) {
        PlayerInventory inv = player.getInventory();
        ItemStack old = inv.getItemInMainHand();
        inv.setItemInMainHand(this.stack);
        openBookPacket.sendPacket(player);
        inv.setItemInMainHand(old);
    }
}
 
Последнее редактирование:
ProtocolLib + PacketWrapper.
Версия 1.13.
Использование:
Код:
        List<String> page1 = Arrays.asList(
                "Строка 1",
                "Строка 2");
        List<String> page2 = Arrays.asList(
                "Строка 3",
                "Строка 4");
        CustomBook book = new CustomBook("Название", "Автор", Arrays.asList(page1, page2));
        book.openFor(player);
Код:
import com.comphenix.packetwrapper.WrapperPlayServerCustomPayload;
import com.comphenix.protocol.wrappers.EnumWrappers;
import com.comphenix.protocol.wrappers.MinecraftKey;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.*********ventory.ItemStack;
import org.*********ventory.PlayerInventory;
import org.*********ventory.meta.BookMeta;

import java.util.ArrayList;
import java.util.List;

public class CustomBook {
    private static final WrapperPlayServerCustomPayload openBookPacket;

    static {
        //Невозможно использовать Player.sendPluginMessage(...), т.к. нельзя зарегистрировать канал от имени "minecraft"
        openBookPacket = new WrapperPlayServerCustomPayload();
        openBookPacket.setChannel(new MinecraftKey("book_open"));
        ByteBuf buf = Unpooled.buffer();
        buf.writeByte(EnumWrappers.Hand.MAIN_HAND.ordinal());
        openBookPacket.setContentsBuffer(buf);
    }

    private ItemStack stack;

    public CustomBook(String title, String author, List<List<String>> pages) {
        this.stack = new ItemStack(Material.WRITTEN_BOOK);
        BookMeta meta = (BookMeta) this.stack.getItemMeta();
        if(title != null)
            meta.setTitle(title);
        if (author != null)
            meta.setAuthor(author);
        List<String> pagesRaw = new ArrayList<>();
        for (List<String> page : pages) {
            StringBuilder lineBuilder = new StringBuilder();
            for(String line : page) {
                if(lineBuilder.length() > 0)
                    lineBuilder.append('\n');
                lineBuilder.append(line);
            }
            pagesRaw.add(lineBuilder.toString());
        }
        meta.setPages(pagesRaw);
        this.stack.setItemMeta(meta);
    }

    public void openFor(Player player) {
        PlayerInventory inv = player.getInventory();
        ItemStack old = inv.getItemInMainHand();
        inv.setItemInMainHand(this.stack);
        openBookPacket.sendPacket(player);
        inv.setItemInMainHand(old);
    }
}
Неплохо. Но в итоге получается, что на некоторое время книга появляется, а затем сразу исчезает. Т.е. без этого никак(( Буду ждать пока в Bukkit добавят подобное сами
 
Неплохо. Но в итоге получается, что на некоторое время книга появляется, а затем сразу исчезает. Т.е. без этого никак(( Буду ждать пока в Bukkit добавят подобное сами
Да нормальное решение. Незаметно это.

В Bukkit не добавят - так работает ванильный клиент, что книга открывается, только если она есть в руке.
В 1.14 что-то сделают с книгами (по крайней мере с кафедрами), но эту механику, думаю, оставят без изменений.

Короче способов сделать это по-человечески сейчас как в принципе нет.
Ну, можешь клиент переписать самостоятельно...
 
Статус
Закрыто для дальнейших ответов.
Назад
Верх