package annotationassociate;
import annotationassociate.Main.Client;
import annotationassociate.Main.DataPacket;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
/**
*
* @author Jay
*/
public class HandlerManager {
public static enum HandlerList {
MOVEMENT("path.to.Handler");
private final String className;
private HandlerList(String className) {
this.className = className;
}
public String getName() {
return className;
}
}
private static Map<Integer, Method> handlers = new HashMap<Integer, Method>();
static {
try {
initialize();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
private static void initialize() throws ClassNotFoundException {
for (HandlerList handler : HandlerList.values()) {
Class c = Class.forName(handler.getName());
for (Method method : c.getMethods()) {
PacketIdentifier annotation = method.getAnnotation(PacketIdentifier.class);
if (annotation != null) {
if (isValidMethod(method)) {
if (handlers.containsKey(annotation.packetId())) {
System.out.println("Duplicate handler for packetId: " + annotation.packetId());
} else {
handlers.put(annotation.packetId(), method);
}
} else {
System.out.println("Failed to add handler with method name of: " + method.getName() + " in " + handler.getName());
}
}
}
}
}
private static boolean isValidMethod(Method method) {
Class[] types = method.getParameterTypes();
return types.length == 2 && types[0].equals(Client.class) && types[1].equals(DataPacket.class);
}
/**
* @param client The client to be passed to the handler
* @param data The DataPacket to be passed to the handler
* @param packetId 1/2/4 byte identifier which can be specified by the user.
*/
public static void handle(Client client, DataPacket data, int packetId) {
Method method = handlers.get(packetId);
try {
if (method != null) {
method.invoke(null, client, data);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
PacketIdentifier.java
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package annotationassociate;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
*
* @author Jay
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface PacketIdentifier {
int packetId();
}
This lets you identify methods to be used as packet handlers instead of using a switch statement/list of objects that inherit from something and putting them in a HashMap. This was just for fun, but I hope someone can find some use for it. If you want to change what's considered a valid handler look at isValidMethod inside of HandlerManager.Handler example for a chat server using netty:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package chatservernew.net.handlers;
import chatservernew.net.Client;
import chatservernew.net.Opcodes;
import chatservernew.net.ServerHandler;
import chatservernew.util.PacketIdentifier;
import chatservernew.util.PacketTools;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
/**
*
* @author Jay
*/
public class AuthHandler {
@PacketIdentifier(packetId = Opcodes.RECV_LOGIN)
public static void handleLogin(Client client, ChannelBuffer buffer) {
String nick = PacketTools.readString(buffer);
ChannelBuffer out = ChannelBuffers.buffer(2);
out.writeByte(Opcodes.SEND_LOGIN);
if (!ServerHandler.getNickConnections().containsKey(nick)) {
ServerHandler.getNickConnections().put(nick, client);
out.writeByte(1);
} else {
out.writeByte(0);
}
client.getChannel().write(out);
}
@PacketIdentifier(packetId = Opcodes.RECV_AUTHENTICATED)
public static void handleAuthenticated(Client client, ChannelBuffer buffer) {
ChannelBuffer out = ChannelBuffers.dynamicBuffer(32);
out.writeByte(Opcodes.SEND_USERS);
StringBuilder sb = new StringBuilder();
for (String str : ServerHandler.getNickConnections().keySet()) {
sb.append(str);
sb.append(" ");
}
PacketTools.writeString(out, sb.toString().trim());
client.getChannel().write(out);
}
@PacketIdentifier(packetId = Opcodes.RECV_CHAT)
public static void handleChat(Client client, ChannelBuffer buffer) {
String msg = PacketTools.readString(buffer);
ChannelBuffer out = ChannelBuffers.buffer(msg.length() + 3);
out.writeByte(Opcodes.SEND_CHAT);
PacketTools.writeString(out, msg);
for (Client user : ServerHandler.getNickConnections().values()) {
user.getChannel().write(out);
}
}
}
Where the DataPacket is replaced with ChannelBufferPost questions/opinions. Thanks :)
Edited by Generic, 26 December 2010 - 11:51 PM.


Sign In
Create Account


Back to top









