Пакет для смены ника персонажа при входе игру

Glafferax

Путник
Местный
Сообщения
19
Розыгрыши
0
Репутация
0
Реакции
12
Баллы
0
Хроники
  1. Fafurion
Исходники
Присутствуют
Сборка
Солянка
Добрый день!
Нахожусь в поисках нужных опкодов и пакетов, которые используются для принудительной смены ника при входе в игру.
Например, такое используется после слияния двух серверов.

Подозреваю, что нужен некий флаг в данных о персонаже, вот только какой ?
 
Хз как на счет фафуриона, а вообще стандартно раньше было так:
1) после слияния добавляем к никам префикс (например #)
2) при входе в игру (пакет CharacterSelected от клиента) смотрим наличие флага в нике
3) если флаг присутствует, выводим ХТМЛ диалог, с предложением о смене ника / если флага нет, запускаем в игру
4) после успешной смены ника, запускаем персонажа в игру
(вприцнипе, при желании, можно сделать поле в таблице characters, сигналезирующее о необходимости смены ника, и чекать его при входе)
 

    Glafferax

    Баллов: 1
    Спасибо за подсказку
Не думал, что диалог можно выводить на этапе выбора персонажа.
Попробую так, если получится - отпишусь.
 
26070 26071
Java:
package l2p.gameserver.network.s2c;

import l2p.gameserver.network.components.Opcode;

public class ExNeedToChangeName extends L2GameServerPacket
{
    private int _type, _reason;
    private String _origName;

    public ExNeedToChangeName(int type, int reason, String origName)
    {
        _type = type;
        _reason = reason;
        _origName = origName;
    }

    @Override
    protected final void writeImpl()
    {
        writeEx(Opcode.ExNeedToChangeName); // 0x6A;
        writeD(_type); // с любым значением больше 0 показывает одно и то же
        writeD(_reason); // 0 - смена имени клана, 1 - смена имени персонажа
        writeS(_origName); // используется в диалоге при _reason равном 0
    }
}
в ответ от клиента прилетает
Java:
package l2p.gameserver.network.c2s;

// 0x38
public class RequestExChangeName extends L2GameClientPacket
{
    private int _unk1, _unk2;
    private String _name;

    @Override
    protected void readImpl()
    {
        _unk1 = readD(); // всегда приходит 1
        _name = readS(); // новое имя, введенное в диалоге
        _unk2 = readD(); // всегда приходит 0
    }

    @Override
    protected void runImpl()
    {
        System.out.println("unk1: " + _unk1 + "\tname: " + _name + "\tunk2: " + _unk2);
    }
}
 
Gaikotsu, то что нужно, благодарю.
Matrix, ваш вариант тоже рабочий, но только такое окно (html) показывается один раз по не ясной для меня причине, если его закрыть, последующие попытки "входа в игру", в ответ на которые я отправляю html, не дают эффекта.
 
последующие попытки "входа в игру", в ответ на которые я отправляю html, не дают эффекта
Скорей всего чтоб такого "эффекта" небыло, помимо html стоит отправить пакет ActionFailed
 
Решил следующем образом:
1) Добавил в таблицу character поле renameOnEnter
SQL:
+ALTER TABLE characters ADD COLUMN `renameOnEnter` BOOLEAN NOT NULL DEFAULT '0' AFTER `char_name`;
2) В класс Player добавил поле
Java:
+    private boolean _renameOnEnter = false;
и методы:
Java:
+    public final void setRenameOnEnter(boolean renameOnEnter) {
+        _renameOnEnter = renameOnEnter;
+    }
+
+    public final void setRenameOnEnter(boolean renameOnEnter, boolean saveToDB) {
+        setRenameOnEnter(renameOnEnter);
+
+        if (saveToDB) {
+            saveRenameOnEnterToDB();
+        }
+    }
+
+    public final void saveRenameOnEnterToDB()
+    {
+        Connection con = null;
+        PreparedStatement st = null;
+        try
+        {
+            con = DatabaseFactory.getInstance().getConnection();
+            st = con.prepareStatement("UPDATE characters SET renameOnEnter = ? WHERE obj_Id = ?");
+            st.setInt(1, getRenameOnEnter() ? 1 : 0);
+            st.setInt(2, getObjectId());
+            st.executeUpdate();
+        }
+        catch(Exception e)
+        {
+            _log.error("", e);
+        }
+        finally
+        {
+            DbUtils.closeQuietly(con, st);
+        }
+    }
+
+    public boolean getRenameOnEnter()
+    {
+        return _renameOnEnter;
+    }
так же необходимо в методе restore указать чтение этого поля из базы
Код:
                 player.setName(rset.getString("char_name"));
+                player.setRenameOnEnter(rset.getBoolean("renameOnEnter"));
4) В классе CharacterSelected следующие изменения:
Код:
-        sendPacket(new CharacterSelectedPacket(activeChar, client.getSessionKey().playOkID1));
+
+        if (activeChar.getRenameOnEnter()) {
+            sendPacket(new ExNeedToChangeName(1, 1, ""));
+        } else {
+            sendPacket(new CharacterSelectedPacket(activeChar, client.getSessionKey().playOkID1));
+        }
5) Обработка пакета RequestExChangeName
Java:
public class RequestExChangeName extends L2GameClientPacket
{
+    private int _unk1, _unk2;
+    private String _name;

     @Override
     protected void readImpl()
     {
+        _unk1 = readD(); // всегда приходит 1
+        _name = readS(); // новое имя, введенное в диалоге
+        _unk2 = readD(); // всегда приходит 0
     }

     @Override
     protected void runImpl()
     {
+        GameClient client = getClient();
+        Player activeChar = client.getActiveChar();
+
+        if(activeChar == null)
+            return;
+
+        if(_name == null || _name.isEmpty())
+        {
+            activeChar.sendPacket(new ExNeedToChangeName(1, 1, ""));
+            return;
+        }
+        else if(!Util.isMatchingRegexp(_name, Config.CNAME_TEMPLATE))
+        {
+            activeChar.sendPacket(new ExNeedToChangeName(1, 1, ""));
+            return;
+        }
+        else if(CharacterDAO.getInstance().getObjectIdByName(_name) > 0)
+        {
+            activeChar.sendPacket(new ExNeedToChangeName(1, 1, ""));
+            return;
+        }
+
+        activeChar.setName(_name);
+        activeChar.saveNameToDB();
+        activeChar.setRenameOnEnter(false, true);
+
+        sendPacket(new CharacterSelectedPacket(activeChar, client.getSessionKey().playOkID1));
     }
}

Это покрывает только кейс смены ника, смену названия клана еще не затрагивал.

Таким образом получается, что если в таблице characters поставить значение renameOnEnter в 1, то при входе в игру будет предложено сменить ник игроку, пока он не введет корректный.
 
Последнее редактирование:
(l2jhf) есть еще такая таблица character_variables куда можно вписать ключ и значение
PlayerVariables var = activeChar.getVariables();
 
Назад
Сверху Снизу