Java tutorial
/* * 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 lineage2.gameserver.data.xml.parser; import java.io.File; import java.io.Serializable; import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import lineage2.commons.collections.MultiValueSet; import lineage2.commons.data.xml.AbstractDirParser; import lineage2.gameserver.Config; import lineage2.gameserver.data.xml.holder.EventHolder; import lineage2.gameserver.model.entity.events.EventAction; import lineage2.gameserver.model.entity.events.EventType; import lineage2.gameserver.model.entity.events.GlobalEvent; import lineage2.gameserver.model.entity.events.actions.ActiveDeactiveAction; import lineage2.gameserver.model.entity.events.actions.AnnounceAction; import lineage2.gameserver.model.entity.events.actions.GiveItemAction; import lineage2.gameserver.model.entity.events.actions.IfElseAction; import lineage2.gameserver.model.entity.events.actions.InitAction; import lineage2.gameserver.model.entity.events.actions.NpcSayAction; import lineage2.gameserver.model.entity.events.actions.OpenCloseAction; import lineage2.gameserver.model.entity.events.actions.PlaySoundAction; import lineage2.gameserver.model.entity.events.actions.RefreshAction; import lineage2.gameserver.model.entity.events.actions.SayAction; import lineage2.gameserver.model.entity.events.actions.SpawnDespawnAction; import lineage2.gameserver.model.entity.events.actions.StartStopAction; import lineage2.gameserver.model.entity.events.actions.TeleportPlayersAction; import lineage2.gameserver.model.entity.events.objects.BoatPoint; import lineage2.gameserver.model.entity.events.objects.CTBTeamObject; import lineage2.gameserver.model.entity.events.objects.CastleDamageZoneObject; import lineage2.gameserver.model.entity.events.objects.DoorObject; import lineage2.gameserver.model.entity.events.objects.FortressCombatFlagObject; import lineage2.gameserver.model.entity.events.objects.SiegeToggleNpcObject; import lineage2.gameserver.model.entity.events.objects.SpawnExObject; import lineage2.gameserver.model.entity.events.objects.StaticObjectObject; import lineage2.gameserver.model.entity.events.objects.ZoneObject; import lineage2.gameserver.network.serverpackets.PlaySound; import lineage2.gameserver.network.serverpackets.components.ChatType; import lineage2.gameserver.network.serverpackets.components.NpcString; import lineage2.gameserver.network.serverpackets.components.SysString; import lineage2.gameserver.network.serverpackets.components.SystemMsg; import lineage2.gameserver.utils.Location; import org.dom4j.Element; /** * @author Mobius * @version $Revision: 1.0 $ */ public final class EventParser extends AbstractDirParser<EventHolder> { private static final EventParser _instance = new EventParser(); /** * Method getInstance. * @return EventParser */ public static EventParser getInstance() { return _instance; } /** * Constructor for EventParser. */ protected EventParser() { super(EventHolder.getInstance()); } /** * Method getXMLDir. * @return File */ @Override public File getXMLDir() { return new File(Config.DATAPACK_ROOT, "data/xml/events/"); } /** * Method isIgnored. * @param f File * @return boolean */ @Override public boolean isIgnored(File f) { return false; } /** * Method getDTDFileName. * @return String */ @Override public String getDTDFileName() { return "events.dtd"; } /** * Method readData. * @param rootElement Element * @throws Exception */ @Override @SuppressWarnings("unchecked") protected void readData(Element rootElement) throws Exception { for (Iterator<?> iterator = rootElement.elementIterator("event"); iterator.hasNext();) { Element eventElement = (Element) iterator.next(); int id = Integer.parseInt(eventElement.attributeValue("id")); String name = eventElement.attributeValue("name"); String impl = eventElement.attributeValue("impl"); EventType type = EventType.valueOf(eventElement.attributeValue("type")); Class<GlobalEvent> eventClass = null; try { eventClass = (Class<GlobalEvent>) Class .forName("lineage2.gameserver.model.entity.events.impl." + impl + "Event"); } catch (ClassNotFoundException e) { info("Not found impl class: " + impl + "; File: " + getCurrentFileName()); continue; } Constructor<GlobalEvent> constructor = eventClass.getConstructor(MultiValueSet.class); MultiValueSet<String> set = new MultiValueSet<>(); set.set("id", id); set.set("name", name); for (Iterator<?> parameterIterator = eventElement.elementIterator("parameter"); parameterIterator .hasNext();) { Element parameterElement = (Element) parameterIterator.next(); set.set(parameterElement.attributeValue("name"), parameterElement.attributeValue("value")); } GlobalEvent event = constructor.newInstance(set); event.addOnStartActions(parseActions(eventElement.element("on_start"), Integer.MAX_VALUE)); event.addOnStopActions(parseActions(eventElement.element("on_stop"), Integer.MAX_VALUE)); event.addOnInitActions(parseActions(eventElement.element("on_init"), Integer.MAX_VALUE)); Element onTime = eventElement.element("on_time"); if (onTime != null) { for (Iterator<?> onTimeIterator = onTime.elementIterator("on"); onTimeIterator.hasNext();) { Element on = (Element) onTimeIterator.next(); int time = Integer.parseInt(on.attributeValue("time")); List<EventAction> actions = parseActions(on, time); event.addOnTimeActions(time, actions); } } for (Iterator<?> objectIterator = eventElement.elementIterator("objects"); objectIterator.hasNext();) { Element objectElement = (Element) objectIterator.next(); String objectsName = objectElement.attributeValue("name"); List<Serializable> objects = parseObjects(objectElement); event.addObjects(objectsName, objects); } getHolder().addEvent(type, event); } } /** * Method parseObjects. * @param element Element * @return List<Serializable> */ private List<Serializable> parseObjects(Element element) { if (element == null) { return Collections.emptyList(); } List<Serializable> objects = new ArrayList<>(2); for (Iterator<?> objectsIterator = element.elementIterator(); objectsIterator.hasNext();) { Element objectsElement = (Element) objectsIterator.next(); final String nodeName = objectsElement.getName(); if (nodeName.equalsIgnoreCase("boat_point")) { objects.add(BoatPoint.parse(objectsElement)); } else if (nodeName.equalsIgnoreCase("point")) { objects.add(Location.parse(objectsElement)); } else if (nodeName.equalsIgnoreCase("spawn_ex")) { objects.add(new SpawnExObject(objectsElement.attributeValue("name"))); } else if (nodeName.equalsIgnoreCase("door")) { objects.add(new DoorObject(Integer.parseInt(objectsElement.attributeValue("id")))); } else if (nodeName.equalsIgnoreCase("static_object")) { objects.add(new StaticObjectObject(Integer.parseInt(objectsElement.attributeValue("id")))); } else if (nodeName.equalsIgnoreCase("combat_flag")) { int x = Integer.parseInt(objectsElement.attributeValue("x")); int y = Integer.parseInt(objectsElement.attributeValue("y")); int z = Integer.parseInt(objectsElement.attributeValue("z")); objects.add(new FortressCombatFlagObject(new Location(x, y, z))); } else if (nodeName.equalsIgnoreCase("siege_toggle_npc")) { int id = Integer.parseInt(objectsElement.attributeValue("id")); int fakeId = Integer.parseInt(objectsElement.attributeValue("fake_id")); int x = Integer.parseInt(objectsElement.attributeValue("x")); int y = Integer.parseInt(objectsElement.attributeValue("y")); int z = Integer.parseInt(objectsElement.attributeValue("z")); int hp = Integer.parseInt(objectsElement.attributeValue("hp")); Set<String> set = Collections.emptySet(); for (Iterator<?> oIterator = objectsElement.elementIterator(); oIterator.hasNext();) { Element sub = (Element) oIterator.next(); if (set.isEmpty()) { set = new HashSet<>(); } set.add(sub.attributeValue("name")); } objects.add(new SiegeToggleNpcObject(id, fakeId, new Location(x, y, z), hp, set)); } else if (nodeName.equalsIgnoreCase("castle_zone")) { long price = Long.parseLong(objectsElement.attributeValue("price")); objects.add(new CastleDamageZoneObject(objectsElement.attributeValue("name"), price)); } else if (nodeName.equalsIgnoreCase("zone")) { objects.add(new ZoneObject(objectsElement.attributeValue("name"))); } else if (nodeName.equalsIgnoreCase("ctb_team")) { int mobId = Integer.parseInt(objectsElement.attributeValue("mob_id")); int flagId = Integer.parseInt(objectsElement.attributeValue("id")); Location loc = Location.parse(objectsElement); objects.add(new CTBTeamObject(mobId, flagId, loc)); } } return objects; } /** * Method parseActions. * @param element Element * @param time int * @return List<EventAction> */ private List<EventAction> parseActions(Element element, int time) { if (element == null) { return Collections.emptyList(); } IfElseAction lastIf = null; List<EventAction> actions = new ArrayList<>(0); for (Iterator<?> iterator = element.elementIterator(); iterator.hasNext();) { Element actionElement = (Element) iterator.next(); if (actionElement.getName().equalsIgnoreCase("start")) { String name = actionElement.attributeValue("name"); StartStopAction startStopAction = new StartStopAction(name, true); actions.add(startStopAction); } else if (actionElement.getName().equalsIgnoreCase("stop")) { String name = actionElement.attributeValue("name"); StartStopAction startStopAction = new StartStopAction(name, false); actions.add(startStopAction); } else if (actionElement.getName().equalsIgnoreCase("spawn")) { String name = actionElement.attributeValue("name"); SpawnDespawnAction spawnDespawnAction = new SpawnDespawnAction(name, true); actions.add(spawnDespawnAction); } else if (actionElement.getName().equalsIgnoreCase("despawn")) { String name = actionElement.attributeValue("name"); SpawnDespawnAction spawnDespawnAction = new SpawnDespawnAction(name, false); actions.add(spawnDespawnAction); } else if (actionElement.getName().equalsIgnoreCase("open")) { String name = actionElement.attributeValue("name"); OpenCloseAction a = new OpenCloseAction(true, name); actions.add(a); } else if (actionElement.getName().equalsIgnoreCase("close")) { String name = actionElement.attributeValue("name"); OpenCloseAction a = new OpenCloseAction(false, name); actions.add(a); } else if (actionElement.getName().equalsIgnoreCase("active")) { String name = actionElement.attributeValue("name"); ActiveDeactiveAction a = new ActiveDeactiveAction(true, name); actions.add(a); } else if (actionElement.getName().equalsIgnoreCase("deactive")) { String name = actionElement.attributeValue("name"); ActiveDeactiveAction a = new ActiveDeactiveAction(false, name); actions.add(a); } else if (actionElement.getName().equalsIgnoreCase("refresh")) { String name = actionElement.attributeValue("name"); RefreshAction a = new RefreshAction(name); actions.add(a); } else if (actionElement.getName().equalsIgnoreCase("init")) { String name = actionElement.attributeValue("name"); InitAction a = new InitAction(name); actions.add(a); } else if (actionElement.getName().equalsIgnoreCase("npc_say")) { int npc = Integer.parseInt(actionElement.attributeValue("npc")); ChatType chat = ChatType.valueOf(actionElement.attributeValue("chat")); int range = Integer.parseInt(actionElement.attributeValue("range")); NpcString string = NpcString.valueOf(actionElement.attributeValue("text")); NpcSayAction action = new NpcSayAction(npc, range, chat, string); actions.add(action); } else if (actionElement.getName().equalsIgnoreCase("play_sound")) { int range = Integer.parseInt(actionElement.attributeValue("range")); String sound = actionElement.attributeValue("sound"); PlaySound.Type type = PlaySound.Type.valueOf(actionElement.attributeValue("type")); PlaySoundAction action = new PlaySoundAction(range, sound, type); actions.add(action); } else if (actionElement.getName().equalsIgnoreCase("give_item")) { int itemId = Integer.parseInt(actionElement.attributeValue("id")); long count = Integer.parseInt(actionElement.attributeValue("count")); GiveItemAction action = new GiveItemAction(itemId, count); actions.add(action); } else if (actionElement.getName().equalsIgnoreCase("announce")) { String val = actionElement.attributeValue("val"); if ((val == null) && (time == Integer.MAX_VALUE)) { info("Can't get announce time." + getCurrentFileName()); continue; } int val2 = val == null ? time : Integer.parseInt(val); EventAction action = new AnnounceAction(val2); actions.add(action); } else if (actionElement.getName().equalsIgnoreCase("if")) { String name = actionElement.attributeValue("name"); IfElseAction action = new IfElseAction(name, false); action.setIfList(parseActions(actionElement, time)); actions.add(action); lastIf = action; } else if (actionElement.getName().equalsIgnoreCase("ifnot")) { String name = actionElement.attributeValue("name"); IfElseAction action = new IfElseAction(name, true); action.setIfList(parseActions(actionElement, time)); actions.add(action); lastIf = action; } else if (actionElement.getName().equalsIgnoreCase("else")) { if (lastIf == null) { info("Not find <if> for <else> tag"); } else { lastIf.setElseList(parseActions(actionElement, time)); } } else if (actionElement.getName().equalsIgnoreCase("say")) { ChatType chat = ChatType.valueOf(actionElement.attributeValue("chat")); int range = Integer.parseInt(actionElement.attributeValue("range")); String how = actionElement.attributeValue("how"); String text = actionElement.attributeValue("text"); SysString sysString = SysString.valueOf2(how); SayAction sayAction = null; if (sysString != null) { sayAction = new SayAction(range, chat, sysString, SystemMsg.valueOf(text)); } else { sayAction = new SayAction(range, chat, how, NpcString.valueOf(text)); } actions.add(sayAction); } else if (actionElement.getName().equalsIgnoreCase("teleport_players")) { String name = actionElement.attributeValue("id"); TeleportPlayersAction a = new TeleportPlayersAction(name); actions.add(a); } } return actions.isEmpty() ? Collections.<EventAction>emptyList() : actions; } }