package com.snowcattle.game.service.net.message.facade;
import com.snowcattle.game.common.annotation.MessageCommandAnnotation;
import com.snowcattle.game.common.config.GameServerConfigService;
import com.snowcattle.game.common.constant.GlobalConstants;
import com.snowcattle.game.common.constant.Loggers;
import com.snowcattle.game.common.constant.ServiceName;
import com.snowcattle.game.common.exception.GameHandlerException;
import com.snowcattle.game.common.loader.DefaultClassLoader;
import com.snowcattle.game.common.loader.scanner.ClassScanner;
import com.snowcattle.game.manager.LocalMananger;
import com.snowcattle.game.message.handler.AbstractMessageHandler;
import com.snowcattle.game.message.handler.IMessageHandler;
import com.snowcattle.game.service.Reloadable;
import com.snowcattle.game.service.net.message.AbstractNetMessage;
import com.snowcattle.game.common.loader.DynamicGameClassLoader;
import com.snowcattle.game.service.IService;
import org.slf4j.Logger;
import org.springframework.stereotype.Service;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
/**
* Created by jiangwenping on 17/2/8.
*/
@Service
public class GameFacade implements IFacade ,Reloadable, IService{
/**
* Logger for this class
*/
public static final Logger logger = Loggers.serverLogger;
public ClassScanner messageScanner = new ClassScanner();
public String[] fileNames;
protected Map<Integer, IMessageHandler> handlers = new HashMap<Integer, IMessageHandler>();
public void addHandler(int httpCode, IMessageHandler handler) {
handlers.put(httpCode, handler);
}
@Override
public AbstractNetMessage dispatch(AbstractNetMessage message)
throws GameHandlerException {
try {
int cmd = message.getCmd();
IMessageHandler handler = handlers.get(cmd);
Method method = handler.getMessageHandler(cmd);
method.setAccessible(true);
Object object = method.invoke(handler,
message);
AbstractNetMessage result = null;
if(object != null){
result = (AbstractNetMessage) object;
}
return result;
} catch (Exception e) {
throw new GameHandlerException(e, message.getSerial());
}
}
public void loadPackage(String namespace, String ext)
throws Exception {
if(fileNames == null){
fileNames = messageScanner.scannerPackage(namespace, ext);
}
// 加载class,获取协议命令
DefaultClassLoader defaultClassLoader = LocalMananger.getInstance().getLocalSpringServiceManager().getDefaultClassLoader();
defaultClassLoader.resetDynamicGameClassLoader();
DynamicGameClassLoader dynamicGameClassLoader = defaultClassLoader.getDynamicGameClassLoader();
if(fileNames != null) {
for (String fileName : fileNames) {
String realClass = namespace
+ "."
+ fileName.subSequence(0, fileName.length()
- (ext.length()));
// Class<?> messageClass = null;
// FileClassLoader fileClassLoader = defaultClassLoader.getDefaultClassLoader();
// if (!defaultClassLoader.isJarLoad()) {
// defaultClassLoader.initClassLoaderPath(realClass, ext);
// byte[] bytes = fileClassLoader.getClassData(realClass);
// messageClass = dynamicGameClassLoader.findClass(realClass, bytes);
// } else {
// //读取 game_server_handler.jar包所在位置
// URL url = ClassLoader.getSystemClassLoader().getResource("./");
// File file = new File(url.getPath());
// File parentFile = new File(file.getParent());
// String jarPath = parentFile.getPath() + File.separator + "lib/game_server_handler.jar";
// logger.info("message load jar path:" + jarPath);
// JarFile jarFile = new JarFile(new File(jarPath));
// fileClassLoader.initJarPath(jarFile);
// byte[] bytes = fileClassLoader.getClassData(realClass);
// messageClass = dynamicGameClassLoader.findClass(realClass, bytes);
// }
Class<?> messageClass = Class.forName(realClass);
logger.info("handler load: " + messageClass);
IMessageHandler iMessageHandler = getMessageHandler(messageClass);
AbstractMessageHandler handler = (AbstractMessageHandler) iMessageHandler;
handler.init();
Method[] methods = messageClass.getMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(MessageCommandAnnotation.class)) {
MessageCommandAnnotation messageCommandAnnotation = (MessageCommandAnnotation) method
.getAnnotation(MessageCommandAnnotation.class);
if (messageCommandAnnotation != null) {
addHandler(messageCommandAnnotation.command(), iMessageHandler);
}
}
}
}
}
}
/**
* 获取消息对象
*
* @param commandId
* @return
* @throws Exception
*/
public final IMessageHandler getMessageHandler(Class<?> classes) {
try {
if (classes == null) {
return null;
}
IMessageHandler messageHandler = (IMessageHandler) classes
.newInstance();
return messageHandler;
} catch (Exception e) {
logger.error("getMessageHandler - classes=" + classes.getName()
+ ". ", e);
}
return null;
}
@Override
public void reload() throws Exception {
try {
GameServerConfigService gameServerConfigService = LocalMananger.getInstance().getLocalSpringServiceManager().getGameServerConfigService();
loadPackage(gameServerConfigService.getGameServerConfig().getNetMessageHandlerNameSpace(), GlobalConstants.MessageCommandConstants.Ext);
} catch (Exception e) {
logger.error(e.toString(), e);
}
}
@Override
public String getId() {
return ServiceName.GameFacade;
}
@Override
public void startup() throws Exception {
reload();
}
@Override
public void shutdown() throws Exception {
}
}