661 lines
19 KiB
Java
661 lines
19 KiB
Java
/*
|
|
* This file is part of the L2J Mobius project.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
package handlers.admincommandhandlers;
|
|
|
|
import java.awt.Color;
|
|
import java.io.File;
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.nio.file.Files;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.StringJoiner;
|
|
import java.util.StringTokenizer;
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
import java.util.concurrent.atomic.AtomicInteger;
|
|
import java.util.logging.Level;
|
|
import java.util.logging.Logger;
|
|
|
|
import com.l2jmobius.Config;
|
|
import com.l2jmobius.commons.util.CommonUtil;
|
|
import com.l2jmobius.commons.util.Rnd;
|
|
import com.l2jmobius.gameserver.GeoData;
|
|
import com.l2jmobius.gameserver.enums.PlayerAction;
|
|
import com.l2jmobius.gameserver.handler.IAdminCommandHandler;
|
|
import com.l2jmobius.gameserver.instancemanager.ZoneManager;
|
|
import com.l2jmobius.gameserver.model.Location;
|
|
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
|
import com.l2jmobius.gameserver.model.events.EventType;
|
|
import com.l2jmobius.gameserver.model.events.ListenerRegisterType;
|
|
import com.l2jmobius.gameserver.model.events.annotations.Priority;
|
|
import com.l2jmobius.gameserver.model.events.annotations.RegisterEvent;
|
|
import com.l2jmobius.gameserver.model.events.annotations.RegisterType;
|
|
import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerDlgAnswer;
|
|
import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerMoveRequest;
|
|
import com.l2jmobius.gameserver.model.events.returns.TerminateReturn;
|
|
import com.l2jmobius.gameserver.model.html.PageBuilder;
|
|
import com.l2jmobius.gameserver.model.html.PageResult;
|
|
import com.l2jmobius.gameserver.model.zone.L2ZoneType;
|
|
import com.l2jmobius.gameserver.model.zone.form.ZoneNPoly;
|
|
import com.l2jmobius.gameserver.network.serverpackets.ConfirmDlg;
|
|
import com.l2jmobius.gameserver.network.serverpackets.ExServerPrimitive;
|
|
import com.l2jmobius.gameserver.network.serverpackets.ExShowTerritory;
|
|
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
|
|
import com.l2jmobius.gameserver.util.Util;
|
|
|
|
import ai.AbstractNpcAI;
|
|
|
|
/**
|
|
* @author UnAfraid
|
|
*/
|
|
public class AdminZones extends AbstractNpcAI implements IAdminCommandHandler
|
|
{
|
|
private static final Logger _log = Logger.getLogger(AdminPathNode.class.getName());
|
|
private final Map<Integer, ZoneNodeHolder> _zones = new ConcurrentHashMap<>();
|
|
|
|
private static final String[] COMMANDS =
|
|
{
|
|
"admin_zones",
|
|
};
|
|
|
|
public AdminZones()
|
|
{
|
|
}
|
|
|
|
@Override
|
|
public boolean useAdminCommand(String command, L2PcInstance activeChar)
|
|
{
|
|
final StringTokenizer st = new StringTokenizer(command);
|
|
final String cmd = st.nextToken();
|
|
switch (cmd)
|
|
{
|
|
case "admin_zones":
|
|
{
|
|
if (!st.hasMoreTokens())
|
|
{
|
|
buildZonesEditorWindow(activeChar);
|
|
return false;
|
|
}
|
|
final String subCmd = st.nextToken();
|
|
switch (subCmd)
|
|
{
|
|
case "load":
|
|
{
|
|
if (st.hasMoreTokens())
|
|
{
|
|
String name = "";
|
|
while (st.hasMoreTokens())
|
|
{
|
|
name += st.nextToken() + " ";
|
|
}
|
|
loadZone(activeChar, name.trim());
|
|
}
|
|
break;
|
|
}
|
|
case "create":
|
|
{
|
|
buildHtmlWindow(activeChar, 0);
|
|
break;
|
|
}
|
|
case "setname":
|
|
{
|
|
String name = "";
|
|
while (st.hasMoreTokens())
|
|
{
|
|
name += st.nextToken() + " ";
|
|
}
|
|
if (!name.isEmpty())
|
|
{
|
|
name = name.substring(0, name.length() - 1);
|
|
}
|
|
setName(activeChar, name);
|
|
break;
|
|
}
|
|
case "start":
|
|
{
|
|
enablePicking(activeChar);
|
|
break;
|
|
}
|
|
case "finish":
|
|
{
|
|
disablePicking(activeChar);
|
|
break;
|
|
}
|
|
case "setMinZ":
|
|
{
|
|
if (st.hasMoreTokens())
|
|
{
|
|
final int minZ = Integer.parseInt(st.nextToken());
|
|
setMinZ(activeChar, minZ);
|
|
}
|
|
break;
|
|
}
|
|
case "setMaxZ":
|
|
{
|
|
if (st.hasMoreTokens())
|
|
{
|
|
final int maxZ = Integer.parseInt(st.nextToken());
|
|
setMaxZ(activeChar, maxZ);
|
|
}
|
|
break;
|
|
}
|
|
case "show":
|
|
{
|
|
showPoints(activeChar);
|
|
final ConfirmDlg dlg = new ConfirmDlg("When enable show territory you must restart client to remove it, are you sure about that?");
|
|
dlg.addTime(15 * 1000);
|
|
activeChar.sendPacket(dlg);
|
|
activeChar.addAction(PlayerAction.ADMIN_SHOW_TERRITORY);
|
|
break;
|
|
}
|
|
case "hide":
|
|
{
|
|
final ZoneNodeHolder holder = _zones.get(activeChar.getObjectId());
|
|
if (holder != null)
|
|
{
|
|
final ExServerPrimitive exsp = new ExServerPrimitive("DebugPoint_" + activeChar.getObjectId(), activeChar.getX(), activeChar.getY(), activeChar.getZ());
|
|
exsp.addPoint(Color.BLACK, 0, 0, 0);
|
|
activeChar.sendPacket(exsp);
|
|
}
|
|
break;
|
|
}
|
|
case "change":
|
|
{
|
|
if (!st.hasMoreTokens())
|
|
{
|
|
activeChar.sendMessage("Missing node index!");
|
|
break;
|
|
}
|
|
final String indexToken = st.nextToken();
|
|
if (!Util.isDigit(indexToken))
|
|
{
|
|
activeChar.sendMessage("Node index should be int!");
|
|
break;
|
|
}
|
|
final int index = Integer.parseInt(indexToken);
|
|
changePoint(activeChar, index);
|
|
break;
|
|
}
|
|
case "delete":
|
|
{
|
|
if (!st.hasMoreTokens())
|
|
{
|
|
activeChar.sendMessage("Missing node index!");
|
|
break;
|
|
}
|
|
final String indexToken = st.nextToken();
|
|
if (!Util.isDigit(indexToken))
|
|
{
|
|
activeChar.sendMessage("Node index should be int!");
|
|
break;
|
|
}
|
|
final int index = Integer.parseInt(indexToken);
|
|
deletePoint(activeChar, index);
|
|
showPoints(activeChar);
|
|
break;
|
|
}
|
|
case "clear":
|
|
{
|
|
_zones.remove(activeChar.getObjectId());
|
|
break;
|
|
}
|
|
case "dump":
|
|
{
|
|
dumpPoints(activeChar);
|
|
break;
|
|
}
|
|
case "list":
|
|
{
|
|
final int page = CommonUtil.parseNextInt(st, 0);
|
|
buildHtmlWindow(activeChar, page);
|
|
return false;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
buildHtmlWindow(activeChar, 0);
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @param activeChar
|
|
* @param minZ
|
|
*/
|
|
private void setMinZ(L2PcInstance activeChar, int minZ)
|
|
{
|
|
_zones.computeIfAbsent(activeChar.getObjectId(), key -> new ZoneNodeHolder(activeChar)).setMinZ(minZ);
|
|
}
|
|
|
|
/**
|
|
* @param activeChar
|
|
* @param maxZ
|
|
*/
|
|
private void setMaxZ(L2PcInstance activeChar, int maxZ)
|
|
{
|
|
_zones.computeIfAbsent(activeChar.getObjectId(), key -> new ZoneNodeHolder(activeChar)).setMaxZ(maxZ);
|
|
}
|
|
|
|
private void buildZonesEditorWindow(L2PcInstance activeChar)
|
|
{
|
|
final StringBuilder sb = new StringBuilder();
|
|
final List<L2ZoneType> zones = ZoneManager.getInstance().getZones(activeChar);
|
|
for (L2ZoneType zone : zones)
|
|
{
|
|
if (zone.getZone() instanceof ZoneNPoly)
|
|
{
|
|
sb.append("<tr>");
|
|
sb.append("<td fixwidth=200><a action=\"bypass -h admin_zones load " + zone.getName() + "\">" + zone.getName() + "</a></td>");
|
|
sb.append("</tr>");
|
|
}
|
|
}
|
|
|
|
final NpcHtmlMessage msg = new NpcHtmlMessage(0, 1);
|
|
msg.setFile(activeChar.getHtmlPrefix(), "data/html/admin/zone_editor.htm");
|
|
msg.replace("%zones%", sb.toString());
|
|
activeChar.sendPacket(msg);
|
|
}
|
|
|
|
/**
|
|
* @param activeChar
|
|
* @param zoneName
|
|
*/
|
|
private void loadZone(L2PcInstance activeChar, String zoneName)
|
|
{
|
|
activeChar.sendMessage("Searching for zone: " + zoneName);
|
|
final List<L2ZoneType> zones = ZoneManager.getInstance().getZones(activeChar);
|
|
L2ZoneType zoneType = null;
|
|
for (L2ZoneType zone : zones)
|
|
{
|
|
if (zone.getName().equalsIgnoreCase(zoneName))
|
|
{
|
|
zoneType = zone;
|
|
activeChar.sendMessage("Zone found: " + zone.getId());
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ((zoneType != null) && (zoneType.getZone() instanceof ZoneNPoly))
|
|
{
|
|
final ZoneNPoly zone = (ZoneNPoly) zoneType.getZone();
|
|
final ZoneNodeHolder holder = _zones.computeIfAbsent(activeChar.getObjectId(), val -> new ZoneNodeHolder(activeChar));
|
|
holder.getNodes().clear();
|
|
holder.setName(zoneType.getName());
|
|
holder.setMinZ(zone.getLowZ());
|
|
holder.setMaxZ(zone.getHighZ());
|
|
for (int i = 0; i < zone.getX().length; i++)
|
|
{
|
|
final int x = zone.getX()[i];
|
|
final int y = zone.getY()[i];
|
|
holder.addNode(new Location(x, y, GeoData.getInstance().getSpawnHeight(x, y, Rnd.get(zone.getLowZ(), zone.getHighZ()))));
|
|
}
|
|
showPoints(activeChar);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param activeChar
|
|
* @param name
|
|
*/
|
|
private void setName(L2PcInstance activeChar, String name)
|
|
{
|
|
if (name.contains("<") || name.contains(">") || name.contains("&") || name.contains("\\") || name.contains("\"") || name.contains("$"))
|
|
{
|
|
activeChar.sendMessage("You cannot use symbols like: < > & \" $ \\");
|
|
return;
|
|
}
|
|
_zones.computeIfAbsent(activeChar.getObjectId(), key -> new ZoneNodeHolder(activeChar)).setName(name);
|
|
}
|
|
|
|
/**
|
|
* @param activeChar
|
|
*/
|
|
private void enablePicking(L2PcInstance activeChar)
|
|
{
|
|
if (!activeChar.hasAction(PlayerAction.ADMIN_POINT_PICKING))
|
|
{
|
|
activeChar.addAction(PlayerAction.ADMIN_POINT_PICKING);
|
|
activeChar.sendMessage("Point picking mode activated!");
|
|
}
|
|
else
|
|
{
|
|
activeChar.sendMessage("Point picking mode is already activated!");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param activeChar
|
|
*/
|
|
private void disablePicking(L2PcInstance activeChar)
|
|
{
|
|
if (activeChar.removeAction(PlayerAction.ADMIN_POINT_PICKING))
|
|
{
|
|
activeChar.sendMessage("Point picking mode deactivated!");
|
|
}
|
|
else
|
|
{
|
|
activeChar.sendMessage("Point picking mode was not activated!");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param activeChar
|
|
*/
|
|
private void showPoints(L2PcInstance activeChar)
|
|
{
|
|
final ZoneNodeHolder holder = _zones.get(activeChar.getObjectId());
|
|
if (holder != null)
|
|
{
|
|
if (holder.getNodes().size() < 3)
|
|
{
|
|
activeChar.sendMessage("In order to visualize this zone you must have at least 3 points.");
|
|
return;
|
|
}
|
|
final ExServerPrimitive exsp = new ExServerPrimitive("DebugPoint_" + activeChar.getObjectId(), activeChar.getX(), activeChar.getY(), activeChar.getZ());
|
|
final List<Location> list = holder.getNodes();
|
|
for (int i = 1; i < list.size(); i++)
|
|
{
|
|
final Location prevLoc = list.get(i - 1);
|
|
final Location nextLoc = list.get(i);
|
|
if (holder.getMinZ() != 0)
|
|
{
|
|
exsp.addLine("Min Point " + i + " > " + (i + 1), Color.CYAN, true, prevLoc.getX(), prevLoc.getY(), holder.getMinZ(), nextLoc.getX(), nextLoc.getY(), holder.getMinZ());
|
|
}
|
|
exsp.addLine("Point " + i + " > " + (i + 1), Color.WHITE, true, prevLoc, nextLoc);
|
|
if (holder.getMaxZ() != 0)
|
|
{
|
|
exsp.addLine("Max Point " + i + " > " + (i + 1), Color.RED, true, prevLoc.getX(), prevLoc.getY(), holder.getMaxZ(), nextLoc.getX(), nextLoc.getY(), holder.getMaxZ());
|
|
}
|
|
}
|
|
final Location prevLoc = list.get(list.size() - 1);
|
|
final Location nextLoc = list.get(0);
|
|
if (holder.getMinZ() != 0)
|
|
{
|
|
exsp.addLine("Min Point " + list.size() + " > 1", Color.CYAN, true, prevLoc.getX(), prevLoc.getY(), holder.getMinZ(), nextLoc.getX(), nextLoc.getY(), holder.getMinZ());
|
|
}
|
|
exsp.addLine("Point " + list.size() + " > 1", Color.WHITE, true, prevLoc, nextLoc);
|
|
if (holder.getMaxZ() != 0)
|
|
{
|
|
exsp.addLine("Max Point " + list.size() + " > 1", Color.RED, true, prevLoc.getX(), prevLoc.getY(), holder.getMaxZ(), nextLoc.getX(), nextLoc.getY(), holder.getMaxZ());
|
|
}
|
|
activeChar.sendPacket(exsp);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param activeChar
|
|
* @param index
|
|
*/
|
|
private void changePoint(L2PcInstance activeChar, int index)
|
|
{
|
|
final ZoneNodeHolder holder = _zones.get(activeChar.getObjectId());
|
|
if (holder != null)
|
|
{
|
|
final Location loc = holder.getNodes().get(index);
|
|
if (loc != null)
|
|
{
|
|
enablePicking(activeChar);
|
|
holder.setChangingLoc(loc);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param activeChar
|
|
* @param index
|
|
*/
|
|
private void deletePoint(L2PcInstance activeChar, int index)
|
|
{
|
|
final ZoneNodeHolder holder = _zones.get(activeChar.getObjectId());
|
|
if (holder != null)
|
|
{
|
|
final Location loc = holder.getNodes().get(index);
|
|
if (loc != null)
|
|
{
|
|
holder.getNodes().remove(loc);
|
|
activeChar.sendMessage("Node " + index + " has been removed!");
|
|
if (holder.getNodes().isEmpty())
|
|
{
|
|
activeChar.sendMessage("Since node list is empty destroying session!");
|
|
_zones.remove(activeChar.getObjectId());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param activeChar
|
|
*/
|
|
private void dumpPoints(L2PcInstance activeChar)
|
|
{
|
|
final ZoneNodeHolder holder = _zones.get(activeChar.getObjectId());
|
|
if ((holder != null) && !holder.getNodes().isEmpty())
|
|
{
|
|
if (holder.getName().isEmpty())
|
|
{
|
|
activeChar.sendMessage("Set name first!");
|
|
return;
|
|
}
|
|
|
|
final Location firstNode = holder.getNodes().get(0);
|
|
final StringJoiner sj = new StringJoiner(Config.EOL);
|
|
sj.add("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
|
|
sj.add("<list enabled=\"true\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"../../data/xsd/zones.xsd\">");
|
|
sj.add("\t<zone name=\"" + holder.getName() + "\" type=\"ScriptZone\" shape=\"NPoly\" minZ=\"" + (holder.getMinZ() != 0 ? holder.getMinZ() : firstNode.getZ() - 100) + "\" maxZ=\"" + (holder.getMaxZ() != 0 ? holder.getMaxZ() : firstNode.getZ() + 100) + "\">");
|
|
for (Location loc : holder.getNodes())
|
|
{
|
|
sj.add("\t\t<node X=\"" + loc.getX() + "\" Y=\"" + loc.getY() + "\" />");
|
|
}
|
|
sj.add("\t</zone>");
|
|
sj.add("</list>");
|
|
sj.add(""); // new line at end of file
|
|
try
|
|
{
|
|
File file = new File("log/points/" + activeChar.getAccountName() + "/" + holder.getName() + ".xml");
|
|
if (file.exists())
|
|
{
|
|
int i = 0;
|
|
while ((file = new File("log/points/" + activeChar.getAccountName() + "/" + holder.getName() + i + ".xml")).exists())
|
|
{
|
|
i++;
|
|
}
|
|
}
|
|
if (!file.getParentFile().isDirectory())
|
|
{
|
|
file.getParentFile().mkdirs();
|
|
}
|
|
Files.write(file.toPath(), sj.toString().getBytes(StandardCharsets.UTF_8));
|
|
activeChar.sendMessage("Successfully written on: " + file.getAbsolutePath().replace(new File(".").getCanonicalFile().getAbsolutePath(), ""));
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
activeChar.sendMessage("Failed writing the dump: " + e.getMessage());
|
|
_log.log(Level.WARNING, "Failed writing point picking dump for " + activeChar.getName() + ":" + e.getMessage(), e);
|
|
}
|
|
}
|
|
}
|
|
|
|
@RegisterEvent(EventType.ON_PLAYER_MOVE_REQUEST)
|
|
@RegisterType(ListenerRegisterType.GLOBAL_PLAYERS)
|
|
@Priority(Integer.MAX_VALUE)
|
|
public TerminateReturn onPlayerPointPicking(OnPlayerMoveRequest event)
|
|
{
|
|
final L2PcInstance activeChar = event.getActiveChar();
|
|
if (activeChar.hasAction(PlayerAction.ADMIN_POINT_PICKING))
|
|
{
|
|
final Location newLocation = event.getLocation();
|
|
final ZoneNodeHolder holder = _zones.computeIfAbsent(activeChar.getObjectId(), key -> new ZoneNodeHolder(activeChar));
|
|
final Location changeLog = holder.getChangingLoc();
|
|
if (changeLog != null)
|
|
{
|
|
changeLog.setXYZ(newLocation);
|
|
holder.setChangingLoc(null);
|
|
activeChar.sendMessage("Location " + (holder.indexOf(changeLog) + 1) + " has been updated!");
|
|
disablePicking(activeChar);
|
|
}
|
|
else
|
|
{
|
|
holder.addNode(newLocation);
|
|
activeChar.sendMessage("Location " + (holder.indexOf(changeLog) + 1) + " has been added!");
|
|
}
|
|
// Auto visualization when nodes >= 3
|
|
if (holder.getNodes().size() >= 3)
|
|
{
|
|
showPoints(activeChar);
|
|
}
|
|
buildHtmlWindow(activeChar, 0);
|
|
|
|
return new TerminateReturn(true, true, false);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
@RegisterEvent(EventType.ON_PLAYER_DLG_ANSWER)
|
|
@RegisterType(ListenerRegisterType.GLOBAL_PLAYERS)
|
|
public void onPlayerDlgAnswer(OnPlayerDlgAnswer event)
|
|
{
|
|
final L2PcInstance activeChar = event.getActiveChar();
|
|
if (activeChar.removeAction(PlayerAction.ADMIN_SHOW_TERRITORY) && (event.getAnswer() == 1))
|
|
{
|
|
final ZoneNodeHolder holder = _zones.get(activeChar.getObjectId());
|
|
if (holder != null)
|
|
{
|
|
final List<Location> list = holder.getNodes();
|
|
if (list.size() < 3)
|
|
{
|
|
activeChar.sendMessage("You must have at least 3 nodes to use this option!");
|
|
return;
|
|
}
|
|
|
|
final Location firstLoc = list.get(0);
|
|
final int minZ = holder.getMinZ() != 0 ? holder.getMinZ() : firstLoc.getZ() - 100;
|
|
final int maxZ = holder.getMaxZ() != 0 ? holder.getMaxZ() : firstLoc.getZ() + 100;
|
|
final ExShowTerritory exst = new ExShowTerritory(minZ, maxZ);
|
|
list.forEach(exst::addVertice);
|
|
activeChar.sendPacket(exst);
|
|
activeChar.sendMessage("In order to remove the debug you must restart your game client!");
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public String[] getAdminCommandList()
|
|
{
|
|
return COMMANDS;
|
|
}
|
|
|
|
private void buildHtmlWindow(L2PcInstance activeChar, int page)
|
|
{
|
|
final NpcHtmlMessage msg = new NpcHtmlMessage(0, 1);
|
|
msg.setFile(activeChar.getHtmlPrefix(), "data/html/admin/zone_editor_create.htm");
|
|
final ZoneNodeHolder holder = _zones.computeIfAbsent(activeChar.getObjectId(), key -> new ZoneNodeHolder(activeChar));
|
|
final AtomicInteger position = new AtomicInteger(page * 20);
|
|
|
|
final PageResult result = PageBuilder.newBuilder(holder.getNodes(), 20, "bypass -h admin_zones list").currentPage(page).bodyHandler((pages, loc, sb) ->
|
|
{
|
|
sb.append("<tr>");
|
|
sb.append("<td fixwidth=5></td>");
|
|
sb.append("<td fixwidth=20>" + position.getAndIncrement() + "</td>");
|
|
sb.append("<td fixwidth=60>" + loc.getX() + "</td>");
|
|
sb.append("<td fixwidth=60>" + loc.getY() + "</td>");
|
|
sb.append("<td fixwidth=60>" + loc.getZ() + "</td>");
|
|
sb.append("<td fixwidth=30><a action=\"bypass -h admin_zones change " + holder.indexOf(loc) + "\">[E]</a></td>");
|
|
sb.append("<td fixwidth=30><a action=\"bypass -h admin_move_to " + loc.getX() + " " + loc.getY() + " " + loc.getZ() + "\">[T]</a></td>");
|
|
sb.append("<td fixwidth=30><a action=\"bypass -h admin_zones delete " + holder.indexOf(loc) + "\">[D]</a></td>");
|
|
sb.append("<td fixwidth=5></td>");
|
|
sb.append("</tr>");
|
|
}).build();
|
|
|
|
msg.replace("%name%", holder.getName());
|
|
msg.replace("%minZ%", holder.getMinZ());
|
|
msg.replace("%maxZ%", holder.getMaxZ());
|
|
msg.replace("%pages%", result.getPagerTemplate());
|
|
msg.replace("%nodes%", result.getBodyTemplate());
|
|
activeChar.sendPacket(msg);
|
|
}
|
|
|
|
protected class ZoneNodeHolder
|
|
{
|
|
private String _name = "";
|
|
private Location _changingLoc = null;
|
|
private int _minZ;
|
|
private int _maxZ;
|
|
private final List<Location> _nodes = new ArrayList<>();
|
|
|
|
public ZoneNodeHolder(L2PcInstance player)
|
|
{
|
|
_minZ = player.getZ() - 200;
|
|
_maxZ = player.getZ() + 200;
|
|
}
|
|
|
|
public void setName(String name)
|
|
{
|
|
_name = name;
|
|
}
|
|
|
|
public String getName()
|
|
{
|
|
return _name;
|
|
}
|
|
|
|
public void setChangingLoc(Location loc)
|
|
{
|
|
_changingLoc = loc;
|
|
}
|
|
|
|
public Location getChangingLoc()
|
|
{
|
|
return _changingLoc;
|
|
}
|
|
|
|
public void addNode(Location loc)
|
|
{
|
|
_nodes.add(loc);
|
|
}
|
|
|
|
public List<Location> getNodes()
|
|
{
|
|
return _nodes;
|
|
}
|
|
|
|
public int indexOf(Location loc)
|
|
{
|
|
return _nodes.indexOf(loc);
|
|
}
|
|
|
|
public int getMinZ()
|
|
{
|
|
return _minZ;
|
|
}
|
|
|
|
public int getMaxZ()
|
|
{
|
|
return _maxZ;
|
|
}
|
|
|
|
public void setMinZ(int minZ)
|
|
{
|
|
_minZ = minZ;
|
|
}
|
|
|
|
public void setMaxZ(int maxZ)
|
|
{
|
|
_maxZ = maxZ;
|
|
}
|
|
}
|
|
}
|