diff --git a/gameserver/src/main/java/brainwine/gameserver/GameServer.java b/gameserver/src/main/java/brainwine/gameserver/GameServer.java index 23460c8..608275b 100644 --- a/gameserver/src/main/java/brainwine/gameserver/GameServer.java +++ b/gameserver/src/main/java/brainwine/gameserver/GameServer.java @@ -7,6 +7,8 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import brainwine.gameserver.entity.player.PlayerManager; +import brainwine.gameserver.msgpack.MessagePackHelper; +import brainwine.gameserver.server.NetworkRegistry; import brainwine.gameserver.server.Server; import brainwine.gameserver.zone.ZoneManager; @@ -29,8 +31,10 @@ public class GameServer { long startTime = System.currentTimeMillis(); logger.info("Starting GameServer ..."); GameConfiguration.init(); + MessagePackHelper.init(); zoneManager = new ZoneManager(); playerManager = new PlayerManager(); + NetworkRegistry.init(); server = new Server(); server.addEndpoint(5002); ConsoleThread consoleThread = new ConsoleThread(this); diff --git a/gameserver/src/main/java/brainwine/gameserver/server/Command.java b/gameserver/src/main/java/brainwine/gameserver/server/Command.java index 3d4d604..5c39f62 100644 --- a/gameserver/src/main/java/brainwine/gameserver/server/Command.java +++ b/gameserver/src/main/java/brainwine/gameserver/server/Command.java @@ -2,54 +2,14 @@ package brainwine.gameserver.server; import java.io.IOException; import java.lang.reflect.Field; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; import org.msgpack.unpacker.Unpacker; -import brainwine.gameserver.reflections.ReflectionsHelper; +import brainwine.gameserver.server.commands.BlocksIgnoreCommand; import brainwine.gameserver.server.pipeline.Connection; -@SuppressWarnings("unchecked") public abstract class Command { - private static final Logger logger = LogManager.getLogger(); - private static final Map> commands = new HashMap<>(); - - static { - Set> classes = ReflectionsHelper.getTypesAnnotatedWith(RegisterCommand.class); - - for(Class clazz : classes) { - if(!Command.class.isAssignableFrom(clazz)) { - logger.warn("Attempted to register non-command {}", clazz.getName()); - continue; - } - - RegisterCommand info = clazz.getAnnotation(RegisterCommand.class); - registerCommand(info.id(), (Class)clazz); - } - } - - public static void registerCommand(int id, Class type) { - if(commands.containsKey(id)) { - logger.warn("Attempted to register duplicate command {}", type.getTypeName()); - return; - } - - commands.put(id, type); - } - - public static Command instantiateCommand(int id) throws InstantiationException, IllegalAccessException { - if(!commands.containsKey(id)) { - return null; - } - - return commands.get(id).newInstance(); - } - public abstract void process(Connection connection); /** diff --git a/gameserver/src/main/java/brainwine/gameserver/server/Message.java b/gameserver/src/main/java/brainwine/gameserver/server/Message.java index c308aaf..1cc7556 100644 --- a/gameserver/src/main/java/brainwine/gameserver/server/Message.java +++ b/gameserver/src/main/java/brainwine/gameserver/server/Message.java @@ -5,62 +5,14 @@ import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import java.util.HashMap; import java.util.List; -import java.util.Map; -import java.util.Set; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; import org.msgpack.packer.Packer; -import brainwine.gameserver.reflections.ReflectionsHelper; - -@SuppressWarnings("unchecked") public abstract class Message { - private static final Logger logger = LogManager.getLogger(); - private static final Map, Integer> messageIds = new HashMap<>(); - private static final Map, MessageOptions> messageOptions = new HashMap<>(); - - static { - Set> classes = ReflectionsHelper.getTypesAnnotatedWith(RegisterMessage.class); - - for(Class clazz : classes) { - if(!Message.class.isAssignableFrom(clazz)) { - logger.warn("Attempted to register non-message {}", clazz.getName()); - continue; - } - - RegisterMessage info = clazz.getAnnotation(RegisterMessage.class); - registerMessage((Class)clazz, info.id(), new MessageOptions(info)); - } - } - - public static void registerMessage(Class type, int id) { - registerMessage(type, id, new MessageOptions(false, false, false, false)); - } - - public static void registerMessage(Class type, int id, MessageOptions options) { - if(messageIds.containsKey(type)) { - logger.warn("Attempted to register duplicate message {}", type.getTypeName()); - return; - } - - messageIds.put(type, id); - messageOptions.put(type, options); - } - - public static int getMessageId(Message message) { - return messageIds.getOrDefault(message.getClass(), 0); - } - - public static MessageOptions getMessageOptions(Message message) { - return messageOptions.get(message.getClass()); - } - public void pack(Packer packer) throws IOException, IllegalArgumentException, IllegalAccessException { - MessageOptions options = getMessageOptions(this); + MessageOptions options = NetworkRegistry.getMessageOptions(this); Field[] fields = getClass().getFields(); if(options.isPrepacked()) { diff --git a/gameserver/src/main/java/brainwine/gameserver/server/NetworkRegistry.java b/gameserver/src/main/java/brainwine/gameserver/server/NetworkRegistry.java new file mode 100644 index 0000000..ad7dbfd --- /dev/null +++ b/gameserver/src/main/java/brainwine/gameserver/server/NetworkRegistry.java @@ -0,0 +1,101 @@ +package brainwine.gameserver.server; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import brainwine.gameserver.reflections.ReflectionsHelper; + +public class NetworkRegistry { + + private static final Logger logger = LogManager.getLogger(); + private static final Map> commands = new HashMap<>(); + private static final Map, Integer> messageIds = new HashMap<>(); + private static final Map, MessageOptions> messageOptions = new HashMap<>(); + private static boolean initialized = false; + + public static void init() { + if(initialized) { + logger.warn("init() called twice"); + return; + } + + initialized = true; + registerCommands(); + registerMessages(); + } + + @SuppressWarnings("unchecked") + private static void registerCommands() { + logger.info("Registering commands ..."); + Set> classes = ReflectionsHelper.getTypesAnnotatedWith(RegisterCommand.class); + + for(Class clazz : classes) { + if(!Command.class.isAssignableFrom(clazz)) { + logger.warn("Attempted to register non-command {}", clazz.getName()); + continue; + } + + RegisterCommand info = clazz.getAnnotation(RegisterCommand.class); + registerCommand(info.id(), (Class)clazz); + } + } + + @SuppressWarnings("unchecked") + private static void registerMessages() { + logger.info("Registering messages ..."); + Set> classes = ReflectionsHelper.getTypesAnnotatedWith(RegisterMessage.class); + + for(Class clazz : classes) { + if(!Message.class.isAssignableFrom(clazz)) { + logger.warn("Attempted to register non-message {}", clazz.getName()); + continue; + } + + RegisterMessage info = clazz.getAnnotation(RegisterMessage.class); + registerMessage((Class)clazz, info.id(), new MessageOptions(info)); + } + } + + public static void registerCommand(int id, Class type) { + if(commands.containsKey(id)) { + logger.warn("Attempted to register duplicate command {}", type.getTypeName()); + return; + } + + commands.put(id, type); + } + + public static Command instantiateCommand(int id) throws InstantiationException, IllegalAccessException { + if(!commands.containsKey(id)) { + return null; + } + + return commands.get(id).newInstance(); + } + + public static void registerMessage(Class type, int id) { + registerMessage(type, id, new MessageOptions(false, false, false, false)); + } + + public static void registerMessage(Class type, int id, MessageOptions options) { + if(messageIds.containsKey(type)) { + logger.warn("Attempted to register duplicate message {}", type.getTypeName()); + return; + } + + messageIds.put(type, id); + messageOptions.put(type, options); + } + + public static int getMessageId(Message message) { + return messageIds.getOrDefault(message.getClass(), 0); + } + + public static MessageOptions getMessageOptions(Message message) { + return messageOptions.get(message.getClass()); + } +} diff --git a/gameserver/src/main/java/brainwine/gameserver/server/pipeline/CommandDecoder.java b/gameserver/src/main/java/brainwine/gameserver/server/pipeline/CommandDecoder.java index be72ffe..2232d26 100644 --- a/gameserver/src/main/java/brainwine/gameserver/server/pipeline/CommandDecoder.java +++ b/gameserver/src/main/java/brainwine/gameserver/server/pipeline/CommandDecoder.java @@ -7,6 +7,7 @@ import org.msgpack.unpacker.Unpacker; import brainwine.gameserver.msgpack.MessagePackHelper; import brainwine.gameserver.server.Command; +import brainwine.gameserver.server.NetworkRegistry; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.MessageToMessageDecoder; @@ -17,7 +18,7 @@ public class CommandDecoder extends MessageToMessageDecoder { protected void decode(ChannelHandlerContext ctx, ByteBuf buf, List out) throws Exception { int id = buf.readByte() & 0xFF; buf.readIntLE(); // body length - Command command = Command.instantiateCommand(id); + Command command = NetworkRegistry.instantiateCommand(id); if(command == null) { throw new IOException("Client sent invalid command: " + id); diff --git a/gameserver/src/main/java/brainwine/gameserver/server/pipeline/MessageEncoder.java b/gameserver/src/main/java/brainwine/gameserver/server/pipeline/MessageEncoder.java index 1ca3d96..3c4e50e 100644 --- a/gameserver/src/main/java/brainwine/gameserver/server/pipeline/MessageEncoder.java +++ b/gameserver/src/main/java/brainwine/gameserver/server/pipeline/MessageEncoder.java @@ -12,6 +12,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import brainwine.gameserver.msgpack.MessagePackHelper; import brainwine.gameserver.server.Message; import brainwine.gameserver.server.MessageOptions; +import brainwine.gameserver.server.NetworkRegistry; import brainwine.gameserver.util.ZipUtils; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; @@ -23,8 +24,8 @@ public class MessageEncoder extends MessageToByteEncoder { @Override protected void encode(ChannelHandlerContext ctx, Message in, ByteBuf out) throws Exception { - int id = Message.getMessageId(in); - MessageOptions options = Message.getMessageOptions(in); + int id = NetworkRegistry.getMessageId(in); + MessageOptions options = NetworkRegistry.getMessageOptions(in); if(id == 0) { throw new IOException("Attempted to encode unregistered message " + in.getClass());