Last active
September 28, 2024 11:45
-
-
Save Williams0ff/f044f95524c805a72fbef9bcad126e1c to your computer and use it in GitHub Desktop.
L2jOne - Commands SpawnManeger
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/aCis_gameserver/java/net/sf/l2j/gameserver/handler/admincommandhandlers/AdminSpawn.java b/aCis_gameserver/java/net/sf/l2j/gameserver/handler/admincommandhandlers/AdminSpawn.java | |
index 0a20e4a..a367708 100644 | |
--- a/aCis_gameserver/java/net/sf/l2j/gameserver/handler/admincommandhandlers/AdminSpawn.java | |
+++ b/aCis_gameserver/java/net/sf/l2j/gameserver/handler/admincommandhandlers/AdminSpawn.java | |
@@ -197,7 +197,7 @@ | |
spawn.setRespawnDelay(respawnTime); | |
spawn.doSpawn(false); | |
- SpawnManager.getInstance().addSpawn(spawn); | |
+ SpawnManager.getInstance().addSpawn(spawn, true); | |
player.sendMessage("You spawned " + template.getName() + ". - Cmd: " + cmd); | |
} | |
@@ -223,7 +224,7 @@ | |
// Npc ASpawn must be Spawn type. | |
final ASpawn spawn = targetNpc.getSpawn(); | |
- if (!(spawn instanceof Spawn)) | |
+ if (!(spawn instanceof Spawn) && !(spawn instanceof MultiSpawn)) | |
{ | |
player.sendPacket(SystemMessageId.INVALID_TARGET); | |
return; | |
@@ -231,9 +232,11 @@ | |
// Delete the Npc. | |
targetNpc.deleteMe(); | |
- | |
- // Delete the Spawn entry. | |
- SpawnManager.getInstance().deleteSpawn((Spawn) spawn); | |
+ | |
+ if (spawn instanceof MultiSpawn multi) | |
+ SpawnManager.getInstance().deleteSpawn(multi.getNpcMaker().getName()); | |
+ else if (spawn instanceof Spawn) | |
+ SpawnManager.getInstance().removeSpawn((Spawn) spawn); | |
// Send Player log. | |
player.sendMessage("You deleted " + targetNpc.getName() + "."); | |
diff --git a/aCis_gameserver/java/net/sf/l2j/gameserver/data/manager/SpawnManager.java b/aCis_gameserver/java/net/sf/l2j/gameserver/data/manager/SpawnManager.java | |
index 7e4bf6f..2ca0289 100644 | |
--- a/aCis_gameserver/java/net/sf/l2j/gameserver/data/manager/SpawnManager.java | |
+++ b/aCis_gameserver/java/net/sf/l2j/gameserver/data/manager/SpawnManager.java | |
@@ -1,5 +1,10 @@ | |
package net.sf.l2j.gameserver.data.manager; | |
+import java.io.BufferedReader; | |
+import java.io.BufferedWriter; | |
+import java.io.File; | |
+import java.io.FileReader; | |
+import java.io.FileWriter; | |
import java.nio.file.Path; | |
import java.sql.Connection; | |
import java.sql.PreparedStatement; | |
@@ -11,6 +16,13 @@ | |
import java.util.Set; | |
import java.util.concurrent.ConcurrentHashMap; | |
+import javax.xml.parsers.DocumentBuilder; | |
+import javax.xml.parsers.DocumentBuilderFactory; | |
+import javax.xml.transform.Transformer; | |
+import javax.xml.transform.TransformerFactory; | |
+import javax.xml.transform.dom.DOMSource; | |
+import javax.xml.transform.stream.StreamResult; | |
+ | |
import net.sf.l2j.commons.data.StatSet; | |
import net.sf.l2j.commons.data.xml.IXmlReader; | |
import net.sf.l2j.commons.geometry.Triangle; | |
@@ -22,6 +34,7 @@ | |
import net.sf.l2j.gameserver.data.xml.NpcData; | |
import net.sf.l2j.gameserver.enums.CabalType; | |
import net.sf.l2j.gameserver.enums.SealType; | |
+import net.sf.l2j.gameserver.model.World; | |
import net.sf.l2j.gameserver.model.actor.Npc; | |
import net.sf.l2j.gameserver.model.actor.template.NpcTemplate; | |
import net.sf.l2j.gameserver.model.location.Location; | |
@@ -37,7 +50,10 @@ | |
import net.sf.l2j.gameserver.scripting.Quest; | |
import org.w3c.dom.Document; | |
+import org.w3c.dom.Element; | |
import org.w3c.dom.NamedNodeMap; | |
+import org.w3c.dom.Node; | |
+import org.w3c.dom.NodeList; | |
/** | |
* Loads spawn list based on {@link Territory}s and {@link NpcMaker}s.<br> | |
@@ -58,6 +73,7 @@ | |
private final Set<Spawn> _spawns = ConcurrentHashMap.newKeySet(); | |
private int _dynamicGroupId = 0; | |
+ private int _index = 1; | |
public SpawnManager() | |
{ | |
@@ -785,6 +802,272 @@ | |
} | |
/** | |
+ * Adds a new spawn to the spawn table. | |
+ * @param spawn the spawn to add | |
+ * @param store if {@code true} it'll be saved in the spawn XML files | |
+ */ | |
+ public void addSpawn(Spawn spawn, boolean store) | |
+ { | |
+ addSpawn(spawn); | |
+ | |
+ if (store) | |
+ { | |
+ // Create output directory if it doesn't exist | |
+ final File outputDirectory = new File("./data/xml/spawnlist/custom/"); | |
+ if (!outputDirectory.exists()) | |
+ { | |
+ try | |
+ { | |
+ outputDirectory.mkdir(); | |
+ } | |
+ catch (SecurityException se) | |
+ { | |
+ // empty | |
+ } | |
+ } | |
+ | |
+ // index spawn | |
+ int index = _index++; | |
+ | |
+ // XML file for spawn | |
+ final String name = spawn.getNpc().getName().replaceAll("(\\s|')+","").toLowerCase(); | |
+ | |
+ final int x = ((spawn.getLocX() - World.WORLD_X_MIN) >> 15) + World.TILE_X_MIN; | |
+ final int y = ((spawn.getLocY() - World.WORLD_Y_MIN) >> 15) + World.TILE_Y_MIN; | |
+ final File spawnFile = new File("./data/xml/spawnlist/custom/" + name + "_" + x + "_" + y + ".xml"); | |
+ | |
+ // Write info to XML | |
+ final String spawnLoc = String.valueOf(spawn.getLocX() + ";" + spawn.getLocY() + ";" + spawn.getLocZ() + ";" + spawn.getHeading()); | |
+ | |
+ final var respawnDelay = getSpawn(spawn.getNpc().getNpcId()).getRespawnDelay() + "sec"; | |
+ | |
+ if (spawnFile.exists()) // update | |
+ { | |
+ final File tempFile = new File("./data/xml/spawnlist/custom/" + name + "_" + x + "_" + y + ".tmp"); | |
+ try (BufferedReader reader = new BufferedReader(new FileReader(spawnFile)); | |
+ BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile))) | |
+ { | |
+ String currentLine; | |
+ while ((currentLine = reader.readLine()) != null) | |
+ { | |
+ if (currentLine.contains("</list>")) | |
+ { | |
+ writer.write(" <territory name=\"" + name + "_" + x + "_" + y +"_0"+ index + "\" minZ=\"" + (spawn.getLocZ()) + "\" maxZ=\"" + (spawn.getLocZ() + 16) + "\">\n"); | |
+ writer.write(" <node x=\"" + (spawn.getLocX() + 50) + "\" y=\"" + (spawn.getLocY() + 50) + "\" />\n"); | |
+ writer.write(" <node x=\"" + (spawn.getLocX() - 50) + "\" y=\"" + (spawn.getLocY() + 50) + "\" />\n"); | |
+ writer.write(" <node x=\"" + (spawn.getLocX() - 50) + "\" y=\"" + (spawn.getLocY() - 50) + "\" />\n"); | |
+ writer.write(" <node x=\"" + (spawn.getLocX() + 50) + "\" y=\"" + (spawn.getLocY() - 50) + "\" />\n"); | |
+ writer.write(" </territory>\n"); | |
+ writer.write(" <npcmaker name=\"" + name + "_" + x + "_" + y +"_0"+ index + "\" territory=\"" + name + "_" + x + "_" + y +"_0"+ index + "\" maximumNpcs=\"" + 1 + "\">\n"); | |
+ writer.write(" <ai type=\"default_maker\"/>\n"); | |
+ writer.write(" <npc id=\"" + spawn.getNpcId() + "\" pos=\"" + spawnLoc + "\" total=\"" + 1 + "\" respawn=\"" + respawnDelay + "\" /> <!-- " + spawn.getNpc().getName() + " -->\n"); | |
+ writer.write(" </npcmaker>\n"); | |
+ writer.write(currentLine + "\n"); | |
+ continue; | |
+ } | |
+ writer.write(currentLine + "\n"); | |
+ } | |
+ writer.close(); | |
+ reader.close(); | |
+ spawnFile.delete(); | |
+ tempFile.renameTo(spawnFile); | |
+ } | |
+ catch (Exception e) | |
+ { | |
+ LOGGER.warn("Could not store spawn in the spawn XML files: " + e); | |
+ } | |
+ } | |
+ else // new file | |
+ { | |
+ try (BufferedWriter writer = new BufferedWriter(new FileWriter(spawnFile))) | |
+ { | |
+ writer.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"); | |
+ writer.write("<list>\n"); | |
+ writer.write(" <territory name=\"" + name + "_" + x + "_" + y +"_0"+ index + "\" minZ=\"" + (spawn.getLocZ()) + "\" maxZ=\"" + (spawn.getLocZ() + 16) + "\">\n"); | |
+ writer.write(" <node x=\"" + (spawn.getLocX() + 50) + "\" y=\"" + (spawn.getLocY() + 50) + "\" />\n"); | |
+ writer.write(" <node x=\"" + (spawn.getLocX() - 50) + "\" y=\"" + (spawn.getLocY() + 50) + "\" />\n"); | |
+ writer.write(" <node x=\"" + (spawn.getLocX() - 50) + "\" y=\"" + (spawn.getLocY() - 50) + "\" />\n"); | |
+ writer.write(" <node x=\"" + (spawn.getLocX() + 50) + "\" y=\"" + (spawn.getLocY() - 50) + "\" />\n"); | |
+ writer.write(" </territory>\n"); | |
+ writer.write(" <npcmaker name=\"" + name + "_" + x + "_" + y + "\" territory=\"" + name + "_" + x + "_" + y +"_0"+ index + "\" maximumNpcs=\"" + 1 + "\">\n"); | |
+ writer.write(" <ai type=\"default_maker\"/>\n"); | |
+ writer.write(" <npc id=\"" + spawn.getNpcId() + "\" pos=\"" + spawnLoc + "\" total=\"" + 1 + "\" respawn=\"" + respawnDelay + "\" /> <!-- " + spawn.getNpc().getName() + " -->\n"); | |
+ writer.write(" </npcmaker>\n"); | |
+ writer.write("</list>\n"); | |
+ writer.close(); | |
+ } | |
+ catch (Exception e) | |
+ { | |
+ LOGGER.warn("Spawn " + spawn + " could not be added to the spawn XML files: " + e); | |
+ } | |
+ } | |
+ } | |
+ } | |
+ | |
+ /** | |
+ * Removes the specific NPC from the spawn XML file. | |
+ * @param spawn the spawn to remove | |
+ */ | |
+ public void removeSpawn(Spawn spawn) | |
+ { | |
+ final String name = spawn.getNpc().getName().replaceAll("(\\s|')+", "").toLowerCase(); | |
+ final int x = ((spawn.getLocX() - World.WORLD_X_MIN) >> 15) + World.TILE_X_MIN; | |
+ final int y = ((spawn.getLocY() - World.WORLD_Y_MIN) >> 15) + World.TILE_Y_MIN; | |
+ final File spawnFile = new File("./data/xml/spawnlist/custom/" + name + "_" + x + "_" + y + ".xml"); | |
+ | |
+ if (!spawnFile.exists()) | |
+ { | |
+ LOGGER.warn("File for spawn {} not found.", spawn); | |
+ return; | |
+ } | |
+ | |
+ try | |
+ { | |
+ DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); | |
+ DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); | |
+ Document doc = dBuilder.parse(spawnFile); | |
+ doc.getDocumentElement().normalize(); | |
+ | |
+ String territoryName = null; | |
+ | |
+ NodeList npcMakers = doc.getElementsByTagName("npcmaker"); | |
+ for (int i = 0; i < npcMakers.getLength(); i++) | |
+ { | |
+ Element npcMaker = (Element) npcMakers.item(i); | |
+ NodeList npcs = npcMaker.getElementsByTagName("npc"); | |
+ boolean npcFound = false; | |
+ | |
+ for (int j = 0; j < npcs.getLength(); j++) | |
+ { | |
+ Element npc = (Element) npcs.item(j); | |
+ if (npc.getAttribute("id").equals(String.valueOf(spawn.getNpcId()))) | |
+ { | |
+ territoryName = npcMaker.getAttribute("territory"); | |
+ npcFound = true; | |
+ break; | |
+ } | |
+ } | |
+ | |
+ if (npcFound) | |
+ { | |
+ npcMaker.getParentNode().removeChild(npcMaker); | |
+ break; | |
+ } | |
+ } | |
+ | |
+ if (territoryName != null) | |
+ { | |
+ NodeList territories = doc.getElementsByTagName("territory"); | |
+ for (int i = 0; i < territories.getLength(); i++) | |
+ { | |
+ Element territory = (Element) territories.item(i); | |
+ if (territory.getAttribute("name").startsWith(name + "_" + x + "_" + y)) | |
+ { | |
+ territory.getParentNode().removeChild(territory); | |
+ break; | |
+ } | |
+ } | |
+ } | |
+ | |
+ TransformerFactory transformerFactory = TransformerFactory.newInstance(); | |
+ Transformer transformer = transformerFactory.newTransformer(); | |
+ DOMSource source = new DOMSource(doc); | |
+ StreamResult result = new StreamResult(spawnFile); | |
+ transformer.transform(source, result); | |
+ | |
+ LOGGER.info("Successfully removed spawn {} and its territory from XML.", spawn); | |
+ | |
+ } | |
+ catch (Exception e) | |
+ { | |
+ LOGGER.warn("Could not remove spawn {} from the spawn XML files: {}", spawn, e); | |
+ } | |
+ } | |
+ | |
+ /** | |
+ * Deletes a spawn associated with a {@link MultiSpawn}, removing both the associated npcMaker and territory. | |
+ * If no elements remain in the XML file, the file is deleted. | |
+ * @param spawnName the name of the {@link MultiSpawn} to be deleted | |
+ */ | |
+ public void deleteSpawn(String spawnName) | |
+ { | |
+ _spawns.removeIf(spawn -> spawn.getNpc().getName().equalsIgnoreCase(spawnName)); | |
+ | |
+ String xmlFileName = "./data/xml/spawnlist/custom/" + spawnName + ".xml"; | |
+ File xmlFile = new File(xmlFileName); | |
+ | |
+ if (xmlFile.exists() && xmlFile.isFile()) | |
+ { | |
+ try | |
+ { | |
+ DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); | |
+ DocumentBuilder docBuilder = docFactory.newDocumentBuilder(); | |
+ Document doc = docBuilder.parse(xmlFile); | |
+ | |
+ // Encontrar e remover os NPCs associados ao npcMaker e os territ�rios | |
+ NodeList npcMakerList = doc.getElementsByTagName("npcmaker"); | |
+ NodeList territoryList = doc.getElementsByTagName("territory"); | |
+ | |
+ boolean nodeRemoved = false; | |
+ | |
+ for (int i = npcMakerList.getLength() - 1; i >= 0; i--) | |
+ { | |
+ Element npcMakerElement = (Element) npcMakerList.item(i); | |
+ String npcMakerName = npcMakerElement.getAttribute("name"); | |
+ | |
+ if (npcMakerName.equalsIgnoreCase(spawnName)) | |
+ { | |
+ Node parentNode = npcMakerElement.getParentNode(); | |
+ parentNode.removeChild(npcMakerElement); | |
+ nodeRemoved = true; | |
+ } | |
+ } | |
+ | |
+ for (int i = territoryList.getLength() - 1; i >= 0; i--) | |
+ { | |
+ Element territoryElement = (Element) territoryList.item(i); | |
+ String territoryName = territoryElement.getAttribute("name"); | |
+ | |
+ if (territoryName.startsWith(spawnName)) | |
+ { | |
+ Node parentNode = territoryElement.getParentNode(); | |
+ parentNode.removeChild(territoryElement); | |
+ nodeRemoved = true; | |
+ } | |
+ } | |
+ | |
+ boolean isEmpty = doc.getDocumentElement().getChildNodes().getLength() == 0; | |
+ | |
+ if (isEmpty) | |
+ { | |
+ if (xmlFile.delete()) | |
+ LOGGER.info("Arquivo XML vazio deletado: {}", xmlFileName); | |
+ else | |
+ LOGGER.warn("Falha ao deletar o arquivo XML vazio: {}", xmlFileName); | |
+ } | |
+ else if (nodeRemoved) | |
+ { | |
+ TransformerFactory transformerFactory = TransformerFactory.newInstance(); | |
+ Transformer transformer = transformerFactory.newTransformer(); | |
+ DOMSource source = new DOMSource(doc); | |
+ StreamResult result = new StreamResult(xmlFile); | |
+ transformer.transform(source, result); | |
+ } | |
+ else | |
+ LOGGER.warn("Nenhum spawn encontrado para remover no arquivo XML: {}", xmlFileName); | |
+ } | |
+ catch (Exception e) | |
+ { | |
+ LOGGER.error("Erro ao modificar o arquivo XML de spawn: {}", xmlFileName, e); | |
+ } | |
+ } | |
+ else | |
+ { | |
+ LOGGER.warn("Arquivo XML n�o encontrado: {}", xmlFileName); | |
+ } | |
+ } | |
+ | |
+ /** | |
* Remove an individual {@link Spawn}. | |
* @param spawn : {@link Spawn} to be removed. | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment