package jnet.server; import io.netty.channel.Channel; import io.netty.channel.group.ChannelGroup; import io.netty.channel.group.DefaultChannelGroup; import io.netty.util.concurrent.GlobalEventExecutor; import java.net.InetSocketAddress; import java.util.ListIterator; import jnet.lib.LogFile; import jnet.lib.Message; import jnet.lib.PasswordHashing; import jnet.lib.object.Event; import jnet.lib.object.Map; import jnet.lib.object.MapObject; import jnet.lib.object.ObjectType; import jnet.lib.object.OnlineClients; import jnet.lib.object.ServerConfig; import jnet.lib.object.SnmpProfile; import jnet.lib.object.User; public class ServerMessageParser { private final Channel currentClient; private static final ChannelGroup channels = new DefaultChannelGroup( "containers", GlobalEventExecutor.INSTANCE); public ServerMessageParser(Channel currentClient) { this.currentClient = currentClient; } public void parse(Message msg) { LogFile.printDebug("-> Message type: " + msg.getType()); ListIterator iteratorMap = Server.maps.listIterator(); ListIterator iteratorMapObject = Server.mapObject.listIterator(); switch (msg.getType()) { case Message.CLIENT_VERSION: int client_version = (int) msg.getMsg(); if (client_version < Server.MINIMAL_CLIENT_VERSION) { LogFile.printInfo("Outdated client. Sent update request (" + ((InetSocketAddress) currentClient.remoteAddress()).getHostName() + ")"); send(new Message(Message.UPDATE, null)); } else { LogFile.printInfo("Authorization request send (" + ((InetSocketAddress) currentClient.remoteAddress()).getHostName() + ")"); // oodeslat pozadavek na autorizacni udaje send(new Message(Message.AUTH_REQUEST, null)); } break; case Message.AUTH: String[] userData = (String[]) msg.getMsg(); String username = userData[0]; String password = userData[1]; int platform = Integer.parseInt(userData[2]); User u = Database.getUserInfo(username); if (PasswordHashing.verify(password, u.getPassword())) { LogFile.printInfo("User: " + username + " logged in (" + ((InetSocketAddress) currentClient.remoteAddress()).getAddress().getHostName() + ")"); // odeslat informaci uzivateli o jeho uspesnem prihlaseni send(new Message(Message.AUTH_SUCEFULL, null)); // pridani uzivatele mezi pripojene kanaly channels.add(currentClient); // vložit uživatele na seznam online uživatelů InetSocketAddress socketAddress = (InetSocketAddress) currentClient.remoteAddress(); String clientIp = socketAddress.getAddress().getHostAddress(); String clientPort = String.valueOf(socketAddress.getPort()); Server.onlineClients.add(new OnlineClients( String.valueOf(u.getId()), u.getUsername(), clientIp, clientPort, platform)); // odeslat informace o prihlasenem uzivateli, opravneni atd send(new Message(Message.USER_INFO, u)); // odeslat vsem nový seznam pripojenych klientu sendAll(new Message(Message.ONLINE_CLIENTS, Server.onlineClients)); // odeslat nastaveni serveru ServerConfig sc = new ServerConfig( Server.config.getInt("ping_attempt"), Server.config.getInt("ping_timeout"), Server.config.getInt("instability_attempt"), Server.config.getInt("instability_limit")); send(new Message(Message.SERVER_CONFIG, sc)); // odeslat typy objektu for (ObjectType ot : Server.objectType) { send(new Message(Message.OBJECT_TYPE, ot)); } // odesila seznam uzivatelu for (User us : Server.users) { send(new Message(Message.USER, us)); } // odeslat seznam map for (Map i : Server.maps) { send(new Message(Message.MAP, i)); } // odeslat seznam objektu send(Message.OBJECT_LIST, Server.mapObject); // odeslat seznam udalosti send(new Message(Message.EVENT_LIST, Server.events)); // odeslat seznam snmp profilů for (SnmpProfile i : Server.snmpProfile) { send(new Message(Message.SNMP_PROFILE, i)); } } else { LogFile.printInfo("Authorization failed (ser: " + username + " )"); } break; case Message.NEW_OBJECT_TYPE: ObjectType not = (ObjectType) msg.getMsg(); int id = Database.addObjectType(not); not.setId(id); Server.objectType.add(not); sendAll(new Message(Message.OBJECT_TYPE, not)); break; case Message.SET_MAP_LOCK: int[] data_lock = (int[]) msg.getMsg(); while (iteratorMap.hasNext()) { Map map = iteratorMap.next(); if (map.getId() == data_lock[0]) { map.setLock((data_lock[1] == 1)); break; } } // upravit informaci v databazi Database.mapLock(data_lock[1], data_lock[0]); // odeslani informace ostatnim sendAll(new Message(Message.SET_MAP_LOCK, data_lock)); break; case Message.ADD_OBJECT: MapObject mo = Database.addMapObject((MapObject) msg.getMsg()); // pridat do seznamu iteratorMapObject.add(mo); // odesle všem novy objekt sendAll(new Message(Message.ADD_OBJECT, mo)); // prida event a odesle ho Event event = Database.addEvent(mo.getId(), "Přidáno", Event.TYPE_INFO); sendAll(new Message(Message.EVENT_NEW, event)); // pokud je object vypnuty prida log if (!mo.isActive()) { Event event_disable = Database.addEvent(mo.getId(), "Ping vypnut", Event.TYPE_PING_OFF); sendAll(new Message(Message.EVENT_NEW, event_disable)); } break; case Message.REMOVE_OBJECT: while (iteratorMapObject.hasNext()) { MapObject obj = iteratorMapObject.next(); if (obj.getId() == (int) msg.getMsg()) { // odebere z databaze Database.removeObject(obj.getId()); // odesle informaci o odebrani objektu klientum sendAll(new Message(Message.REMOVE_OBJECT, obj.getId())); // odebere ze seznamu iteratorMapObject.remove(); break; } } break; case Message.MAP_REMOVE: while (iteratorMap.hasNext()) { Map map = iteratorMap.next(); if (map.getId() == (int) msg.getMsg()) { // odebere z databaze Database.removeMap(map.getId()); // odesle informaci o odebrani objektu klientum sendAll(new Message(Message.MAP_REMOVE, map.getId())); // odebere ze seznamu iteratorMap.remove(); break; } } break; case Message.MAP_ADD: Map map = new Map((String) msg.getMsg()); // přidání mapy do databaze map.setId(Database.addMap(map.getName())); //odeslání mapy klientum send(new Message(Message.MAP, map)); // pridani mapy do seznamu iteratorMap.add(map); break; case Message.OBJECT_MOVE: int[] data = (int[]) msg.getMsg(); // 0 = obj id // 2 = x // 2 = y // zmenit v databázi Database.objectMove(data[0], data[1], data[2]); // zmenit v seznamu while (iteratorMapObject.hasNext()) { MapObject obj = iteratorMapObject.next(); if (obj.getId() == data[0]) { // zmenit pozici obj.setX(data[1]); obj.setY(data[2]); // zapsat zmenu do databaze Database.objectMove(data[0], data[1], data[2]); // preposlat zmenu klientum sendAll(new Message(Message.UPDATE_OBJECT, obj)); break; } } break; case Message.UPDATE_OBJECT: MapObject mo_u = (MapObject) msg.getMsg(); // zmenit v databazi Database.updateObject(mo_u); // zmenit v seznamu while (iteratorMapObject.hasNext()) { if (iteratorMapObject.next().getId() == mo_u.getId()) { iteratorMapObject.set(mo_u); break; } } // preposlat zmenu klientum sendAll(new Message(Message.UPDATE_OBJECT, mo_u)); break; case Message.DELETE_LOG: int objId = (int) msg.getMsg(); // vymaže logy v databazi Database.deleteObjectLog(objId); // vymaze logy v listu ListIterator iterator = Server.events.listIterator(); while (iterator.hasNext()) { if (iterator.next().getObject() == objId) { iterator.remove(); break; } } sendAll(new Message(Message.DELETE_LOG, objId)); break; case Message.USER: User user = (User) msg.getMsg(); user.setPassword(PasswordHashing.hash(user.getPassword())); //pridáni do databáze a nastaveni id user.setId(Database.addUser(user)); // přidání do seznamu Server.users.add(user); // odeslat klientum nového uživatele send(new Message(Message.USER, user)); break; case Message.USER_EDIT: User ue = (User) msg.getMsg(); // upraveni v databázi Database.editUser(ue); // zmenit v seznamu ListIterator iteratorUser = Server.users.listIterator(); while (iteratorUser.hasNext()) { User next = iteratorUser.next(); if (next.getId() == ue.getId()) { iteratorUser.set(ue); break; } } // preposlat zmenu klientum sendAll(new Message(Message.USER_EDIT, ue)); break; case Message.SERVER_CONFIG: ServerConfig sc = (ServerConfig) msg.getMsg(); // ulozeni Server.config.setInt("ping_attempt", sc.getPingAttempt()); Server.config.setInt("ping_timeout", sc.getPingTimeout()); Server.config.setInt("instability_attempt", sc.getInstabilityAttempt()); Server.config.setInt("instability_limit", sc.getInstabilityLimit()); Server.config.save(); //odeslani vsem sendAll(Message.SERVER_CONFIG, sc); break; default: LogFile.printErr("Neznamy typ zpravy"); } } public void send(Message message) { currentClient.writeAndFlush(message); LogFile.printDebug("<- Message type: " + message.getType()); } public void send(int type, Object obj) { currentClient.writeAndFlush(new Message(type, obj)); LogFile.printDebug("<- Message type: " + type); } public static void sendAll(Message message) { if (channels.isEmpty()) { return; } channels.writeAndFlush(message); LogFile.printDebug("<- For all. Message type: " + message.getType()); } public static void sendAll(int type, Object obj) { if (channels.isEmpty()) { return; } channels.writeAndFlush(new Message(type, obj)); LogFile.printDebug("<- For all. Message type: " + type); } public static final void removeClient(Channel ch) { // odebrani z připojenych kanalu channels.remove(ch); // odebrani ze seznamu klientu InetSocketAddress socketAddress = (InetSocketAddress) ch.remoteAddress(); String clientIp = socketAddress.getAddress().getHostAddress(); String clientPort = String.valueOf(socketAddress.getPort()); for (OnlineClients oc : Server.onlineClients) { if (oc.getIp().equals(clientIp) && oc.getPort().equals(clientPort)) { Server.onlineClients.remove(oc); System.err.println("Client removed"); break; } } // odeslat vsem novy seznam klientu sendAll(new Message(Message.ONLINE_CLIENTS, Server.onlineClients)); } }