📄 gameserver.java
字号:
package zsw_mmorpg.server;import zsw_mmorpg.common.*;import zsw_mmorpg.server.controller.*;import java.nio.channels.*;import java.util.*;import java.net.*;import java.io.*;import org.apache.log4j.*;/** * GameServer.java * 主类, GameServer 接受客户端连接并转到SelectAndRead 处理 * GameServer also keeps track of the connected players * @author <a href="mailto:shiwei@raymobile.com">朱世伟</a> * @version 1.0 */public class GameServer extends Thread { /** log4j Logger */ private Logger log = Logger.getLogger("GameServer"); /** ServerSocketChannel 用来接受玩家的连接 */ private ServerSocketChannel sSockChan; /** 多个 ServerSocketChannels 之间的选择器*/ private Selector selector; private Hashtable gameControllers; private static final String CONTROLLER_CLASS_PREFIX = "zsw_mmorpg.server.controller."; /** 登陆过的玩家列表 */ public static Hashtable playersByPlayerId; private static Hashtable playersBySessionId; private boolean running; private SelectAndRead selectAndRead; private EventWriter eventWriter; private static long nextSessionId = 0; /** * 启动GAMESERVER */ public static void main(String args[]) { BasicConfigurator.configure(); GameServer gs = new GameServer(); gs.start(); } /** * 初始化 hashtables */ public GameServer() { gameControllers = new Hashtable(); playersByPlayerId = new Hashtable(); playersBySessionId = new Hashtable(); } /** * 初始化 GameServer ,启动 selectAndRead */ public void init() { log.info("GameServer initializing"); loadGameControllers(); initServerSocket(); selectAndRead = new SelectAndRead(this); selectAndRead.start(); eventWriter = new EventWriter(this, Globals.EVENT_WRITER_WORKERS); } /** * 绑定端口,设置选择器 */ private void initServerSocket() { try { // 异步 ,无阻塞 socket channel sSockChan = ServerSocketChannel.open(); sSockChan.configureBlocking(false); // bind port InetAddress addr = InetAddress.getLocalHost(); log.info("binding to address: " + addr.getHostAddress()+":"+Globals.PORT); sSockChan.socket().bind(new InetSocketAddress(addr, Globals.PORT)); // selector = Selector.open(); // SelectionKey acceptKey = sSockChan.register(selector, SelectionKey.OP_ACCEPT); } catch (Exception e) { log.error("error initializing ServerSocket", e); System.exit(1); } } /** *循环调用 select() 接受连接,并把连接句柄交给 SelectAndRead处理 */ public void run() { init(); log.info("******** Shenzhou 1.0 *** GameServer running ********"); running = true; int numReady = 0; while (running) { try { selector.select(); // 取得索引 Set readyKeys = selector.selectedKeys(); Iterator i = readyKeys.iterator(); while (i.hasNext()) { SelectionKey key = (SelectionKey) i.next(); i.remove(); ServerSocketChannel ssChannel = (ServerSocketChannel) key.channel(); SocketChannel clientChannel = ssChannel.accept(); selectAndRead.addNewClient(clientChannel); log.info("got connection from: " + clientChannel.socket().getInetAddress()); } } catch (IOException ioe) { log.warn("error during serverSocket select(): " + ioe.getMessage()); } catch (Exception e) { log.error("exception in run()", e); } } } /** * 关闭 */ public void shutdown() { selector.wakeup(); } /** * 没用上 */ public synchronized String nextSessionId() { return "" + nextSessionId++; } /** * 取得GameController */ public GameController getGameController(String gameName) { return getGameControllerByHash(gameName.hashCode()); } public GameController getGameControllerByHash(int gameNameHash) {//没用 GameController gc = (GameController) gameControllers.get("" + gameNameHash); if (gc == null) log.error("no gamecontroller for gameNameHash: " + gameNameHash); return gc; } /** * 加载游戏的引擎 */ private void loadGameControllers() { log.info("loading GameControllers"); String baseClass = "zsw_mmorpg/server/controller/GameController.class"; File f = new File( this.getClass( ).getClassLoader().getResource(baseClass).getPath()); File[] files = f.getParentFile().listFiles( ); if (files == null) { log.error("error getting GameController directory"); return; } for( int i = 0; ( i < files.length); i++) { String file = files[i].getName( ); if (file.indexOf( ".class") == -1) continue; if (file.equals("GameController.class")) continue; try { // String controllerClassName = CONTROLLER_CLASS_PREFIX + file.substring(0, file.indexOf(".class")); log.info("loading class: " + controllerClassName); Class cl = Class.forName(controllerClassName); if (!GameController.class.isAssignableFrom(cl)) { log.warn("class file does not extend GameController: " + file); continue; } // get an instance GameController gc = (GameController) cl.newInstance(); String gameName = gc.getGameName(); gc.init(this, getGameConfig(gameName)); gameControllers.put("" + gameName.hashCode(), gc); // log.info("loaded controller for gameName: " + gameName + ", hash: " + gameName.hashCode()); } catch (Exception e) { log.error("Error instantiating GameController from file: " + file, e); } } } /** * 把事件传给 EventWriter */ public void writeEvent(GameEvent e) { eventWriter.handleEvent(e); } public GameConfig getGameConfig(String gameName) { // todo: implement getGameConfig() return null; } /** * 给定playerId,取得玩家句柄 */ public static Player getPlayerById( String id) { return (Player) playersByPlayerId.get(id); } /** * 检查该用户是否在线 */ public static boolean checkPlayerById( String id) { return playersByPlayerId.containsKey(id); } /** * 没有用 */ public static Player getPlayerBySessionId(String id) { return (Player) playersBySessionId.get(id); } /** * 加入GAMESERVER的玩家列表 */ public static void addPlayer(Player p) { playersByPlayerId.put(p.getPlayerId(), p); playersBySessionId.put(p.getSessionId(), p); } /** * 踢出GAMESERVER玩家列表 */ public static void removePlayer(Player p) { playersByPlayerId.remove(p.getPlayerId()); playersBySessionId.remove(p.getPlayerId()); }}// GameServer
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -