/* OrpheusMS: MapleStory Private Server based on OdinMS Copyright (C) 2012 Aaron Weiss <aaron@deviant-core.net> Patrick Huy <patrick.huy@frz.cc> Matthias Butz <matze@odinms.de> Jan Christian Meyer <vimes@odinms.de> This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package gm.server; import gm.GMPacketCreator; import gm.GMServerHandler; import gm.mina.GMCodecFactory; import java.net.InetSocketAddress; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import net.MaplePacket; import org.apache.mina.core.buffer.IoBuffer; import org.apache.mina.core.buffer.SimpleBufferAllocator; import org.apache.mina.core.filterchain.IoFilter; import org.apache.mina.core.service.IoAcceptor; import org.apache.mina.core.session.IdleStatus; import org.apache.mina.core.session.IoSession; import org.apache.mina.filter.codec.ProtocolCodecFilter; import org.apache.mina.transport.socket.SocketSessionConfig; import org.apache.mina.transport.socket.nio.NioSocketAcceptor; import tools.Output; /** * * @author kevintjuh93 */ public class GMServer { private IoAcceptor acceptor; private Map<String, IoSession> outGame;// LOL private Map<String, IoSession> inGame; private static GMServer instance; public final static String KEYWORD = "MOOPLEDEV"; public static GMServer getInstance() { if (instance == null) { instance = new GMServer(); } return instance; } public GMServer() { IoBuffer.setUseDirectBuffer(false); IoBuffer.setAllocator(new SimpleBufferAllocator()); acceptor = new NioSocketAcceptor(); acceptor.setHandler(new GMServerHandler()); acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 30); acceptor.getFilterChain().addLast("codec", (IoFilter) new ProtocolCodecFilter(new GMCodecFactory())); ((SocketSessionConfig) acceptor.getSessionConfig()).setTcpNoDelay(true); try { acceptor.bind(new InetSocketAddress(5252)); Output.print("GM Server: Listening on port 5252."); } catch (Exception e) { Output.print("Failed to bind the GM server to port 5252."); } outGame = new HashMap<String, IoSession>(); inGame = new HashMap<String, IoSession>(); } public void broadcastOutGame(MaplePacket packet, String exclude) { for (IoSession ss : outGame.values()) { if (!ss.getAttribute("NAME").equals(exclude)) { ss.write(packet); } } } public void broadcastInGame(MaplePacket packet) { for (IoSession ss : inGame.values()) { ss.write(packet); } } public void addInGame(String name, IoSession session) { if (!inGame.containsKey(name)) { broadcastOutGame(GMPacketCreator.chat(name + " has logged in."), null); broadcastOutGame(GMPacketCreator.addUser(name), null); } inGame.put(name, session);// replace old one (: } public void addOutGame(String name, IoSession session) { outGame.put(name, session); } public void removeInGame(String name) { if (inGame.remove(name) != null) { broadcastOutGame(GMPacketCreator.removeUser(name), null); broadcastOutGame(GMPacketCreator.chat(name + " has logged out."), null); } } public void removeOutGame(String name) { IoSession ss = outGame.remove(name); if (ss != null) { if (!ss.isClosing()) { broadcastOutGame(GMPacketCreator.removeUser(name), null); broadcastOutGame(GMPacketCreator.chat(name + " has logged out."), null); } } } public boolean contains(String name) { return inGame.containsKey(name) || outGame.containsKey(name); } public final void closeAllSessions() { try {// I CAN AND IT'S FREE BITCHES Collection<IoSession> sss = Collections.synchronizedCollection(outGame.values()); synchronized (sss) { final Iterator<IoSession> outIt = sss.iterator(); while (outIt.hasNext()) { outIt.next().close(true); outIt.remove(); } } } catch (Exception e) { e.printStackTrace(); } } public List<String> getUserList(String exclude) { List<String> returnList = new ArrayList<String>(outGame.keySet()); returnList.remove(exclude);// Already sent in LoginHandler (So you are // first on the list (: returnList.addAll(inGame.keySet()); return returnList; } public final void shutdown() {// nothing to save o.o try { closeAllSessions(); acceptor.unbind(); Output.print("GM Server is now offline."); } catch (Exception e) { e.printStackTrace(); } } }