Открытие мультиссела 140 протокол

  • Автор темы Автор темы romash
  • Дата начала Дата начала

romash

Выдающийся
Местный
Легенда Истоков
Сообщения
298
Розыгрыши
0
Решения
1
Репутация
0
Реакции
66
Баллы
1 390
Всем ку. Когда через альтб открываем мультисел, окно мультиселла появляется за окном альтб. Хочу переделать чтобы открывалось на передний план. Может кто-то подсказать где найти эту функцию? Думаю где-то в интерфейсе клиента, но с чего бы начать?
 
А разве не в последовательности пакетов дело? Если слать сначала ответ на кб, а потом мультисел?
 
А разве не в последовательности пакетов дело? Если слать сначала ответ на кб, а потом мультисел?
Возможно. Но как-то давно у одного из разрабов спрашивал, сказали это править в клиенте надо. Ну и я отложил это дело до лучших времен. На гифке объясню детали, возможно не всем понятно о чем речь.
 
romash, не, я так и подумал, как на гифке показано. ) Ну просто от того, что слать сначала будет зависеть, какое окно первьім откроется, мне кажется, єто самое простое решение, слать мультисел последним просто. Ну либо хотя бьі глянуть, как оно сейчас. ) А так закостьілить можно в интерфейсе вполне, в классе как мультисела, так и кб, либо делать мультисел активньім, либо слать в кб какой-то тег,по которому его задвигать на второй план и тд. Но мне кажется, что єто лишнее.
 
100% дело в очередности отправки пакетов - скорее всего сначала шлет пакет мультиселла, а потом уже пакет отображения коммунки.
Так что надо банально поискать где в сборке обрабатывается байпасс коммунки на мультиселлы и переставить местами там пару строк.
 
Check at xdat the multisell window and add the option alwaysOnTop, as i remember was the solution for me)
 
Java:
else if (command.startsWith("_bbsmultisell"))
{
    final String fullBypass = command.replace("_bbsmultisell;", "");
    final String[] buypassOptions = fullBypass.split(",");
    final int multisellId = Integer.parseInt(buypassOptions[0]);
    final String page = buypassOptions[1];
    returnHtml = HtmCache.getInstance().getHtm(player, "data/html/CommunityBoard/Custom/" + page + ".html");
    ThreadPool.schedule(() -> {
        MultisellData.getInstance().separateAndSend(multisellId, player, null, false);
    }, 100);
}
Вот такой костыль работает, но ровно до того момента пока не захочешь открыть еще один мультисел не закрывая текущий.
Если идеи как закостылить, чтобы всегда открывался мультисел на переднем плане?
bypass -h _bbsmultisell не работает.
Может какой-то пакет слать для принудительного закрытия мультисела перед открытием нового?
 
Последнее редактирование:
если чисто теоретически EX_MULTISELL_RESULT с результатом "фейл" послать? возможно это закроет текущее окно мультисела сразу?
Java:
package l2p.gameserver.network.s2c.multisell;

import l2p.gameserver.network.components.ServerPackets;
import l2p.gameserver.network.s2c.L2GameServerPacket;

public class ExMultisellResult extends L2GameServerPacket
{
    private final boolean _success;
    private final int _type, _count;

    public ExMultisellResult(boolean success, int type, int count)
    {
        _type = type;
        _count = count;
        _success = success;
    }

    @Override
    protected void writeImpl()
    {
        writeId(ServerPackets.EX_MULTISELL_RESULT);
        writeC(_success);
        writeD(_type);
        writeD(_count);
    }
}
 
если чисто теоретически EX_MULTISELL_RESULT с результатом "фейл" послать? возможно это закроет текущее окно мультисела сразу?
Java:
package l2p.gameserver.network.s2c.multisell;

import l2p.gameserver.network.components.ServerPackets;
import l2p.gameserver.network.s2c.L2GameServerPacket;

public class ExMultisellResult extends L2GameServerPacket
{
    private final boolean _success;
    private final int _type, _count;

    public ExMultisellResult(boolean success, int type, int count)
    {
        _type = type;
        _count = count;
        _success = success;
    }

    @Override
    protected void writeImpl()
    {
        writeId(ServerPackets.EX_MULTISELL_RESULT);
        writeC(_success);
        writeD(_type);
        writeD(_count);
    }
}
Не помогло
 
Psycho, а есть компилятор интерфейса? Изи можно и там закостьілить, чет типа, если ид мультисела -200, то закрьіваем окно нахер, ну и перед отркрьітием с кб сначала слать мультисел с ид -200, профит.
 
Или не юзать мобиуса в котором нихера не работает :pandaredlol:
Вон, на опенах через -h все нормально работает.
 
как выше сказано порядок отсылки пакетов , добавил сервис смены сабов было тоже самое пока не сменил порядок пакетов
 
как выше сказано порядок отсылки пакетов , добавил сервис смены сабов было тоже самое пока не сменил порядок пакетов
Серьезно? Ну расскажи за порядок отправки пакетов, че не так с ним.

Java:
else if (command.startsWith("_bbsmultisell"))
{
    final String fullBypass = command.replace("_bbsmultisell;", "");
    final String[] buypassOptions = fullBypass.split(",");
    final int multisellId = Integer.parseInt(buypassOptions[0]);
    final String page = buypassOptions[1];
    returnHtml = HtmCache.getInstance().getHtm(player, "data/html/CommunityBoard/Custom/" + page + ".html");
    MultisellData.getInstance().separateAndSend(multisellId, player, null, false);
}
 
Ну тут же у тебя начала шлется мультиселл, а потом уже судя по логике где-то там дальше по коду отправляется ShowBoard c returnHtml
т.е. клиент сначала получит пакет мультисела и покажет его, а потом пакет коммунки и покажет ее поверх окна мультисела.

логичней чет типа такого
Java:
        if (bypass.startsWith("_multisell"))
        {
            showPage(page, player);
            MultiSellHolder.getInstance().separateAndSend(listId, player, null, 0);
        }
 
Ну тут же у тебя начала шлется мультиселл, а потом уже судя по логике где-то там дальше по коду отправляется ShowBoard c returnHtml
т.е. клиент сначала получит пакет мультисела и покажет его, а потом пакет коммунки и покажет ее поверх окна мультисела.

логичней чет типа такого
Java:
        if (bypass.startsWith("_multisell"))
        {
            showPage(page, player);
            MultiSellHolder.getInstance().separateAndSend(listId, player, null, 0);
        }
Да в принципе тоже самое
ровно до того момента пока не захочешь открыть еще один мультисел не закрывая текущий

Psycho, а есть компилятор интерфейса? Изи можно и там закостьілить, чет типа, если ид мультисела -200, то закрьіваем окно нахер, ну и перед отркрьітием с кб сначала слать мультисел с ид -200, профит.
Такое тоже пробовал :loltt0:
MultisellData.getInstance().separateAndSend(-200, player, null, false);

Посмотреть вложение Capture 2025-09-21 20-49-14-135.mp4
 
Последнее редактирование:
  • Вау
Реакции: Rolo
Psycho, та не, там такого нет. )

Код:
function HandelMultiSellInputItemInfo( string param )
{
    local int        nMultiSellInfoID;
    local int        nCurrentInputItemInfoIndex;
    local int        nItemClassID;
    local ItemInfo    info;

    // 신규 집혼 적용
    local int       ensoulNormalSlot, ensoulBmSlot;

    ParseItemID( param, info.Id );
    class'UIDATA_ITEM'.static.GetItemInfo( info.Id, info );

    ParseInt( param, "MultiSellInfoID",            nMultiSellInfoID );
    ParseInt( param, "ClassID",                    nItemClassID );
    ParseInt( param, "ItemType",                info.ItemType );
    ParseInt64( param, "ItemCount",                info.ItemNum);
    ParseInt( param, "Enchant",                    info.Enchanted );
    ParseInt( param, "RefineryOp1",                info.RefineryOp1);
    ParseInt( param, "RefineryOp2",                info.RefineryOp2);
    ParseInt( param, "AttrAttackType",            info.AttackAttributeType );
    ParseInt( param, "AttrAttackValue",            info.AttackAttributeValue );
    ParseInt( param, "AttrDefenseValueFire",    info.DefenseAttributeValueFire );
    ParseInt( param, "AttrDefenseValueWater",    info.DefenseAttributeValueWater );
    ParseInt( param, "AttrDefenseValueWind",    info.DefenseAttributeValueWind );
    ParseInt( param, "AttrDefenseValueEarth",    info.DefenseAttributeValueEarth );
    ParseInt( param, "AttrDefenseValueHoly",    info.DefenseAttributeValueHoly );
    ParseInt( param, "AttrDefenseValueUnholy",    info.DefenseAttributeValueUnholy );

    // 신규 집혼 추가 (2015-03-09)
    ParseInt( param, "EnsoulOptionNum_" $ EIST_BM    , ensoulBmSlot );
    ParseInt( param, "EnsoulOptionNum_" $ EIST_NORMAL, ensoulNormalSlot );

    // 아이템에 집혼 정보를 적용 시킴
    addEnsoulInfo(EIST_BM     , ensoulBmSlot, param, info);
    addEnsoulInfo(EIST_NORMAL , ensoulNormalSlot, param, info);

    if(m_MultiSellInfoList[m_nCurrentMultiSellInfoIndex].MultiSellInfoID != nMultiSellInfoID)
    {
        //debug("MultiSellWnd::HandelMultiSellInputItemInfo - Invalid nMultiSellInfoID");
        return;
    }
    
    if( nItemClassID == MSIT_PCCAFE_POINT )
    {
        info.Name = GetSystemString(1277);
        info.IconName = GetPcCafeItemIconPackageName();//"icon.etc_i.etc_pccafe_point_i00";
        info.Enchanted = 0;
        info.ItemType = -1;
        info.Id.ClassID = 0;
    }
    else if( nItemClassID == MSIT_PLEDGE_POINT )
    {
        info.Name = GetSystemString( 1311 );
        info.IconName = "icon.etc_i.etc_bloodpledge_point_i00";
        info.Enchanted = 0;
        info.ItemType = -1;
        info.Id.ClassID = 0;
    }   
    else if( nItemClassID == MSIT_PVP_POINT )
    {
        info.Name = GetSystemString( 102 );
        info.IconName = "icon.pvp_point_i00";
        info.Enchanted = 0;
        info.ItemType = -1;
        info.Id.ClassID = 0;
    }
    else if ( nItemClassID == MSIT_RAID_POINT )
    {
        info.Name  = GetSystemString( 3183 );
        info.IconName = "icon.etc_i.etc_rp_point_i00";
        info.Enchanted = 0;
        info.ItemType = -1;
        info.Id.ClassID = 0;
    }
    else
    {
        info.Name = class'UIDATA_ITEM'.static.GetItemName( info.Id );
        info.IconName = class'UIDATA_ITEM'.static.GetItemTextureName( info.Id );
    }

    // 이걸 왜 이렇게 하는지 의문.. 아이템 타입이 아니다.
    // info.ItemType = class'UIDATA_ITEM'.static.GetItemDataType( info.Id );
    info.CrystalType = class'UIDATA_ITEM'.static.GetItemCrystalType( info.Id );
    
    //-400 필드사이클일 경우 아무 데이터도 삽입 안하는 것으로 처리 함.
    if (nItemClassID != MSIT_FIELD_CYCLE_POINT )
    {
        // 결과 이후, 모두 보여줄때와, 입력 데이타만 업데이트
        //if (nRepeat == 1 && nShowAll == 1)
        //{
        //    if(m_MultiSellInfoList[m_nCurrentMultiSellInfoIndex].InputItemInfoList.Length > nRepeatTimeCurrentInputItemInfoIndex)
        //    {
        //        m_MultiSellInfoList[m_nCurrentMultiSellInfoIndex].InputItemInfoList[nRepeatTimeCurrentInputItemInfoIndex] = info;
        //        nRepeatTimeCurrentInputItemInfoIndex++;
        //    }
        //}
        //else
        //{
        //}

            nCurrentInputItemInfoIndex = m_MultiSellInfoList[m_nCurrentMultiSellInfoIndex].InputItemInfoList.Length;
            m_MultiSellInfoList[m_nCurrentMultiSellInfoIndex].InputItemInfoList.Length = nCurrentInputItemInfoIndex + 1;
            m_MultiSellInfoList[m_nCurrentMultiSellInfoIndex].InputItemInfoList[nCurrentInputItemInfoIndex] = info;

    }
}

Я предлагаю чет такое вкостьілить:
Код:
    if(-200 == nMultiSellInfoID)
    {
        OnClose_ButtonClick();
        return;
    }
 
Psycho, та не, там такого нет. )

Код:
function HandelMultiSellInputItemInfo( string param )
{
    local int        nMultiSellInfoID;
    local int        nCurrentInputItemInfoIndex;
    local int        nItemClassID;
    local ItemInfo    info;

    // 신규 집혼 적용
    local int       ensoulNormalSlot, ensoulBmSlot;

    ParseItemID( param, info.Id );
    class'UIDATA_ITEM'.static.GetItemInfo( info.Id, info );

    ParseInt( param, "MultiSellInfoID",            nMultiSellInfoID );
    ParseInt( param, "ClassID",                    nItemClassID );
    ParseInt( param, "ItemType",                info.ItemType );
    ParseInt64( param, "ItemCount",                info.ItemNum);
    ParseInt( param, "Enchant",                    info.Enchanted );
    ParseInt( param, "RefineryOp1",                info.RefineryOp1);
    ParseInt( param, "RefineryOp2",                info.RefineryOp2);
    ParseInt( param, "AttrAttackType",            info.AttackAttributeType );
    ParseInt( param, "AttrAttackValue",            info.AttackAttributeValue );
    ParseInt( param, "AttrDefenseValueFire",    info.DefenseAttributeValueFire );
    ParseInt( param, "AttrDefenseValueWater",    info.DefenseAttributeValueWater );
    ParseInt( param, "AttrDefenseValueWind",    info.DefenseAttributeValueWind );
    ParseInt( param, "AttrDefenseValueEarth",    info.DefenseAttributeValueEarth );
    ParseInt( param, "AttrDefenseValueHoly",    info.DefenseAttributeValueHoly );
    ParseInt( param, "AttrDefenseValueUnholy",    info.DefenseAttributeValueUnholy );

    // 신규 집혼 추가 (2015-03-09)
    ParseInt( param, "EnsoulOptionNum_" $ EIST_BM    , ensoulBmSlot );
    ParseInt( param, "EnsoulOptionNum_" $ EIST_NORMAL, ensoulNormalSlot );

    // 아이템에 집혼 정보를 적용 시킴
    addEnsoulInfo(EIST_BM     , ensoulBmSlot, param, info);
    addEnsoulInfo(EIST_NORMAL , ensoulNormalSlot, param, info);

    if(m_MultiSellInfoList[m_nCurrentMultiSellInfoIndex].MultiSellInfoID != nMultiSellInfoID)
    {
        //debug("MultiSellWnd::HandelMultiSellInputItemInfo - Invalid nMultiSellInfoID");
        return;
    }
   
    if( nItemClassID == MSIT_PCCAFE_POINT )
    {
        info.Name = GetSystemString(1277);
        info.IconName = GetPcCafeItemIconPackageName();//"icon.etc_i.etc_pccafe_point_i00";
        info.Enchanted = 0;
        info.ItemType = -1;
        info.Id.ClassID = 0;
    }
    else if( nItemClassID == MSIT_PLEDGE_POINT )
    {
        info.Name = GetSystemString( 1311 );
        info.IconName = "icon.etc_i.etc_bloodpledge_point_i00";
        info.Enchanted = 0;
        info.ItemType = -1;
        info.Id.ClassID = 0;
    }  
    else if( nItemClassID == MSIT_PVP_POINT )
    {
        info.Name = GetSystemString( 102 );
        info.IconName = "icon.pvp_point_i00";
        info.Enchanted = 0;
        info.ItemType = -1;
        info.Id.ClassID = 0;
    }
    else if ( nItemClassID == MSIT_RAID_POINT )
    {
        info.Name  = GetSystemString( 3183 );
        info.IconName = "icon.etc_i.etc_rp_point_i00";
        info.Enchanted = 0;
        info.ItemType = -1;
        info.Id.ClassID = 0;
    }
    else
    {
        info.Name = class'UIDATA_ITEM'.static.GetItemName( info.Id );
        info.IconName = class'UIDATA_ITEM'.static.GetItemTextureName( info.Id );
    }

    // 이걸 왜 이렇게 하는지 의문.. 아이템 타입이 아니다.
    // info.ItemType = class'UIDATA_ITEM'.static.GetItemDataType( info.Id );
    info.CrystalType = class'UIDATA_ITEM'.static.GetItemCrystalType( info.Id );
   
    //-400 필드사이클일 경우 아무 데이터도 삽입 안하는 것으로 처리 함.
    if (nItemClassID != MSIT_FIELD_CYCLE_POINT )
    {
        // 결과 이후, 모두 보여줄때와, 입력 데이타만 업데이트
        //if (nRepeat == 1 && nShowAll == 1)
        //{
        //    if(m_MultiSellInfoList[m_nCurrentMultiSellInfoIndex].InputItemInfoList.Length > nRepeatTimeCurrentInputItemInfoIndex)
        //    {
        //        m_MultiSellInfoList[m_nCurrentMultiSellInfoIndex].InputItemInfoList[nRepeatTimeCurrentInputItemInfoIndex] = info;
        //        nRepeatTimeCurrentInputItemInfoIndex++;
        //    }
        //}
        //else
        //{
        //}

            nCurrentInputItemInfoIndex = m_MultiSellInfoList[m_nCurrentMultiSellInfoIndex].InputItemInfoList.Length;
            m_MultiSellInfoList[m_nCurrentMultiSellInfoIndex].InputItemInfoList.Length = nCurrentInputItemInfoIndex + 1;
            m_MultiSellInfoList[m_nCurrentMultiSellInfoIndex].InputItemInfoList[nCurrentInputItemInfoIndex] = info;

    }
}

Я предлагаю чет такое вкостьілить:
Код:
    if(-200 == nMultiSellInfoID)
    {
        OnClose_ButtonClick();
        return;
    }
Думаешь это только в 140 проте такая херня?
 
Назад
Сверху