package org.pokenet.chat.server; import java.util.HashMap; import java.util.Iterator; import org.apache.mina.core.service.IoHandlerAdapter; import org.apache.mina.core.session.IoSession; import org.pokenet.chat.server.User.Language; /** * Handles packets from clients * @author shadowkanji * */ public class ChatProtocolHandler extends IoHandlerAdapter { private static HashMap<Integer, ChatRoom> m_chatrooms; private int m_roomCount = 12; private LoginManager m_loginManager; private static HashMap<String, User> m_users; /* Amount of chatrooms server should be limited to (does not include private chats) */ private static int ROOMLIMIT = 10000; /** * Constructor */ public ChatProtocolHandler() { m_loginManager = new LoginManager(); new Thread(m_loginManager).start(); m_users = new HashMap<String, User>(); m_chatrooms = new HashMap<Integer, ChatRoom>(); /* * Create reserved chatrooms */ m_chatrooms.put(0, new ChatRoom("Developer Channel", 0, 7, Language.NONE)); m_chatrooms.put(1, new ChatRoom("Game Moderator Channel", 1, 1, Language.NONE)); m_chatrooms.put(2, new ChatRoom("Chat Moderator Channel", 2, 2, Language.NONE)); m_chatrooms.put(3, new ChatRoom("Server Administrator Channel", 3, 6, Language.NONE)); m_chatrooms.put(4, new ChatRoom("Game Chat", 4, 0, Language.ENGLISH)); m_chatrooms.put(5, new ChatRoom("Discussao do jogo", 5, 0, Language.PORTUGESE)); m_chatrooms.put(6, new ChatRoom("Gioco di Discussione", 6, 0, Language.ITALIAN)); m_chatrooms.put(7, new ChatRoom("Discussion sur le Jeu", 7, 0, Language.FRENCH)); m_chatrooms.put(8, new ChatRoom("Peli Keskustelu", 8, 0, Language.FINNISH)); m_chatrooms.put(9, new ChatRoom("Discusion del Juego", 9, 0, Language.SPANISH)); m_chatrooms.put(10, new ChatRoom("Spel Discussie", 10, 0, Language.DUTCH)); m_chatrooms.put(11, new ChatRoom("Spiel Diskussion", 11, 0, Language.GERMAN)); } /** * Called when client sends a message */ public void messageReceived(IoSession session, Object m) throws Exception { String message = (String) m; String [] details; System.out.println("ChatServ: " + m); if(session.getAttribute("user") == null) { /* Not logged in, only allow login */ System.out.println("User not logged in."); switch(message.charAt(0)) { case 'l': //Login - lLANGUAGEIDUSERNAME,PASSWORD System.out.println("ChatServ: Attempting to login..."); details = message.substring(2).split(","); m_loginManager.queueLogin(session, details[0], details[1], message.charAt(1)); break; } } else { User u = (User) session.getAttribute("user"); System.out.println("ChatServ: Responding..."); ChatRoom r = null; /* Logged in */ switch(message.charAt(0)) { case 'a': //Add a friend u.addFriend(MySqlManager.parseSQL(message.substring(1))); break; case 'r': //Remove a friend u.removeFriend(message.substring(1)); break; case 'm': //Make a new chatroom while(m_chatrooms.containsKey(m_roomCount) && m_roomCount > 0) { m_roomCount = m_roomCount == ROOMLIMIT ? 0 : m_roomCount + 1; } if(m_roomCount == 0) { //Room could not be created u.getSession().write("C"); return; } //Else, make room synchronized(m_chatrooms) { r = new ChatRoom(message.substring(1), m_roomCount, u.getLevel(), u.getLanguage()); r.addUser(u); } break; case 'j': //Join chatroom - jROOMNUMBER r = m_chatrooms.get(Integer.parseInt(message.substring(1))); if(r != null) { r.addUser(u); } break; case 'l': //Leave chatroom - lROOMNUMBER r = m_chatrooms.get(Integer.parseInt(message.substring(1))); if(r != null) { r.removeUser(u.getUsername()); } break; case 'p': //Private chat - pUSER,MESSAGE details = message.substring(1).split(","); synchronized(m_users) { m_users.get(details[0]).getSession().write("p" + u.getUsername() + "," + details[1]); } break; case 'c': //Normal Chat - cROOMID,MESSAGE details = message.substring(1).split(","); r = m_chatrooms.get(Integer.parseInt(details[0])); if(r != null) { r.queueMessage(u, details[1]); } else { //Chat room no longer exists u.getSession().write("E"); } break; case '!': //Announcement if(u.getLevel() >= 6) { synchronized(m_users) { Iterator<User> it = m_users.values().iterator(); while(it.hasNext()) { it.next().getSession().write("!" + message.substring(1)); } } } break; } } } /** * Called when session is closed */ public void sessionClosed(IoSession session) throws Exception { if(session.getAttribute("user") != null) { //Remove user from all chatrooms User u = (User) session.getAttribute("user"); //Inform friends that the player has logged off alertLogon(u, false); Iterator<ChatRoom> it = m_chatrooms.values().iterator(); while(it.hasNext()) { it.next().removeUser(u.getUsername()); } } } /** * Removes a chatroom * @param chatroom */ public static void removeChatRoom(int chatroom) { synchronized(m_chatrooms) { m_chatrooms.remove(chatroom); } } /** * Returns hashmap of users on the server * @return */ public static void addUser(User u) { synchronized(m_chatrooms) { /* Send chat rooms to user */ Iterator<Integer> it = m_chatrooms.keySet().iterator(); ChatRoom r = null; while(it.hasNext()) { int i = it.next(); r = m_chatrooms.get(i); if(r.isJoinable(u)) { u.getSession().write("R" + r.getId() + "," + r.getName()); } } } synchronized(m_users) { //Find all friends Iterator<String> it = u.getFriends().iterator(); String friends = "f"; while(it.hasNext()) { String s = it.next(); if(m_users.containsKey(s)) { friends = friends + s + ","; } } if(friends.endsWith(",")) { friends = friends.substring(0, friends.length() - 1); u.getSession().write(friends); } //Add user m_users.put(u.getUsername(), u); } } /** * Alerts a user's when the user logs on/off * @param u The user that logged on or off * @param connected True for log-on, False for log-off */ public static void alertLogon(User u, boolean connected){ //Check for online friends for (String s : u.getFriends()){ if (m_users.containsKey(s)){ //Send online friends a packet so clients can update if (connected) m_users.get(s).getSession().write("Fn" + u.getUsername()); else m_users.get(s).getSession().write("Ff" + u.getUsername()); } } } }