package com.aionemu.packetsamurai.protocol.protocoltree; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import com.aionemu.packetsamurai.PacketSamurai; import com.aionemu.packetsamurai.Util; import com.aionemu.packetsamurai.parser.PartType; import com.aionemu.packetsamurai.parser.parttypes.IntPartType; import javolution.util.FastMap; /** * This class is a container for {@link ProtocolNode ProtocolNodes} and also is a ProtocolNode * thus allowing an infinite depth tree structure for the protocol definition. * @author Gilles Duboscq * */ public class PacketFamilly extends ProtocolNode { private Map<Integer, ProtocolNode> _nodes; private PartType _switchType; private packetDirection _direction; private int _id; private String _name; public enum packetDirection { clientPacket, serverPacket } public PacketFamilly() { this((String)null); } public PacketFamilly(String name) { super(); _name = name; _nodes = new FastMap<Integer, ProtocolNode>(); } public PacketFamilly(int id) { this(id, null); } public PacketFamilly(int id, String name) { super(id); _id = id; _name = name; _nodes = new FastMap<Integer, ProtocolNode>(); } public void addNode(ProtocolNode node) { ProtocolNode old; if ((old = _nodes.put(node.getID(), node)) != null) { PacketSamurai.getUserInterface().log("WARNING: More then one packet in familly '"+_name+"' with id 0x"+Integer.toHexString(node.getID())+" ("+old+" && "+node+")"); } } /** * @return Returns the switchType. */ public PartType getSwitchType() { return _switchType; } /** * @param type The switchType to set. */ public void setSwitchType(PartType type) { if(!(type instanceof IntPartType)) { PacketSamurai.getUserInterface().log("Warrning!: Bad switchType For a PacketFamilly!"); return; } _switchType = type; } /** * @return Returns the _direction. */ public packetDirection getDirection() { return _direction; } /** * @param _direction The _direction to set. */ public void setDirection(packetDirection direction) { _direction = direction; } /** * @return Returns the _nodes. */ public Map<Integer, ProtocolNode> getNodes() { return _nodes; } public void setName(String name) { _name = name; } public String toString() { return (_name != null ? _name : Util.zeropad(Integer.toHexString(_id), 2).toUpperCase())+" familly"; } public String getName() { return _name; } /** * Used to remove a node in the tree (can be in sub-packetfamillies) * Node can be inexistant. * @param node */ public void remove(ProtocolNode node) { if(node == null) return; Iterator<Entry<Integer, ProtocolNode>> i = _nodes.entrySet().iterator(); while(i.hasNext()) { ProtocolNode testNode = i.next().getValue(); if(node == testNode) { i.remove(); } else if(testNode instanceof PacketFamilly) { ((PacketFamilly)testNode).remove(node); } } } }