Guide Руководство по созданию Bypass Handler'ов

Deazer

Head Developer
Staff member
Введение
Bypass Handler - это обработчик команд, которые приходят от клиента при клике на ссылки в HTML окнах/Интерфейся (NPC диалоги, Community Board, туториалы и т.д.).

Быстрый старт
Шаг 1: Создать класс хендлера
Java:
package handler.bypass;

import l2.gameserver.model.Player;
import l2.gameserver.model.instances.NpcInstance;

public class MyBypassHandler extends ScriptBypassHandler
{
  @Override
  public void handle(Player player, NpcInstance npc, String bypass, String params)
  {
    // Ваша логика здесь
    player.sendMessage("Bypass работает! Params: " + params);
  }

  @Override
  public String[] getBypassPrefixes()
  {
    return new String[]{"_mybypass"};
  }
}

Шаг 2: Добавить в конфиг ТОЛЬКО если вам нужно вызывать этот байпасс напрямую из интерфейса. Если вызываеться из HTML - НЕ НУЖНО, это важно!
Файл: config/altsettins.properties
AltSimpleBypassAllowed = ...,_mybypass

Шаг 3: Использовать в HTML
<a action="bypass _mybypass">Нажми меня</a>
<a action="bypass _mybypass param1 param2">С параметрами</a>

Типы регистрации
Префиксный матчинг (getBypassPrefixes)
Используется когда bypass начинается с определённой строки:

Java:
@Override
public String[] getBypassPrefixes()
{
  return new String[]{"_myprefix"};
}

Точное совпадение (getBypassCommands)
Используется когда нужно точное совпадение строки

Java:
@Override
public String[] getBypassCommands()
{
  return new String[]{"my_exact_command"};
}

Работа с NPC
requiresNpc()
Если хендлер требует наличия NPC:
Java:
@Override
public boolean requiresNpc()
{
  return true; // bypass не выполнится если npc == null
}

requiresNpcCheck()
Если нужна проверка дистанции до NPC:

Java:
@Override
public boolean requiresNpcCheck()
{
  return true; // проверит NpcInstance.canBypassCheck(player, npc)
}

Примеры
Пример 1: Простой информационный bypass

Java:
package handler.bypass;

import l2.gameserver.model.Player;
import l2.gameserver.model.instances.NpcInstance;

/**
 * Показывает информацию о персонаже
 * HTML: <a action="bypass _charinfo">Моя информация</a>
 */
public class CharInfoBypassHandler extends ScriptBypassHandler
{
  @Override
  public void handle(Player player, NpcInstance npc, String bypass, String params)
  {
    player.sendMessage("Ваш уровень: " + player.getLevel());
    player.sendMessage("Ваш класс: " + player.getClassId().name());
    player.sendMessage("Адена: " + player.getAdena());
  }

  @Override
  public String[] getBypassCommands()
  {
    return new String[]{"_charinfo"};
  }
}

Пример 2: Bypass с параметрами
Java:
package handler.bypass;

import l2.gameserver.model.Player;
import l2.gameserver.model.instances.NpcInstance;

/**
 * Телепорт по координатам
 * HTML: <a action="bypass _quicktele 82698 148638 -3473">В Giran</a>
 */
public class QuickTeleportBypassHandler extends ScriptBypassHandler
{
  @Override
  public void handle(Player player, NpcInstance npc, String bypass, String params)
  {
    String[] args = params.trim().split(" ");
    if(args.length < 3)
    {
      player.sendMessage("Неверные координаты");
      return;
    }
  
    try
    {
      int x = Integer.parseInt(args[0]);
      int y = Integer.parseInt(args[1]);
      int z = Integer.parseInt(args[2]);
      player.teleToLocation(x, y, z);
    }
    catch(NumberFormatException e)
    {
      player.sendMessage("Ошибка парсинга координат");
    }
  }

  @Override
  public String[] getBypassPrefixes()
  {
    return new String[]{"_quicktele "};
  }
}

Пример 3: Bypass с проверкой NPC
Java:
package handler.bypass;

import l2.gameserver.model.Player;
import l2.gameserver.model.instances.NpcInstance;

/**
 * Покупка предмета у NPC
 * HTML: <a action="bypass _buybuff 1204 5">Купить Wind Walk</a>
 */
public class BuyBuffBypassHandler extends ScriptBypassHandler
{
  @Override
  public void handle(Player player, NpcInstance npc, String bypass, String params)
  {
    String[] args = params.trim().split(" ");
    if(args.length < 2)
      return;

    int skillId = Integer.parseInt(args[0]);
    int skillLvl = Integer.parseInt(args[1]);
    int price = 10000;

    if(player.getAdena() < price)
    {
      player.sendMessage("Недостаточно адены");
      return;
    }

    player.reduceAdena(price, true);
    npc.broadcastPacket(new MagicSkillUse(npc, player, skillId, skillLvl, 0, 0));
    player.altOnMagicUse(player, SkillTable.getInstance().getInfo(skillId, skillLvl));
  }

  @Override
  public boolean requiresNpc()
  {
    return true;
  }

  @Override
  public boolean requiresNpcCheck()
  {
    return true;
  }

  @Override
  public String[] getBypassPrefixes()
  {
    return new String[]{"_buybuff "};
  }
}

Пример 4: Множественные команды в одном хендлере

Java:
package handler.bypass;

import l2.gameserver.model.Player;
import l2.gameserver.model.instances.NpcInstance;

/**
 * Управление питомцем
 * HTML: <a action="bypass pet_feed">Покормить</a>
 *       <a action="bypass pet_dismiss">Отпустить</a>
 */
public class PetControlBypassHandler extends ScriptBypassHandler
{
  @Override
  public void handle(Player player, NpcInstance npc, String bypass, String params)
  {
    if(player.getPet() == null)
    {
      player.sendMessage("У вас нет питомца");
      return;
    }

    switch(bypass)
    {
      case "pet_feed":
        // логика кормления
        player.sendMessage("Питомец покормлен");
        break;
      case "pet_dismiss":
        // логика отпускания
        player.getPet().unSummon();
        player.sendMessage("Питомец отпущен");
        break;
    }
  }

  @Override
  public String[] getBypassCommands()
  {
    return new String[]{"pet_feed", "pet_dismiss"};
  }
}

Пример 5: GM-only bypass

Java:
package handler.bypass;

import l2.gameserver.model.Player;
import l2.gameserver.model.instances.NpcInstance;

/**
 * Только для GM
 * HTML: <a action="bypass _gmspawn 20001">Заспавнить моба</a>
 */
public class GmSpawnBypassHandler extends ScriptBypassHandler
{
  @Override
  public void handle(Player player, NpcInstance npc, String bypass, String params)
  {
    if(!player.isGM())
    {
      player.sendMessage("Только для GM");
      return;
    }

    int npcId = Integer.parseInt(params.trim());
    // логика спавна
    player.sendMessage("NPC " + npcId + " заспавнен");
  }

  @Override
  public String[] getBypassPrefixes()
  {
    return new String[]{"_gmspawn "};
  }
}
 
Last edited:
Back
Top