Guide Guide Creating Bypass Handler's

Deazer

Head Developer
Staff member
Introduction
Bypass Handler is a handler for commands that come from the client when clicking on links in HTML windows/Interfaces (NPC dialogues, Community Board, tutorials, etc.).

Quick start
Step 1: Create handler class
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)
  {
    // Your logic here
    player.sendMessage("Bypass works! Params: " + params);
  }

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

Step 2: Add to the config ONLY if you need to call this bypass directly from the interface. If it is called from HTML - DO NOT, this is important!
File: config/altsettins.properties
AltSimpleBypassAllowed = ...,_mybypass

Step 3: Use in HTML
<a action="bypass _mybypass">Press me</a>
<a action="bypass _mybypass param1 param2">With parameters</a>

Registration types
Prefix matching (getBypassPrefixes)
Used when bypass starts with a specific string:

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

Exact match (getBypassCommands)
Used when an exact string match is required

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

Working with NPCs
requiresNpc()
If the handler requires NPC:
Java:
@Override
public boolean requiresNpc()
{
  return true; // bypass will not execute if npc == null
}

requiresNpcCheck()
If a check of the distance to the NPC is needed:

Java:
@Override
public boolean requiresNpcCheck()
{
  return true; // will check NpcInstance.canBypassCheck(player, npc)
}

Examples
Example 1: Simple informational bypass

Java:
package handler.bypass;

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

/**
 * Shows character information
 * HTML: <a action="bypass _charinfo">My information</a>
 */
public class CharInfoBypassHandler extends ScriptBypassHandler
{
  @Override
  public void handle(Player player, NpcInstance npc, String bypass, String params)
  {
    player.sendMessage("Your level: " + player.getLevel());
    player.sendMessage("Your class: " + player.getClassId().name());
    player.sendMessage("Adena: " + player.getAdena());
  }

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

Example 2: Bypass with parameters
Java:
package handler.bypass;

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

/**
 * Teleport to Coordinates
 * HTML: <a action="bypass _quicktele 82698 148638 -3473">To Giran Town</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("Incorrect coordinates");
      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("Coordinate parsing error");
    }
  }

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

Example 3: Bypass with NPC check
Java:
package handler.bypass;

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

/**
 * Purchasing buff from NPC
 * HTML: <a action="bypass _buybuff 1204 5">Buff 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("Insufficient adena");
      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 "};
  }
}

Example 4: Multiple commands in one handler

Java:
package handler.bypass;

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

/**
 * Pet management
 * HTML: <a action="bypass pet_feed">Feed</a>
 *       <a action="bypass pet_dismiss">Release</a>
 */
public class PetControlBypassHandler extends ScriptBypassHandler
{
  @Override
  public void handle(Player player, NpcInstance npc, String bypass, String params)
  {
    if(player.getPet() == null)
    {
      player.sendMessage("You do not have a pet");
      return;
    }

    switch(bypass)
    {
      case "pet_feed":
        // feeding logic
        player.sendMessage("The pet is fed");
        break;
      case "pet_dismiss":
        // release logic
        player.getPet().unSummon();
        player.sendMessage("Pet released");
        break;
    }
  }

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

Example 5: GM-only bypass

Java:
package handler.bypass;

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

/**
 * GM Only
 * HTML: <a action="bypass _gmspawn 20001">Spawn mob</a>
 */
public class GmSpawnBypassHandler extends ScriptBypassHandler
{
  @Override
  public void handle(Player player, NpcInstance npc, String bypass, String params)
  {
    if(!player.isGM())
    {
      player.sendMessage("For GM Only");
      return;
    }

    int npcId = Integer.parseInt(params.trim());
    // spawn logic
    player.sendMessage("NPC " + npcId + " spawned");
  }

  @Override
  public String[] getBypassPrefixes()
  {
    return new String[]{"_gmspawn "};
  }
}
 
Last edited:
For voice commands, where the bypass does not depend on an NPC and is 100% hybrid, meaning it uses the same HTML as a base but works both in commands and NPCs?
 
For voice commands, where the bypass does not depend on an NPC and is 100% hybrid, meaning it uses the same HTML as a base but works both in commands and NPCs?
Of course it works and with NPC and on distance if your code doesn't have an NPC check like in the example. By default, everything works wonderfully without the mandatory presence of an NPC. Just try to go beyond the AI agents and read what I wrote in the guide.
 
Back
Top