Работа с пакетами

Версия Minecraft
1.12.2
170
2
53
Делаю мод на костюмы и столкнулся с такой проблемой, в мультиплеере игроки не видят костюмы других игроков. Костюм храниться в отдельном инвентаре, в собственной ячейке. Как я понял, нужно запросить у сервера предмет с этой ячейки у игрока, но я совершенно не понимаю как это сделать. Подскажите, как реализовать?

Код:
public class MainHandRenderHandler
{

    private static class CachedInventory
    {

        NonNullList<ItemStack> stacks;
        int state;

        CachedInventory(int size)
        {
            stacks = NonNullList.withSize(size, ItemStack.EMPTY);
            state = 0;
        }

    }

    public static boolean HideCosArmor = false;

    private static final boolean isBaublesLoaded = Loader.isModLoaded("baubles");

    private final LoadingCache<EntityPlayer, CachedInventory> cache = CacheBuilder.newBuilder().expireAfterAccess(60, TimeUnit.SECONDS).build(new CacheLoader<EntityPlayer, CachedInventory>()
    {

        @Override
        public CachedInventory load(EntityPlayer owner) throws Exception
        {
            return new CachedInventory(owner.inventory.mainInventory.size());
        }

    });

    @SubscribeEvent(priority = EventPriority.LOWEST, receiveCanceled = true)
    public void handleCanceledEvent(RenderPlayerEvent.Pre event)
    {
        if (!event.isCanceled())
            return;

        CachedInventory cachedInv = cache.getUnchecked(event.getEntityPlayer());
        NonNullList<ItemStack> cachedArmor = cachedInv.stacks;
        NonNullList<ItemStack> armor = event.getEntityPlayer().inventory.mainInventory;

        if (armor.size() > cachedArmor.size())
        {
            cache.invalidate(event.getEntityPlayer());
            return;
        }

        if (cachedInv.state != 0)
        {
            for (int i = 0; i < armor.size(); i++)
                armor.set(i, cachedArmor.get(i));

            if (isBaublesLoaded)
            {
                try
                {
                    IBaublesItemHandler bh = BaublesApi.getBaublesHandler(event.getEntityPlayer());
                    boolean block = bh.isEventBlocked();
                    bh.setEventBlock(true);
                    for (int i = 0; i < bh.getSlots(); i++)
                        bh.setStackInSlot(i, cachedArmor.get(9 + i));
                    bh.setEventBlock(block);
                }
                catch (Throwable ignored)
                {
                }
            }

            cachedInv.state = 0;
        }
    }

    @SubscribeEvent(priority = EventPriority.HIGH)
    public void handleEvent(RenderPlayerEvent.Post event)
    {
        CachedInventory cachedInv = cache.getUnchecked(event.getEntityPlayer());
        NonNullList<ItemStack> cachedArmor = cachedInv.stacks;
        NonNullList<ItemStack> armor = event.getEntityPlayer().inventory.mainInventory;

        if (armor.size() > cachedArmor.size())
        {
            cache.invalidate(event.getEntityPlayer());
            return;
        }

        if (cachedInv.state != 0)
        {
            for (int i = 0; i < armor.size(); i++)
                armor.set(i, cachedArmor.get(i));

            if (isBaublesLoaded)
            {
                try
                {
                    IBaublesItemHandler bh = BaublesApi.getBaublesHandler(event.getEntityPlayer());
                    boolean block = bh.isEventBlocked();
                    bh.setEventBlock(true);
                    for (int i = 0; i < bh.getSlots(); i++)
                        bh.setStackInSlot(i, cachedArmor.get(9 + i));
                    bh.setEventBlock(block);
                }
                catch (Throwable ignored)
                {
                }
            }

            cachedInv.state = 0;
        }
    }

    @SubscribeEvent(priority = EventPriority.HIGH, receiveCanceled = true)
    public void handleEvent(RenderPlayerEvent.Pre event)
    {
        CachedInventory cachedInv = cache.getUnchecked(event.getEntityPlayer());
        NonNullList<ItemStack> cachedArmor = cachedInv.stacks;
        EntityPlayer player = event.getEntityPlayer(); // ВОТ ТУТ ВОТ Я БЕРУ ИГРОКА И ПОЛУЧАЮ ЕГО ИНВЕНТАРЬ
        ICAPCustomInventory cap = player.getCapability(CAPCustomInventoryProvider.INVENTORY_CAP, null);
        CustomInventory cosArmor = cap.getInventory();
        NonNullList<ItemStack> armor = event.getEntityPlayer().inventory.mainInventory;

        if (armor.size() > cachedArmor.size())
        {
            cache.invalidate(event.getEntityPlayer());
            return;
        }

        if (cachedInv.state != 0)
        {
            for (int i = 0; i < armor.size(); i++)
                armor.set(i, cachedArmor.get(i));

            if (isBaublesLoaded)
            {
                try
                {
                    IBaublesItemHandler bh = BaublesApi.getBaublesHandler(event.getEntityPlayer());
                    boolean block = bh.isEventBlocked();
                    bh.setEventBlock(true);
                    for (int i = 0; i < bh.getSlots(); i++)
                        bh.setStackInSlot(i, cachedArmor.get(9 + i));
                    bh.setEventBlock(block);
                }
                catch (Throwable ignored)
                {
                }
            }

            cachedInv.state = 0;
        }

        for (int i = 0; i < armor.size(); i++)
            cachedArmor.set(i, armor.get(i));

        cachedInv.state = 1;

        if (HideCosArmor)
            return;

        for (int i = 0; i < armor.size(); i++)
        {
            if (i < 9)
            {
                if (!cosArmor.getStackInSlot(7).isEmpty()) {
                    armor.set(player.inventory.currentItem, cosArmor.getStackInSlot(7)); //тут указываю предмет который нужно рендерить.
                }
            }
        }

        if (isBaublesLoaded)
        {
            try
            {
                IBaublesItemHandler bh = BaublesApi.getBaublesHandler(event.getEntityPlayer());
                boolean block = bh.isEventBlocked();
                bh.setEventBlock(true);
                for (int i = 0; i < bh.getSlots(); i++)
                {
                    if (!cosArmor.getStackInSlot(7).isEmpty()) {
                        bh.setStackInSlot(player.inventory.currentItem, cosArmor.getStackInSlot(i));
                    }
                    else
                        bh.setStackInSlot(player.inventory.currentItem, ItemStack.EMPTY);
                }
                bh.setEventBlock(block);
            }
            catch (Throwable ignored)
            {
            }
        }
    }

}
 
Решение
Тебе нужно сихронизовать свой инвентарь с инвентарём на клиенте, и затем уже через капу получить свой предмет для рендера. А судя по коду, ты пытаешься достать из клиентской капы(которая пустая обычно) предметы, вот никто и не видит кроме тебя самого(и то вряд ли). Что касается пакета, то тем было много(как регистрировать пакеты учить не буду). Тебе нужно передать в свой пакет класс(к примеру MyCustomInventory), затем в toBytes
Java:
buf.writeInt(myInv.slots.size());
for (ItemStack stack : myInv.slots) {
    ByteBufUtils.writeItemStack(buf, stack);
}
далее в fromBytes:
Java:
final int size = buf.readInt();
stacks = new ArrayList<>(size);

for (int i = 0; i < size; i++) {
    stacks.add(ByteBufUtils.readItemStack(buf));
}
И уже в методе...

tox1cozZ

aka Agravaine
8,456
598
2,893
Это клиентский текущий игрок, которому приходит пакет. Нужно же чтобы клиент брал капу не у самого себя, а у другого игрока.
Пересылай в пакете getEntityID, а потом через world.getEntityByID(id) получай игрока.
 

Icosider

Kotliner
Администратор
3,603
99
664
Это клиентский текущий игрок, которому приходит пакет. Нужно же чтобы клиент брал капу не у самого себя, а у другого игрока.
Пересылай в пакете getEntityID, а потом через world.getEntityByID(id) получай игрока.
А я видимо не понял, какого он игрока имел ввиду, тогда да.
 
Сверху