I am trying to code a packet listener for a small server. I am very new to Java, and this is the first time I've been talking to the network. The whole idea that it receives a package corresponds to the identifier of the package with its class, passes the input stream to the package constructor so that it can be constructed, and then pass it to the packet Hander, which will have an overloaded method for each package. To achieve this, use an array that maps the packet identifiers to the classes of each and uses a method called decoding to build the packet. The problem is that handlePacket overloading does not behave as expected. Let's look at the code.
I have a packet listener in the stream, and the execution method looks like this:
public void run() { try { int packet_id; while ((packet_id = istream.readInt()) != -1) { plugin.getServer().getConsoleSender().sendMessage("[Comm] Recived packet " + packet_id); Packet packet = decode(packet_id, istream); plugin.getServer().getConsoleSender().sendMessage("[Comm] Packet is " + Class.forName(packet.getClass().getName())); plugin.getServer().getConsoleSender().sendMessage("[Comm] Class is " + Packet00ReqIdentify.class.cast(packet).getClass().getName()); plugin.getServer().getConsoleSender().sendMessage("[Comm] Class is " + Class.forName(packet.getClass().getName()).getName()); handlePacket(packet); } } catch (IOException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | ClassNotFoundException e) { e.printStackTrace(); } }
The decode and handlePacket methods are as follows:
private void handlePacket(Packet00ReqIdentify packet) throws IOException { plugin.getServer().getConsoleSender().sendMessage("[Comm] Got it!"); } private void handlePacket(Packet packet) { plugin.getServer().getConsoleSender().sendMessage("[Comm] Woops!"); } private Packet decode(int packet_id, PacketInputStream istream) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, ClassNotFoundException, IOException { Class<? extends Packet> packet_class = packets_ids.get(packet_id); try { Constructor<?> packet_constructor = packet_class.getConstructor(PacketInputStream.class); return Class.forName(packet_class.getName()).asSubclass(Packet.class).cast(packet_constructor.newInstance(istream)); } catch (NoSuchMethodException e) { return Class.forName(packet_class.getName()).asSubclass(Packet.class).cast(packet_class.newInstance()); } }
packets_ids is an array containing a reference to the class of each packet, indexed by their identifiers:
private static ArrayList<Class<? extends Packet>> packets_ids;
It is initialized as follows:
private static void registerPacket(int id, Class<? extends Packet> oclass) { packets_ids.add(id, oclass); } static { packets_ids = new ArrayList<Class<? extends Packet>>(); registerPacket(Packet00ReqIdentify.assigned_pid, Packet00ReqIdentify.class); registerPacket(Packet01Identify.assigned_pid, Packet01Identify.class); registerPacket(Packet02Heartbeat.assigned_pid, Packet02Heartbeat.class); }
If I performed this and tested it by sending a packet of type 00, I get the following:
17:37:49 [INFO] [Comm] Connection established to localhost:11000 17:37:49 [INFO] [Comm] Recived packet 0 17:37:49 [INFO] [Comm] Packet is class com.gamerarg.commclient.protocol.Packet00ReqIdentify 17:37:49 [INFO] [Comm] Class is com.gamerarg.commclient.protocol.Packet00ReqIdentify 17:37:49 [INFO] [Comm] Class is com.gamerarg.commclient.protocol.Packet00ReqIdentify 17:37:49 [INFO] [Comm] Woops!
So this means that packet00 was not bound by "handlePacket (Packet00ReqIdentify packet)". If I do an explicit cast to a “package” in a call to handlePacket, this works. So the questions are:
Why is this not working? When I print class names for both, I get the same thing.
How can I make it work? I struggled with this for 6 or 7 hours, read, searched, tried, and saw code from others. One simple solution is to make a switch using a packet identifier, but I want something more elegant. Maybye, I am mistaken from the basic idea, therefore, why I sent the code, I am open to suggestions and ideas from more experienced people in the subject, including recommendations for material in the subject.
Thanks!