Не работает кастомный инвентарь

Версия Minecraft
1.12.2
1,470
19
189
При попытке открыть инвентарь, выбрасывает из мира и пишет в лог это
Java:
[19:05:54] [Netty Server IO #1/ERROR] [FML]: SimpleChannelHandlerWrapper exception
java.lang.NullPointerException: null
    at com.rcp.rcc.main.GuiHandler.getServerGuiElement(GuiHandler.java:23) ~[GuiHandler.class:?]
    at net.minecraftforge.fml.common.network.NetworkRegistry.getRemoteGuiContainer(NetworkRegistry.java:254) ~[NetworkRegistry.class:?]
    at net.minecraftforge.fml.common.network.internal.FMLNetworkHandler.openGui(FMLNetworkHandler.java:87) ~[FMLNetworkHandler.class:?]
    at net.minecraft.entity.player.EntityPlayer.openGui(EntityPlayer.java:2809) ~[EntityPlayer.class:?]
    at com.rcp.rcc.network.OpenInventoryMessage$Handler.onMessage(OpenInventoryMessage.java:37) ~[OpenInventoryMessage$Handler.class:?]
    at com.rcp.rcc.network.OpenInventoryMessage$Handler.onMessage(OpenInventoryMessage.java:27) ~[OpenInventoryMessage$Handler.class:?]
    at net.minecraftforge.fml.common.network.simpleimpl.SimpleChannelHandlerWrapper.channelRead0(SimpleChannelHandlerWrapper.java:56) ~[SimpleChannelHandlerWrapper.class:?]
    at net.minecraftforge.fml.common.network.simpleimpl.SimpleChannelHandlerWrapper.channelRead0(SimpleChannelHandlerWrapper.java:36) ~[SimpleChannelHandlerWrapper.class:?]
    at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105) ~[SimpleChannelInboundHandler.class:4.1.9.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [AbstractChannelHandlerContext.class:4.1.9.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [AbstractChannelHandlerContext.class:4.1.9.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) [AbstractChannelHandlerContext.class:4.1.9.Final]
    at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:102) [MessageToMessageDecoder.class:4.1.9.Final]
    at io.netty.handler.codec.MessageToMessageCodec.channelRead(MessageToMessageCodec.java:111) [MessageToMessageCodec.class:4.1.9.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [AbstractChannelHandlerContext.class:4.1.9.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [AbstractChannelHandlerContext.class:4.1.9.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) [AbstractChannelHandlerContext.class:4.1.9.Final]
    at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1334) [DefaultChannelPipeline$HeadContext.class:4.1.9.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [AbstractChannelHandlerContext.class:4.1.9.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [AbstractChannelHandlerContext.class:4.1.9.Final]
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:926) [DefaultChannelPipeline.class:4.1.9.Final]
    at io.netty.channel.embedded.EmbeddedChannel.writeInbound(EmbeddedChannel.java:274) [EmbeddedChannel.class:4.1.9.Final]
    at net.minecraftforge.fml.common.network.internal.FMLProxyPacket.processPacket(FMLProxyPacket.java:108) [FMLProxyPacket.class:?]
    at net.minecraft.network.NetworkManager.channelRead0(NetworkManager.java:155) [NetworkManager.class:?]
    at net.minecraft.network.NetworkManager.channelRead0(NetworkManager.java:49) [NetworkManager.class:?]
    at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105) [SimpleChannelInboundHandler.class:4.1.9.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [AbstractChannelHandlerContext.class:4.1.9.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [AbstractChannelHandlerContext.class:4.1.9.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) [AbstractChannelHandlerContext.class:4.1.9.Final]
    at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.handleServerSideCustomPacket(NetworkDispatcher.java:456) [NetworkDispatcher.class:?]
    at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.channelRead0(NetworkDispatcher.java:268) [NetworkDispatcher.class:?]
    at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.channelRead0(NetworkDispatcher.java:72) [NetworkDispatcher.class:?]
    at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105) [SimpleChannelInboundHandler.class:4.1.9.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [AbstractChannelHandlerContext.class:4.1.9.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [AbstractChannelHandlerContext.class:4.1.9.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) [AbstractChannelHandlerContext.class:4.1.9.Final]
    at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1334) [DefaultChannelPipeline$HeadContext.class:4.1.9.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [AbstractChannelHandlerContext.class:4.1.9.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [AbstractChannelHandlerContext.class:4.1.9.Final]
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:926) [DefaultChannelPipeline.class:4.1.9.Final]
    at io.netty.channel.local.LocalChannel.finishPeerRead0(LocalChannel.java:443) [LocalChannel.class:4.1.9.Final]
    at io.netty.channel.local.LocalChannel.access$500(LocalChannel.java:49) [LocalChannel.class:4.1.9.Final]
    at io.netty.channel.local.LocalChannel$5.run(LocalChannel.java:397) [LocalChannel$5.class:4.1.9.Final]
    at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163) [AbstractEventExecutor.class:4.1.9.Final]
    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:403) [SingleThreadEventExecutor.class:4.1.9.Final]
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:442) [NioEventLoop.class:4.1.9.Final]
    at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858) [SingleThreadEventExecutor$5.class:4.1.9.Final]
    at java.lang.Thread.run(Thread.java:748) [?:1.8.0_152]
[19:05:54] [Netty Server IO #1/ERROR] [FML]: There was a critical exception handling a packet on channel rcc
java.lang.NullPointerException: null
    at com.rcp.rcc.main.GuiHandler.getServerGuiElement(GuiHandler.java:23) ~[GuiHandler.class:?]
    at net.minecraftforge.fml.common.network.NetworkRegistry.getRemoteGuiContainer(NetworkRegistry.java:254) ~[NetworkRegistry.class:?]
    at net.minecraftforge.fml.common.network.internal.FMLNetworkHandler.openGui(FMLNetworkHandler.java:87) ~[FMLNetworkHandler.class:?]
    at net.minecraft.entity.player.EntityPlayer.openGui(EntityPlayer.java:2809) ~[EntityPlayer.class:?]
    at com.rcp.rcc.network.OpenInventoryMessage$Handler.onMessage(OpenInventoryMessage.java:37) ~[OpenInventoryMessage$Handler.class:?]
    at com.rcp.rcc.network.OpenInventoryMessage$Handler.onMessage(OpenInventoryMessage.java:27) ~[OpenInventoryMessage$Handler.class:?]
    at net.minecraftforge.fml.common.network.simpleimpl.SimpleChannelHandlerWrapper.channelRead0(SimpleChannelHandlerWrapper.java:56) ~[SimpleChannelHandlerWrapper.class:?]
    at net.minecraftforge.fml.common.network.simpleimpl.SimpleChannelHandlerWrapper.channelRead0(SimpleChannelHandlerWrapper.java:36) ~[SimpleChannelHandlerWrapper.class:?]
    at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105) ~[SimpleChannelInboundHandler.class:4.1.9.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) ~[AbstractChannelHandlerContext.class:4.1.9.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) ~[AbstractChannelHandlerContext.class:4.1.9.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) ~[AbstractChannelHandlerContext.class:4.1.9.Final]
    at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:102) ~[MessageToMessageDecoder.class:4.1.9.Final]
    at io.netty.handler.codec.MessageToMessageCodec.channelRead(MessageToMessageCodec.java:111) ~[MessageToMessageCodec.class:4.1.9.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) ~[AbstractChannelHandlerContext.class:4.1.9.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) ~[AbstractChannelHandlerContext.class:4.1.9.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) ~[AbstractChannelHandlerContext.class:4.1.9.Final]
    at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1334) ~[DefaultChannelPipeline$HeadContext.class:4.1.9.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) ~[AbstractChannelHandlerContext.class:4.1.9.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) ~[AbstractChannelHandlerContext.class:4.1.9.Final]
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:926) ~[DefaultChannelPipeline.class:4.1.9.Final]
    at io.netty.channel.embedded.EmbeddedChannel.writeInbound(EmbeddedChannel.java:274) ~[EmbeddedChannel.class:4.1.9.Final]
    at net.minecraftforge.fml.common.network.internal.FMLProxyPacket.processPacket(FMLProxyPacket.java:108) [FMLProxyPacket.class:?]
    at net.minecraft.network.NetworkManager.channelRead0(NetworkManager.java:155) [NetworkManager.class:?]
    at net.minecraft.network.NetworkManager.channelRead0(NetworkManager.java:49) [NetworkManager.class:?]
    at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105) [SimpleChannelInboundHandler.class:4.1.9.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [AbstractChannelHandlerContext.class:4.1.9.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [AbstractChannelHandlerContext.class:4.1.9.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) [AbstractChannelHandlerContext.class:4.1.9.Final]
    at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.handleServerSideCustomPacket(NetworkDispatcher.java:456) [NetworkDispatcher.class:?]
    at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.channelRead0(NetworkDispatcher.java:268) [NetworkDispatcher.class:?]
    at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.channelRead0(NetworkDispatcher.java:72) [NetworkDispatcher.class:?]
    at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105) [SimpleChannelInboundHandler.class:4.1.9.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [AbstractChannelHandlerContext.class:4.1.9.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [AbstractChannelHandlerContext.class:4.1.9.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) [AbstractChannelHandlerContext.class:4.1.9.Final]
    at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1334) [DefaultChannelPipeline$HeadContext.class:4.1.9.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [AbstractChannelHandlerContext.class:4.1.9.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [AbstractChannelHandlerContext.class:4.1.9.Final]
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:926) [DefaultChannelPipeline.class:4.1.9.Final]
    at io.netty.channel.local.LocalChannel.finishPeerRead0(LocalChannel.java:443) [LocalChannel.class:4.1.9.Final]
    at io.netty.channel.local.LocalChannel.access$500(LocalChannel.java:49) [LocalChannel.class:4.1.9.Final]
    at io.netty.channel.local.LocalChannel$5.run(LocalChannel.java:397) [LocalChannel$5.class:4.1.9.Final]
    at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163) [AbstractEventExecutor.class:4.1.9.Final]
    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:403) [SingleThreadEventExecutor.class:4.1.9.Final]
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:442) [NioEventLoop.class:4.1.9.Final]
    at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858) [SingleThreadEventExecutor$5.class:4.1.9.Final]
    at java.lang.Thread.run(Thread.java:748) [?:1.8.0_152]
[19:05:54] [Netty Server IO #1/ERROR] [FML]: Network Disconnect: A fatal error has occurred, this connection is terminated

Сам код
return new ContainerCustomInventory(player.inventory, inv.getInventory(), player);

В чем может быть проблема?

P.S. делал по тутору Тандера
 
Решение
Не знаю. Ты наверное где-то допустил ошибку. Это весь код смотреть надо. Вот человек делал в прошлой теме и все запустилось. Правда на 1.11.2. Но с 1.12 отличий не так уже и много. Создай новый мир и посмотри добавляется ли капа в эвенте игроку при заходе, тыкни туда маркер или System.out например. Или попробуй вместо AttachCapabilitiesEvent<EntityPlayer> просто AttachCapabilitiesEvent
1,470
19
189
Java:
public class CommonProxy {

    public void preInit(FMLPreInitializationEvent event){
        EventsReg.registerEvents();
    }

    public void init(FMLInitializationEvent event){
        CapabilityManager.INSTANCE.register(ICAPCustomInventory.class, new CAPCustomInventoryStorage(), CAPCustomInventory.class);
        CapabilityEventHandler.register();
        NetworkRegistry.INSTANCE.registerGuiHandler(RCC.INSTANCE, new GuiHandler());
    }

    public void postInit(FMLPostInitializationEvent event){

    }
}

Java:
public class ClientProxy extends CommonProxy {

    @Override
    public void preInit(FMLPreInitializationEvent event){
        super.preInit(event);
    }

    @Override
    public void init(FMLInitializationEvent event){
        super.init(event);
        KeyHandler.register();
    }

    @Override
    public void postInit(FMLPostInitializationEvent event){
        super.postInit(event);
    }
}

Java:
public class CapabilityEventHandler {

    public static void register(){
        MinecraftForge.EVENT_BUS.register(new CapabilityEventHandler());
    }

    public static final ResourceLocation INVENTORY_CAP = new ResourceLocation(MODID, "inventory");

    //ОЧЕНЬ ВАЖНО! Добавляет капу игроку при его первом создании
    @SubscribeEvent
    public void attachCapability(AttachCapabilitiesEvent<EntityPlayer> event) {
        if (event.getObject() instanceof EntityPlayer){
            event.addCapability(INVENTORY_CAP, new CAPCustomInventoryProvider());
        }
    }

    //Копирование инвентаря, если по каким-то причинам произошло клонирование игрока. Иначе вещи пропадут
    @SubscribeEvent
    public void onPlayerClone(PlayerEvent.Clone event) {

        EntityPlayer player = event.getEntityPlayer();
        ICAPCustomInventory newCap = player.getCapability(CAPCustomInventoryProvider.INVENTORY_CAP, null);
        ICAPCustomInventory oldCap = event.getOriginal().getCapability(CAPCustomInventoryProvider.INVENTORY_CAP, null);

        newCap.copyInventory(oldCap);

    }

    //Если игрок умрет то ничего не выпадет. Нужно выбросит вещи вручную. Выбрасываем
    @SubscribeEvent
    public void onPlayerDeath(LivingDeathEvent event) {
        if(event.getEntity() instanceof EntityPlayer) {
            //Достаем КАПу, затем инвентарь
            EntityPlayer player = (EntityPlayer)event.getEntity();
            ICAPCustomInventory cap = player.getCapability(CAPCustomInventoryProvider.INVENTORY_CAP, null);
            CustomInventory inv = cap.getInventory();

            //Выбрасываем все вещи из инвентаря
            dropAllItems(player, inv);
            inv.clear();
        }
    }

    private static void dropAllItems(EntityPlayer player, CustomInventory inventory){
        NonNullList<ItemStack> aitemstack = inventory.getStacks();
        for (int i = 0; i < aitemstack.size(); ++i) {
            if (!aitemstack.get(i).isEmpty()) {
                player.dropItem(aitemstack.get(i), true, false);
            }
        }
    }
 
1,470
19
189
Java:
@Mod(modid = MODID, name = NAME, version = VERSION, updateJSON = UpdateJSON)
public class RCC {

    @SidedProxy(clientSide = CLIENT_PROXY, serverSide = COMMON_PROXY)
    public static CommonProxy proxy;

    @Mod.Instance
    public static RCC INSTANCE = new RCC();

    @Mod.EventHandler
    public void preInit(FMLPreInitializationEvent event){
        NetworkHandler.init();
        proxy.preInit(event);
    }

    @Mod.EventHandler
    public void init(FMLInitializationEvent event){
        proxy.init(event);
    }

    @Mod.EventHandler
    public void postInit(FMLPostInitializationEvent event){
        proxy.postInit(event);
    }

    @Mod.EventHandler
    public static void metadata(FMLPreInitializationEvent event){
        ModMetadata meta = event.getModMetadata();
        meta.autogenerated  = false;
        meta.modId = MODID;
        meta.name = NAME;
        meta.version = VERSION;
        meta.updateJSON = UpdateJSON;
        meta.logoFile = "logo.png";
        meta.authorList.add("Nix13");
        meta.description = "Cool realism mod.";
        meta.credits = "Real Craft Project Team";
        meta.url = "https://nix1304.github.io/Real-Craft-Core/";
    }
}
 

Eifel

Модератор
1,624
79
609
Не знаю. Ты наверное где-то допустил ошибку. Это весь код смотреть надо. Вот человек делал в прошлой теме и все запустилось. Правда на 1.11.2. Но с 1.12 отличий не так уже и много. Создай новый мир и посмотри добавляется ли капа в эвенте игроку при заходе, тыкни туда маркер или System.out например. Или попробуй вместо AttachCapabilitiesEvent<EntityPlayer> просто AttachCapabilitiesEvent
 
1,470
19
189
Java:
public class KeyHandler {

    /*    Создаем бинд. Указываем название - Open Inventory
        Кнопка поумолчанию, если игрок ничего не менял будет H
         Название категории - Custom Inventory Keys

    */
    public static KeyBinding openKey = new KeyBinding("Open Inventory", Keyboard.KEY_H, "Custom Inventory Keys");

    //Регистрируем событие и бинд
    public static void register() {
        MinecraftForge.EVENT_BUS.register(new KeyHandler());
        ClientRegistry.registerKeyBinding(openKey);
    }

    //Событие, которое срабатывает при нажатии игроком кнопки на клавиатуре
    @SubscribeEvent
    public void onKey(KeyInputEvent event) {
        //если нажали на нашу кнопку Н то отправляем пакет на сервер с просьбой открыть инвентарь
        if (openKey.isPressed()) {

            NetworkHandler.network.sendToServer(new OpenInventoryMessage());
        }
    }
}

Java:
public class NetworkHandler {

    public static SimpleNetworkWrapper network;

    public static void init() {
        //инициализируем класс, что занимается передачей и обработкой пакетов между клиентом и сервером. TestMod.MOD_ID - айди мода.
        network = NetworkRegistry.INSTANCE.newSimpleChannel(MODID);

        /*    Регистрируем пакет. Параметры: класс обработчика(статический класс, который лежит внутри OpenInventoryMessage),
              класс самого сообщения, идентификатор, сторона, на которой будет обрабатываться пакет.
              Так как мы посылаем его на сервер, для открытия ГУИ менно оттуда, то указываем Side.SERVER
        */
        network.registerMessage(OpenInventoryMessage.Handler.class, OpenInventoryMessage.class, 0, Side.SERVER);
    }
}

Java:
public class OpenInventoryMessage implements IMessage {

    //Наша задача просто открыть ГУИ с серверной стороны, ничего больше передавать не нужно.

    //ОБЯЗАТЕЛЬНЫЙ конструктор без параметров
    public OpenInventoryMessage() {}

    @Override
    public void fromBytes(ByteBuf buf) {}

    @Override
    public void toBytes(ByteBuf buf) {}


    //Класс-обработчик пакета. Реализует метод onMessage, который срабатывает когда пакет приходит на сервер(в данном случае)

    public static class Handler implements IMessageHandler<OpenInventoryMessage, IMessage> {
        //Пишем тут то, что должно произойти когда пакет дойдет до сервера
        @Override
        public IMessage onMessage(OpenInventoryMessage message, MessageContext ctx) {
            /*    В данном случае достаем игрока, который отправил пакет и открываем ГУИ.
                TestMod.INSTANCE - инстанс главного класса, т.е. его обьект.
                Допустим имя главного класса TestMod, а modid = "testmod", тогда в главном классе пишем: @Mod.Instance("testmod") public static TestMod INSTANCE;
                 GuiHandler.INVENTORY_GUI_ID - идентификатор нашего ГУИ. Я присвоил значение 0.
            */
            EntityPlayerMP player = ctx.getServerHandler().player;
            player.openGui(RCC.INSTANCE, GuiHandler.INVENTORY_GUI_ID, player.getEntityWorld(), (int)player.posX, (int)player.posY, (int)player.posZ);
            return null;
        }
    }
}

Java:
public class CAPCustomInventory implements ICAPCustomInventory {

    //Реализуем методы, что определены в интерфейсе ICAPCustomInventory

    //Создаем обьект нашего инвентаря. Он будет храниться в этой КАП'е
    public final CustomInventory inventory = new CustomInventory();

    /**
     * Метод, который возвращает обьект инвентаря inventory
     */
    public CustomInventory getInventory(){

        return this.inventory;
    }

    /**
     * Метод, для копировании информации из другого инвентаря, например при клонировании
     */
    @Override
    public void copyInventory(ICAPCustomInventory inventory) {

        this.inventory.copy(inventory.getInventory());
    }

}

Java:
public class CAPCustomInventoryProvider implements ICapabilitySerializable<NBTBase> {

    @CapabilityInject(ICAPCustomInventory.class)
    public static final Capability<ICAPCustomInventory> INVENTORY_CAP = null;

    private ICAPCustomInventory instance = INVENTORY_CAP.getDefaultInstance();

    @Override
    public boolean hasCapability(Capability<?> capability, EnumFacing facing) {

        return capability == INVENTORY_CAP;
    }

    @Override
    public <T> T getCapability(Capability<T> capability, EnumFacing facing) {

        return capability == INVENTORY_CAP ? INVENTORY_CAP.<T> cast(this.instance) : null;
    }

    @Override
    public NBTBase serializeNBT() {

        return INVENTORY_CAP.getStorage().writeNBT(INVENTORY_CAP, this.instance, null);
    }

    @Override
    public void deserializeNBT(NBTBase nbt) {

        INVENTORY_CAP.getStorage().readNBT(INVENTORY_CAP, this.instance, null, nbt);
    }

}

Java:
public class CAPCustomInventoryStorage implements Capability.IStorage<ICAPCustomInventory> {

    //Сохранение информации (т.е. предметов, что лежать в инвентаре) с помощью writeToNBT

    @Override
    public NBTBase writeNBT(Capability<ICAPCustomInventory> capability, ICAPCustomInventory instance, EnumFacing side) {

        NBTTagCompound properties = new NBTTagCompound();
        //Вызываем метод writeToNBT из инвентаря и записываем инфу о инвентаре с его помощью в тэг
        instance.getInventory().writeToNBT(properties);
        return properties;
    }

    //Чтение информации (т.е. предметов, что лежать в инвентаре) и добавление их в инвентарь с помощью readFromNBT
    @Override
    public void readNBT(Capability<ICAPCustomInventory> capability, ICAPCustomInventory instance, EnumFacing side, NBTBase nbt) {

        NBTTagCompound properties = (NBTTagCompound)nbt;
        //Вызываем метод readFromNBT из инвентаря и кладем в него(инв.) стаки которые хранились в тэге
        instance.getInventory().readFromNBT(properties);
    }

}

Java:
public interface ICAPCustomInventory {
    public void copyInventory(ICAPCustomInventory inventory);

    public CustomInventory getInventory();
}

Вроде все
 
1,470
19
189
1,470
19
189
А какие есть варианты поменять стандартный инвентарь на свой? Т.е. что бы по нажатию на е открывался мой

И еще... При наведение на предметы, не появляется тултип
 
1,470
19
189
А какие есть варианты поменять стандартный инвентарь на свой? Т.е. что бы по нажатию на е открывался мой
 
1,470
19
189
Убрал один ряд слотов и добавил еще один свой слот. Но крашит

Краш
Java:
Caused by: java.lang.ArrayIndexOutOfBoundsException: 40
    at java.util.Arrays$ArrayList.set(Arrays.java:3846) ~[?:1.8.0_152]
    at net.minecraft.util.NonNullList.set(NonNullList.java:57) ~[NonNullList.class:?]
    at com.rcp.rcc.player_inventory.CustomInventory.setInventorySlotContents(CustomInventory.java:105) ~[CustomInventory.class:?]
    at net.minecraft.inventory.Slot.putStack(Slot.java:97) ~[Slot.class:?]
    at net.minecraft.inventory.Container.setAll(Container.java:565) ~[Container.class:?]
    at net.minecraft.client.network.NetHandlerPlayClient.handleWindowItems(NetHandlerPlayClient.java:1314) ~[NetHandlerPlayClient.class:?]
    at net.minecraft.network.play.server.SPacketWindowItems.processPacket(SPacketWindowItems.java:68) ~[SPacketWindowItems.class:?]
    at net.minecraft.network.play.server.SPacketWindowItems.processPacket(SPacketWindowItems.java:13) ~[SPacketWindowItems.class:?]
    at net.minecraft.network.PacketThreadUtil$1.run(PacketThreadUtil.java:21) ~[PacketThreadUtil$1.class:?]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[?:1.8.0_152]
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[?:1.8.0_152]
    at net.minecraft.util.Util.runTask(Util.java:53) ~[Util.class:?]
    ... 15 more
Код
Java:
public class ContainerCustomInventory extends Container {
    //Немного кода из ванилы
    private static final EntityEquipmentSlot[] VALID_EQUIPMENT_SLOTS = new EntityEquipmentSlot[] {EntityEquipmentSlot.HEAD, EntityEquipmentSlot.CHEST, EntityEquipmentSlot.LEGS, EntityEquipmentSlot.FEET};

    private final EntityPlayer thePlayer;

    /**
     * Конструктор
     * @param playerInventory Инвентарь игрока
     * @param cInventory Кастомный инвентарь
     * @param player Игрок
     */
    public ContainerCustomInventory(InventoryPlayer playerInventory, CustomInventory cInventory, EntityPlayer player) {
        this.thePlayer = player;

        //Добавляем 8 кастомных слотов. Аргументы: игрок, инвентарь к которому они относятся, индекс слота, х координата, у координата
        this.addSlotToContainer(new AdditionalSlot(player, cInventory, 0, 98, 8));
        this.addSlotToContainer(new AdditionalSlot(player, cInventory, 1, 98, 26));
        this.addSlotToContainer(new AdditionalSlot(player, cInventory, 2, 98, 44));
        this.addSlotToContainer(new AdditionalSlot(player, cInventory, 3, 98, 62));
        this.addSlotToContainer(new AdditionalSlot(player, cInventory, 4, 116, 8));
        this.addSlotToContainer(new AdditionalSlot(player, cInventory, 5, 116, 26));
        this.addSlotToContainer(new AdditionalSlot(player, cInventory, 6, 116, 44));
        this.addSlotToContainer(new AdditionalSlot(player, cInventory, 7, 116, 62));


        //Все что ниже можно взять из net.minecraft.inventory.ContainerPlayer;
        //Добавляем ванильные слоты для брони
        for (int k = 0; k < 4; ++k){
            final EntityEquipmentSlot entityequipmentslot = VALID_EQUIPMENT_SLOTS[k];
            this.addSlotToContainer(new Slot(playerInventory, 36 + (3 - k), 8, 8 + k * 18){
                public int getSlotStackLimit(){
                    return 1;
                }

                public boolean isItemValid(ItemStack stack){
                    return stack.getItem().isValidArmor(stack, entityequipmentslot, thePlayer);
                }

                public boolean canTakeStack(EntityPlayer playerIn){
                    ItemStack itemstack = this.getStack();
                    return !itemstack.isEmpty() && !playerIn.isCreative() && EnchantmentHelper.hasBindingCurse(itemstack) ? false : super.canTakeStack(playerIn);
                }
                @Nullable
                @SideOnly(Side.CLIENT)
                public String getSlotTexture(){
                    return ItemArmor.EMPTY_SLOT_NAMES[entityequipmentslot.getIndex()];
                }
            });
        }

        //Добавляем 18 ванильных слотов инвентаря игрока
        for (int l = 0; l < 2; ++l) {
            for (int j1 = 0; j1 < 9; ++j1) {
                this.addSlotToContainer(new Slot(playerInventory, j1 + (l + 1) * 9, 35 + j1 * 18, 102 + l * 18));
            }
        }

        //А так же добавляем 9 ванильных слотов в хотбар
        for (int i1 = 0; i1 < 9; ++i1) {
            this.addSlotToContainer(new Slot(playerInventory, i1, 35 + i1 * 18, 142));
        }

        this.addSlotToContainer(new BackpackSlot(player, cInventory, 40, 151, 62));
    }

    /**
     * Этот метод срабатывает когда игрок зажимает Шифт и кликает на слот с целью переместить предмет.
     * Здесь мы должны задать откуда и куда будут перемещаться предметы из слота по которому кликнули
     * @param index Индекс слота, на который кликнул игрок
     */
    @Nullable
    public ItemStack transferStackInSlot(EntityPlayer playerIn, int index) {
        ItemStack itemstack = ItemStack.EMPTY;
        Slot slot = (Slot)this.inventorySlots.get(index);


        //Если слот существует и он не пуст
        if (slot != null && slot.getHasStack()){

            //Достаем стак из слота
            ItemStack itemstack1 = slot.getStack();

            itemstack = itemstack1.copy();

            //Взаимодействие
            //Если индекс слота меньше 12, т.е. игрок уликнул на кастомный слот или слот брони
            if (index < 12){

                //Пытаемся переместить стак в ПЕРВЫЙ свободный слот в хотбаре или инвентаре, т.е. между 12 и 47 слотом
                if (!this.mergeItemStack(itemstack1, 12, 39, true)) {

                    return ItemStack.EMPTY;
                }

                slot.onSlotChange(itemstack1, itemstack);
            }

            //Здесь наоборот. Если игрок кликнул на слот в инвентаре или хотбаре
            else if (index > 11){

                //Если это броня, то ее надо переместить в первый подходящий для нее слот между 8 и 11 индексом
                if(itemstack1.getItem() instanceof ItemArmor){

                    //тут один момент. Почему передаем 12 а не 11? Потому что не включительно. Т.е. между 8 и 12 слотом не включительно
                    if (!this.mergeItemStack(itemstack1, 8, 12, false)){
                        return ItemStack.EMPTY;
                    }

                } else
                    //Если это не броня и мы в инвентаре но не в хотбаре(т.е. между 12 и 38 слотом), то помещаем предмет в хотбар, т.е. между 39 и 47 слотом
                    if (index >= 12 && index < 39){

                        if (!this.mergeItemStack(itemstack1, 12, 39, false)){
                            return ItemStack.EMPTY;
                        }
                    }else
                        //Если мы в хотбаре(т.е. между 39 и 47 слотом) то пытаемся переместить предмет в инвентарь(т.е. между в ПЕРВЫМ свободным слотом в инвентаре, т.е. между 12 и 38 слотом)
                        if (index >= 32 && index < 39 && !this.mergeItemStack(itemstack1, 32, 39, false)){
                            return ItemStack.EMPTY;
                        }
            }


            //Остальные простые проверки
            if (itemstack1.getCount() == 0){
                slot.putStack(ItemStack.EMPTY);
            }
            else{
                slot.onSlotChanged();
            }

            if (itemstack1.getCount() == itemstack.getCount()){
                return ItemStack.EMPTY;
            }

            slot.onTake(playerIn, itemstack1);
        }

        return itemstack;
    }

    /**
     * Может ли игрок взаимодействовать с инвентарем?
     */
    @Override
    public boolean canInteractWith(EntityPlayer playerIn) {
        return true;
    }

}
 
Сверху