Отображение списка бафов в классике

  • Автор темы Автор темы Psycho
  • Дата начала Дата начала
Статус
В этой теме нельзя размещать новые ответы.

Psycho

Легенда
Хроники
  1. Chaotic Throne: High Five
Исходники
Присутствуют
Сборка
L2J
На мейне и эссенсе отображаются, а вот на классик версии отображение ломается.
Скорее всего нужно слать другое значение, но даже хз в каком классе смотреть.
Клиент 542.

Эссенс:
Screenshot_2.webp

Классик:
Screenshot_1.webp
 
S_ABNORMAL_STATUS_UPDATE

S_EX_ABNORMAL_STATUS_UPDATE_FROM_TARGET

Классик и эссенс, насколько я знаю, используют одни и те же версии пакетов.

Код:
        writeOpcode(ServerPacketOpcodes.S_ABNORMAL_STATUS_UPDATE);
        writeH(_effects.size());

        for (Abnormal temp : _effects) {
            writeD(temp.skillId);
            writeH(temp.skillLvl);
            writeH(temp.skillSubLvl);
            writeD(temp.abnormalType);
            writeH(temp.duration);
        }


Код:
        writeOpcode(ServerPacketOpcodes.S_EX_ABNORMAL_STATUS_UPDATE_FROM_TARGET);
        writeD(_objectId);
        writeH(_effects.size());
        for (Abnormal temp : _effects) {
            writeD(temp.skillId);
            writeH(temp.skillLvl);
            writeH(temp.subLevel);
            writeH(temp.abnormalType);
            writeH(temp.duration);
            writeD(temp.effectorObjectId); // Buffer OID
        }


Если структура верна - проверь активные эффекты, всё ли есть в датках классика
 
S_ABNORMAL_STATUS_UPDATE

S_EX_ABNORMAL_STATUS_UPDATE_FROM_TARGET

Классик и эссенс, насколько я знаю, используют одни и те же версии пакетов.

Код:
        writeOpcode(ServerPacketOpcodes.S_ABNORMAL_STATUS_UPDATE);
        writeH(_effects.size());

        for (Abnormal temp : _effects) {
            writeD(temp.skillId);
            writeH(temp.skillLvl);
            writeH(temp.skillSubLvl);
            writeD(temp.abnormalType);
            writeH(temp.duration);
        }


Код:
        writeOpcode(ServerPacketOpcodes.S_EX_ABNORMAL_STATUS_UPDATE_FROM_TARGET);
        writeD(_objectId);
        writeH(_effects.size());
        for (Abnormal temp : _effects) {
            writeD(temp.skillId);
            writeH(temp.skillLvl);
            writeH(temp.subLevel);
            writeH(temp.abnormalType);
            writeH(temp.duration);
            writeD(temp.effectorObjectId); // Buffer OID
        }


Если структура верна - проверь активные эффекты, всё ли есть в датках классика
Java:
public void writeImpl(GameClient client, WritableBuffer buffer)
    {
        ServerPackets.ABNORMAL_STATUS_UPDATE.writeId(this, buffer);
        buffer.writeShort(_effects.size());
        for (BuffInfo info : _effects)
        {
            if ((info != null) && info.isInUse())
            {
                final Skill skill = info.getSkill();
                buffer.writeInt(skill.getDisplayId());
                buffer.writeShort(SkillUtils.convertHFSkillLevelToGOD(skill.getDisplayId(), skill.getDisplayLevel()));
                buffer.writeShort(SkillUtils.convertHFSkillLevelToGODSubLevel(skill.getDisplayId(), skill.getDisplayLevel()));
                buffer.writeInt(skill.getAbnormalType().getClientId());
                writeOptionalInt((skill.isAura() || skill.isToggle()) ? -1 : info.getTime(), buffer);
            }
        }
    }
Java:
public void writeImpl(GameClient client, WritableBuffer buffer)
    {
        ServerPackets.EX_ABNORMAL_STATUS_UPDATE_FROM_TARGET.writeId(this, buffer);
        buffer.writeInt(_creature.getObjectId());
        buffer.writeShort(_effects.size());
        for (BuffInfo info : _effects)
        {
            final Skill skill = info.getSkill();
            buffer.writeInt(skill.getDisplayId());
            buffer.writeShort(skill.getDisplayLevel());
            buffer.writeShort(skill.getSubLevel());
            buffer.writeShort(skill.getAbnormalType().getClientId());
            writeOptionalInt(skill.isAura() ? -1 : info.getTime(), buffer);
            buffer.writeInt(info.getEffectorObjectId());
        }
    }

Ну skillgrp и skillname я распарсил с хф, на других версиях клиента отображаются бафы.
 
Там в классике на 1 h меньше записывается, я не знаю что именно там саб лвл или абнормал тип, ибо просто втыкнул чтоб было.
Java:
    // Model: Codex-GPT5.1 | Date: 2025-11-18 04:18:53 | Generated by agent | Task: map packet opcodes
    @Override
    public IServerPacketOpCode getPacketOpCode()
    {
        return ExServerPacketsOpCodes.S_EX_ABNORMAL_STATUS_UPDATE_FROM_TARGET;
    }
    // Model: Codex-GPT5.1 | Date: 2025-11-18 04:18:53 | Generated by agent | Task: map packet opcodes

    @Override
    public boolean write(PacketWriter packetWriter)
    {
        packetWriter.writeD(_objectId);
        packetWriter.writeH(_effects.size());
        for(Abnormal temp : _effects)
        {
            packetWriter.writeD(temp.skillId);
            packetWriter.writeH(temp.skillLvl);
            if (ConfigServer.GAME_VERSION.getGameServerMask() != ServerType.CLASSIC.getGameServerMask())
            {
                packetWriter.writeH(temp.skillSubLvl);
            }
            packetWriter.writeH(temp.abnormalType);
            writeOptionalD(packetWriter, temp.duration);
            packetWriter.writeD(temp.effectorObjectId); // Buffer OID
        }
        return true;
    }



kick яж не самоубийца в еру ИИ самому более 1000 файлов менять и ставить им опкоды :)
 
Java:
    // Model: Codex-GPT5.1 | Date: 2025-11-18 04:18:53 | Generated by agent | Task: map packet opcodes
    @Override
    public IServerPacketOpCode getPacketOpCode()
    {
        return ExServerPacketsOpCodes.S_EX_ABNORMAL_STATUS_UPDATE_FROM_TARGET;
    }
    // Model: Codex-GPT5.1 | Date: 2025-11-18 04:18:53 | Generated by agent | Task: map packet opcodes

    @Override
    public boolean write(PacketWriter packetWriter)
    {
        packetWriter.writeD(_objectId);
        packetWriter.writeH(_effects.size());
        for(Abnormal temp : _effects)
        {
            packetWriter.writeD(temp.skillId);
            packetWriter.writeH(temp.skillLvl);
            if (ConfigServer.GAME_VERSION.getGameServerMask() != ServerType.CLASSIC.getGameServerMask())
            {
                packetWriter.writeH(temp.skillSubLvl);
            }
            packetWriter.writeH(temp.abnormalType);
            writeOptionalD(packetWriter, temp.duration);
            packetWriter.writeD(temp.effectorObjectId); // Buffer OID
        }
        return true;
    }
Screenshot_7.webp

Всё гораздо проще:
Java:
public void writeImpl(GameClient client, WritableBuffer buffer)
    {
        ServerPackets.ABNORMAL_STATUS_UPDATE.writeId(this, buffer);
        buffer.writeShort(_effects.size());
        for (BuffInfo info : _effects)
        {
            if ((info != null) && info.isInUse())
            {
                final Skill skill = info.getSkill();
                buffer.writeInt(skill.getDisplayId());
                buffer.writeShort(skill.getDisplayLevel());
                // buffer.writeShort(skill.getSubLevel());
                buffer.writeInt(skill.getAbnormalType().getClientId());
                writeOptionalInt(skill.isAura() || skill.isToggle() ? -1 : info.getTime(), buffer);
            }
        }
    }

Да, саблевел, глянул в сорках классика.
 
Посмотреть вложение 94674

Всё гораздо проще:
Java:
public void writeImpl(GameClient client, WritableBuffer buffer)
    {
        ServerPackets.ABNORMAL_STATUS_UPDATE.writeId(this, buffer);
        buffer.writeShort(_effects.size());
        for (BuffInfo info : _effects)
        {
            if ((info != null) && info.isInUse())
            {
                final Skill skill = info.getSkill();
                buffer.writeInt(skill.getDisplayId());
                buffer.writeShort(skill.getDisplayLevel());
                // buffer.writeShort(skill.getSubLevel());
                buffer.writeInt(skill.getAbnormalType().getClientId());
                writeOptionalInt(skill.isAura() || skill.isToggle() ? -1 : info.getTime(), buffer);
            }
        }
    }

Да, саблевел, глянул в сорках классика.
из того что заметил, это еще в S_EX_EVENT_MATCH_SPELLED_INFO (ExEventMatchSpelledInfo) и в S_EX_OLYMPIAD_SPELLED_INFO (ExOlympiadSpelledInfoPacket).

Еще разница может быть в S_RECIPE_ITEM_MAKE_INFO / S_MY_TARGET_SELECTED / S_RECIPE_SHOP_ITEM_INFO / S_RECIPE_SHOP_SELL_LIST
 
Статус
В этой теме нельзя размещать новые ответы.
Назад
Сверху Снизу