AdminSpawn.java 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515
  1. /*
  2. * Copyright (C) 2004-2015 L2J DataPack
  3. *
  4. * This file is part of L2J DataPack.
  5. *
  6. * L2J DataPack is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * L2J DataPack is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. package handlers.admincommandhandlers;
  20. import java.util.List;
  21. import java.util.NoSuchElementException;
  22. import java.util.StringTokenizer;
  23. import java.util.logging.Logger;
  24. import java.util.regex.Matcher;
  25. import java.util.regex.Pattern;
  26. import com.l2jserver.Config;
  27. import com.l2jserver.gameserver.SevenSigns;
  28. import com.l2jserver.gameserver.data.xml.impl.AdminData;
  29. import com.l2jserver.gameserver.data.xml.impl.NpcData;
  30. import com.l2jserver.gameserver.datatables.SpawnTable;
  31. import com.l2jserver.gameserver.handler.IAdminCommandHandler;
  32. import com.l2jserver.gameserver.instancemanager.DayNightSpawnManager;
  33. import com.l2jserver.gameserver.instancemanager.InstanceManager;
  34. import com.l2jserver.gameserver.instancemanager.QuestManager;
  35. import com.l2jserver.gameserver.instancemanager.RaidBossSpawnManager;
  36. import com.l2jserver.gameserver.model.AutoSpawnHandler;
  37. import com.l2jserver.gameserver.model.L2Object;
  38. import com.l2jserver.gameserver.model.L2Spawn;
  39. import com.l2jserver.gameserver.model.L2World;
  40. import com.l2jserver.gameserver.model.actor.L2Npc;
  41. import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
  42. import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
  43. import com.l2jserver.gameserver.model.entity.Instance;
  44. import com.l2jserver.gameserver.network.SystemMessageId;
  45. import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
  46. import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
  47. import com.l2jserver.gameserver.util.Broadcast;
  48. import com.l2jserver.util.StringUtil;
  49. /**
  50. * This class handles following admin commands: - show_spawns = shows menu - spawn_index lvl = shows menu for monsters with respective level - spawn_monster id = spawns monster id on target
  51. * @version $Revision: 1.2.2.5.2.5 $ $Date: 2005/04/11 10:06:06 $
  52. */
  53. public class AdminSpawn implements IAdminCommandHandler
  54. {
  55. private static final Logger _log = Logger.getLogger(AdminSpawn.class.getName());
  56. private static final String[] ADMIN_COMMANDS =
  57. {
  58. "admin_show_spawns",
  59. "admin_spawn",
  60. "admin_spawn_monster",
  61. "admin_spawn_index",
  62. "admin_unspawnall",
  63. "admin_respawnall",
  64. "admin_spawn_reload",
  65. "admin_npc_index",
  66. "admin_spawn_once",
  67. "admin_show_npcs",
  68. "admin_spawnnight",
  69. "admin_spawnday",
  70. "admin_instance_spawns",
  71. "admin_list_spawns",
  72. "admin_list_positions",
  73. "admin_spawn_debug_menu",
  74. "admin_spawn_debug_print",
  75. "admin_spawn_debug_print_menu"
  76. };
  77. @Override
  78. public boolean useAdminCommand(String command, L2PcInstance activeChar)
  79. {
  80. if (command.equals("admin_show_spawns"))
  81. {
  82. AdminHtml.showAdminHtml(activeChar, "spawns.htm");
  83. }
  84. else if (command.equalsIgnoreCase("admin_spawn_debug_menu"))
  85. {
  86. AdminHtml.showAdminHtml(activeChar, "spawns_debug.htm");
  87. }
  88. else if (command.startsWith("admin_spawn_debug_print"))
  89. {
  90. StringTokenizer st = new StringTokenizer(command, " ");
  91. L2Object target = activeChar.getTarget();
  92. if (target instanceof L2Npc)
  93. {
  94. try
  95. {
  96. st.nextToken();
  97. int type = Integer.parseInt(st.nextToken());
  98. printSpawn((L2Npc) target, type);
  99. if (command.contains("_menu"))
  100. {
  101. AdminHtml.showAdminHtml(activeChar, "spawns_debug.htm");
  102. }
  103. }
  104. catch (Exception e)
  105. {
  106. }
  107. }
  108. else
  109. {
  110. activeChar.sendPacket(SystemMessageId.INCORRECT_TARGET);
  111. }
  112. }
  113. else if (command.startsWith("admin_spawn_index"))
  114. {
  115. StringTokenizer st = new StringTokenizer(command, " ");
  116. try
  117. {
  118. st.nextToken();
  119. int level = Integer.parseInt(st.nextToken());
  120. int from = 0;
  121. try
  122. {
  123. from = Integer.parseInt(st.nextToken());
  124. }
  125. catch (NoSuchElementException nsee)
  126. {
  127. }
  128. showMonsters(activeChar, level, from);
  129. }
  130. catch (Exception e)
  131. {
  132. AdminHtml.showAdminHtml(activeChar, "spawns.htm");
  133. }
  134. }
  135. else if (command.equals("admin_show_npcs"))
  136. {
  137. AdminHtml.showAdminHtml(activeChar, "npcs.htm");
  138. }
  139. else if (command.startsWith("admin_npc_index"))
  140. {
  141. StringTokenizer st = new StringTokenizer(command, " ");
  142. try
  143. {
  144. st.nextToken();
  145. String letter = st.nextToken();
  146. int from = 0;
  147. try
  148. {
  149. from = Integer.parseInt(st.nextToken());
  150. }
  151. catch (NoSuchElementException nsee)
  152. {
  153. }
  154. showNpcs(activeChar, letter, from);
  155. }
  156. catch (Exception e)
  157. {
  158. AdminHtml.showAdminHtml(activeChar, "npcs.htm");
  159. }
  160. }
  161. else if (command.startsWith("admin_instance_spawns"))
  162. {
  163. StringTokenizer st = new StringTokenizer(command, " ");
  164. try
  165. {
  166. st.nextToken();
  167. int instance = Integer.parseInt(st.nextToken());
  168. if (instance >= 300000)
  169. {
  170. final StringBuilder html = StringUtil.startAppend(500 + 1000, "<html><table width=\"100%\"><tr><td width=45><button value=\"Main\" action=\"bypass -h admin_admin\" width=45 height=21 back=\"L2UI_ct1.button_df\" fore=\"L2UI_ct1.button_df\"></td><td width=180><center>", "<font color=\"LEVEL\">Spawns for " + String.valueOf(instance) + "</font>", "</td><td width=45><button value=\"Back\" action=\"bypass -h admin_current_player\" width=45 height=21 back=\"L2UI_ct1.button_df\" fore=\"L2UI_ct1.button_df\"></td></tr></table><br>", "<table width=\"100%\"><tr><td width=200>NpcName</td><td width=70>Action</td></tr>");
  171. int counter = 0;
  172. int skiped = 0;
  173. Instance inst = InstanceManager.getInstance().getInstance(instance);
  174. if (inst != null)
  175. {
  176. for (L2Npc npc : inst.getNpcs())
  177. {
  178. if (!npc.isDead())
  179. {
  180. // Only 50 because of client html limitation
  181. if (counter < 50)
  182. {
  183. StringUtil.append(html, "<tr><td>" + npc.getName() + "</td><td>", "<a action=\"bypass -h admin_move_to " + npc.getX() + " " + npc.getY() + " " + npc.getZ() + "\">Go</a>", "</td></tr>");
  184. counter++;
  185. }
  186. else
  187. {
  188. skiped++;
  189. }
  190. }
  191. }
  192. StringUtil.append(html, "<tr><td>Skipped:</td><td>" + String.valueOf(skiped) + "</td></tr></table></body></html>");
  193. final NpcHtmlMessage ms = new NpcHtmlMessage();
  194. ms.setHtml(html.toString());
  195. activeChar.sendPacket(ms);
  196. }
  197. else
  198. {
  199. activeChar.sendMessage("Cannot find instance " + instance);
  200. }
  201. }
  202. else
  203. {
  204. activeChar.sendMessage("Invalid instance number.");
  205. }
  206. }
  207. catch (Exception e)
  208. {
  209. activeChar.sendMessage("Usage //instance_spawns <instance_number>");
  210. }
  211. }
  212. else if (command.startsWith("admin_unspawnall"))
  213. {
  214. Broadcast.toAllOnlinePlayers(SystemMessage.getSystemMessage(SystemMessageId.NPC_SERVER_NOT_OPERATING));
  215. RaidBossSpawnManager.getInstance().cleanUp();
  216. DayNightSpawnManager.getInstance().cleanUp();
  217. L2World.getInstance().deleteVisibleNpcSpawns();
  218. AdminData.getInstance().broadcastMessageToGMs("NPC Unspawn completed!");
  219. }
  220. else if (command.startsWith("admin_spawnday"))
  221. {
  222. DayNightSpawnManager.getInstance().spawnDayCreatures();
  223. }
  224. else if (command.startsWith("admin_spawnnight"))
  225. {
  226. DayNightSpawnManager.getInstance().spawnNightCreatures();
  227. }
  228. else if (command.startsWith("admin_respawnall") || command.startsWith("admin_spawn_reload"))
  229. {
  230. // make sure all spawns are deleted
  231. RaidBossSpawnManager.getInstance().cleanUp();
  232. DayNightSpawnManager.getInstance().cleanUp();
  233. L2World.getInstance().deleteVisibleNpcSpawns();
  234. // now respawn all
  235. NpcData.getInstance().load();
  236. SpawnTable.getInstance().load();
  237. RaidBossSpawnManager.getInstance().load();
  238. AutoSpawnHandler.getInstance().reload();
  239. SevenSigns.getInstance().spawnSevenSignsNPC();
  240. QuestManager.getInstance().reloadAllScripts();
  241. AdminData.getInstance().broadcastMessageToGMs("NPC Respawn completed!");
  242. }
  243. else if (command.startsWith("admin_spawn_monster") || command.startsWith("admin_spawn"))
  244. {
  245. StringTokenizer st = new StringTokenizer(command, " ");
  246. try
  247. {
  248. String cmd = st.nextToken();
  249. String id = st.nextToken();
  250. int respawnTime = 0;
  251. int mobCount = 1;
  252. if (st.hasMoreTokens())
  253. {
  254. mobCount = Integer.parseInt(st.nextToken());
  255. }
  256. if (st.hasMoreTokens())
  257. {
  258. respawnTime = Integer.parseInt(st.nextToken());
  259. }
  260. if (cmd.equalsIgnoreCase("admin_spawn_once"))
  261. {
  262. spawnMonster(activeChar, id, respawnTime, mobCount, false);
  263. }
  264. else
  265. {
  266. spawnMonster(activeChar, id, respawnTime, mobCount, true);
  267. }
  268. }
  269. catch (Exception e)
  270. { // Case of wrong or missing monster data
  271. AdminHtml.showAdminHtml(activeChar, "spawns.htm");
  272. }
  273. }
  274. else if (command.startsWith("admin_list_spawns") || command.startsWith("admin_list_positions"))
  275. {
  276. int npcId = 0;
  277. int teleportIndex = -1;
  278. try
  279. { // admin_list_spawns x[xxxx] x[xx]
  280. String[] params = command.split(" ");
  281. Pattern pattern = Pattern.compile("[0-9]*");
  282. Matcher regexp = pattern.matcher(params[1]);
  283. if (regexp.matches())
  284. {
  285. npcId = Integer.parseInt(params[1]);
  286. }
  287. else
  288. {
  289. params[1] = params[1].replace('_', ' ');
  290. npcId = NpcData.getInstance().getTemplateByName(params[1]).getId();
  291. }
  292. if (params.length > 2)
  293. {
  294. teleportIndex = Integer.parseInt(params[2]);
  295. }
  296. }
  297. catch (Exception e)
  298. {
  299. activeChar.sendMessage("Command format is //list_spawns <npcId|npc_name> [tele_index]");
  300. }
  301. if (command.startsWith("admin_list_positions"))
  302. {
  303. findNPCInstances(activeChar, npcId, teleportIndex, true);
  304. }
  305. else
  306. {
  307. findNPCInstances(activeChar, npcId, teleportIndex, false);
  308. }
  309. }
  310. return true;
  311. }
  312. @Override
  313. public String[] getAdminCommandList()
  314. {
  315. return ADMIN_COMMANDS;
  316. }
  317. /**
  318. * Get all the spawn of a NPC.
  319. * @param activeChar
  320. * @param npcId
  321. * @param teleportIndex
  322. * @param showposition
  323. */
  324. private void findNPCInstances(L2PcInstance activeChar, int npcId, int teleportIndex, boolean showposition)
  325. {
  326. int index = 0;
  327. for (L2Spawn spawn : SpawnTable.getInstance().getSpawns(npcId))
  328. {
  329. index++;
  330. L2Npc npc = spawn.getLastSpawn();
  331. if (teleportIndex > -1)
  332. {
  333. if (teleportIndex == index)
  334. {
  335. if (showposition && (npc != null))
  336. {
  337. activeChar.teleToLocation(npc.getLocation(), true);
  338. }
  339. else
  340. {
  341. activeChar.teleToLocation(spawn.getLocation(), true);
  342. }
  343. }
  344. }
  345. else
  346. {
  347. if (showposition && (npc != null))
  348. {
  349. activeChar.sendMessage(index + " - " + spawn.getTemplate().getName() + " (" + spawn + "): " + npc.getX() + " " + npc.getY() + " " + npc.getZ());
  350. }
  351. else
  352. {
  353. activeChar.sendMessage(index + " - " + spawn.getTemplate().getName() + " (" + spawn + "): " + spawn.getX() + " " + spawn.getY() + " " + spawn.getZ());
  354. }
  355. }
  356. }
  357. if (index == 0)
  358. {
  359. activeChar.sendMessage(getClass().getSimpleName() + ": No current spawns found.");
  360. }
  361. }
  362. private void printSpawn(L2Npc target, int type)
  363. {
  364. int i = target.getId();
  365. int x = target.getSpawn().getX();
  366. int y = target.getSpawn().getY();
  367. int z = target.getSpawn().getZ();
  368. int h = target.getSpawn().getHeading();
  369. switch (type)
  370. {
  371. default:
  372. case 0:
  373. _log.info("('',1," + i + "," + x + "," + y + "," + z + ",0,0," + h + ",60,0,0),");
  374. break;
  375. case 1:
  376. _log.info("<spawn npcId=\"" + i + "\" x=\"" + x + "\" y=\"" + y + "\" z=\"" + z + "\" heading=\"" + h + "\" respawn=\"0\" />");
  377. break;
  378. case 2:
  379. _log.info("{ " + i + ", " + x + ", " + y + ", " + z + ", " + h + " },");
  380. break;
  381. }
  382. }
  383. private void spawnMonster(L2PcInstance activeChar, String monsterId, int respawnTime, int mobCount, boolean permanent)
  384. {
  385. L2Object target = activeChar.getTarget();
  386. if (target == null)
  387. {
  388. target = activeChar;
  389. }
  390. L2NpcTemplate template;
  391. if (monsterId.matches("[0-9]*"))
  392. {
  393. // First parameter was an ID number
  394. template = NpcData.getInstance().getTemplate(Integer.parseInt(monsterId));
  395. }
  396. else
  397. {
  398. // First parameter wasn't just numbers so go by name not ID
  399. template = NpcData.getInstance().getTemplateByName(monsterId.replace('_', ' '));
  400. }
  401. try
  402. {
  403. final L2Spawn spawn = new L2Spawn(template);
  404. if (Config.SAVE_GMSPAWN_ON_CUSTOM)
  405. {
  406. spawn.setCustom(true);
  407. }
  408. spawn.setX(target.getX());
  409. spawn.setY(target.getY());
  410. spawn.setZ(target.getZ());
  411. spawn.setAmount(mobCount);
  412. spawn.setHeading(activeChar.getHeading());
  413. spawn.setRespawnDelay(respawnTime);
  414. if (activeChar.getInstanceId() > 0)
  415. {
  416. spawn.setInstanceId(activeChar.getInstanceId());
  417. permanent = false;
  418. }
  419. else
  420. {
  421. spawn.setInstanceId(0);
  422. }
  423. // TODO add checks for GrandBossSpawnManager
  424. if (RaidBossSpawnManager.getInstance().isDefined(spawn.getId()))
  425. {
  426. activeChar.sendMessage("You cannot spawn another instance of " + template.getName() + ".");
  427. }
  428. else
  429. {
  430. if (template.isType("L2RaidBoss"))
  431. {
  432. spawn.setRespawnMinDelay(43200);
  433. spawn.setRespawnMaxDelay(129600);
  434. RaidBossSpawnManager.getInstance().addNewSpawn(spawn, 0, template.getBaseHpMax(), template.getBaseMpMax(), permanent);
  435. }
  436. else
  437. {
  438. SpawnTable.getInstance().addNewSpawn(spawn, permanent);
  439. spawn.init();
  440. }
  441. if (!permanent)
  442. {
  443. spawn.stopRespawn();
  444. }
  445. activeChar.sendMessage("Created " + template.getName() + " on " + target.getObjectId());
  446. }
  447. }
  448. catch (Exception e)
  449. {
  450. activeChar.sendPacket(SystemMessageId.TARGET_CANT_FOUND);
  451. }
  452. }
  453. private void showMonsters(L2PcInstance activeChar, int level, int from)
  454. {
  455. final List<L2NpcTemplate> mobs = NpcData.getInstance().getAllMonstersOfLevel(level);
  456. final int mobsCount = mobs.size();
  457. final StringBuilder tb = StringUtil.startAppend(500 + (mobsCount * 80), "<html><title>Spawn Monster:</title><body><p> Level : ", Integer.toString(level), "<br>Total Npc's : ", Integer.toString(mobsCount), "<br>");
  458. // Loop
  459. int i = from;
  460. for (int j = 0; (i < mobsCount) && (j < 50); i++, j++)
  461. {
  462. StringUtil.append(tb, "<a action=\"bypass -h admin_spawn_monster ", Integer.toString(mobs.get(i).getId()), "\">", mobs.get(i).getName(), "</a><br1>");
  463. }
  464. if (i == mobsCount)
  465. {
  466. tb.append("<br><center><button value=\"Back\" action=\"bypass -h admin_show_spawns\" width=40 height=15 back=\"L2UI_ct1.button_df\" fore=\"L2UI_ct1.button_df\"></center></body></html>");
  467. }
  468. else
  469. {
  470. StringUtil.append(tb, "<br><center><button value=\"Next\" action=\"bypass -h admin_spawn_index ", Integer.toString(level), " ", Integer.toString(i), "\" width=40 height=15 back=\"L2UI_ct1.button_df\" fore=\"L2UI_ct1.button_df\"><button value=\"Back\" action=\"bypass -h admin_show_spawns\" width=40 height=15 back=\"L2UI_ct1.button_df\" fore=\"L2UI_ct1.button_df\"></center></body></html>");
  471. }
  472. activeChar.sendPacket(new NpcHtmlMessage(tb.toString()));
  473. }
  474. private void showNpcs(L2PcInstance activeChar, String starting, int from)
  475. {
  476. final List<L2NpcTemplate> mobs = NpcData.getInstance().getAllNpcStartingWith(starting);
  477. final int mobsCount = mobs.size();
  478. final StringBuilder tb = StringUtil.startAppend(500 + (mobsCount * 80), "<html><title>Spawn Monster:</title><body><p> There are ", Integer.toString(mobsCount), " Npcs whose name starts with ", starting, ":<br>");
  479. // Loop
  480. int i = from;
  481. for (int j = 0; (i < mobsCount) && (j < 50); i++, j++)
  482. {
  483. StringUtil.append(tb, "<a action=\"bypass -h admin_spawn_monster ", Integer.toString(mobs.get(i).getId()), "\">", mobs.get(i).getName(), "</a><br1>");
  484. }
  485. if (i == mobsCount)
  486. {
  487. tb.append("<br><center><button value=\"Back\" action=\"bypass -h admin_show_npcs\" width=40 height=15 back=\"L2UI_ct1.button_df\" fore=\"L2UI_ct1.button_df\"></center></body></html>");
  488. }
  489. else
  490. {
  491. StringUtil.append(tb, "<br><center><button value=\"Next\" action=\"bypass -h admin_npc_index ", starting, " ", Integer.toString(i), "\" width=40 height=15 back=\"L2UI_ct1.button_df\" fore=\"L2UI_ct1.button_df\"><button value=\"Back\" action=\"bypass -h admin_show_npcs\" width=40 height=15 back=\"L2UI_ct1.button_df\" fore=\"L2UI_ct1.button_df\"></center></body></html>");
  492. }
  493. activeChar.sendPacket(new NpcHtmlMessage(tb.toString()));
  494. }
  495. }