package com.aelfengard.i3.packet;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.aelfengard.i3.LPCUtils;
import com.aelfengard.i3.LPCMixed;
public abstract class I3Packet {
private static final Map<String,Type> typeMap = new HashMap<String,Type>();
public static enum Type {
STARTUP_REQ(StartupReq3Packet.class),
STARTUP_REPLY(StartupReplyPacket.class),
MUD_LIST(MudListPacket.class),
CHANLIST_REPLY(ChanListReplyPacket.class),
CHANNEL_LISTEN(ChannelListenPacket.class),
CHANNEL_M(ChannelMPacket.class),
CHANNEL_E(ChannelEPacket.class),
CHANNEL_T(ChannelTPacket.class),
ERROR(ErrorPacket.class),
WHO_REQ(WhoReqPacket.class),
WHO_REPLY(WhoReplyPacket.class),
TELL(TellPacket.class),
EMOTE_TO(EmoteToPacket.class);
private final Class clazz;
private Type(Class clazz) {
try {
this.clazz = clazz;
String token = (String) clazz.getField("TOKEN").get(null);
typeMap.put(token, this);
}
catch (Exception ex) {
throw new RuntimeException(ex);
}
}
public Class getPacketClass() {
return clazz;
}
}
private final Type type;
public I3Packet(Type type) {
if (getClass() != type.getPacketClass()) {
throw new IllegalArgumentException(type + ", " + getClass());
}
this.type = type;
}
public static I3Packet forString(String s) {
List<LPCMixed> list = LPCUtils.lpcToJava(s).asList();
return forList(list);
}
public static I3Packet forList(List<LPCMixed> list) {
String typeString = list.get(0).asString();
Type type = typeMap.get(typeString);
if (type == null) {
return null; }
try {
Class clazz = type.getPacketClass();
Constructor c = clazz.getConstructor(List.class);
return (I3Packet) c.newInstance(list);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
public Type getType() {
return type;
}
public final String toString() {
return LPCUtils.javaToLPC(toList());
}
public abstract List<LPCMixed> toList();
}