#include "server.h" #include #include #include #include #include #include #include #include #include #include #include namespace Yc { namespace Lib { Server::Server(Yc::Lib::Config *config) : _config(config), _stop(false) { struct sockaddr_in serverAddr; int opt = true; _socket = socket(AF_INET, SOCK_STREAM, 0); setsockopt(_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)); int flags = 1; setsockopt(_socket, IPPROTO_TCP, TCP_NODELAY, (void *)&flags, sizeof(flags)); serverAddr.sin_family = AF_INET; serverAddr.sin_addr.s_addr = INADDR_ANY; serverAddr.sin_port = htons(1235); if (bind(_socket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0) { std::cout << "bind not possible" << std::endl; exit(-1); } createRooms(config->group("rooms")); } void Server::run() { if (listen(_socket, 5) < 0) { std::cout << "listen not possible" << std::endl; exit(-1); } timeval origTv; origTv.tv_sec = 5; origTv.tv_usec = 0; int _maxSd = _socket; while (!_stop) { timeval tv(origTv); fd_set fd; FD_ZERO(&fd); FD_SET(_socket, &fd); if (select(_maxSd + 1, &fd, NULL, NULL, &tv) > 0) { std::async(std::launch::async, &Server::handleRequest, this); } } } std::vector Server::roomList() { std::vector list; for (auto &room: _rooms) { list.push_back(room->name()); } return list; } Json::Value Server::jsonRoomList() { Json::Value list; for (auto &room: _rooms) { list.append(room->name()); } return list; } bool Server::roomAllowed(std::string roomName, std::string userName, std::string password){ for (auto &room: _rooms) { if (room->name() == roomName && room->accessAllowed(userName, password)) { return true; } } return false; } void Server::createRooms(Json::Value roomList) { for (auto &room: roomList) { Room *newRoom = new Room(this, room); _rooms.push_back(newRoom); } } void Server::handleRequest() { struct sockaddr_in sockAddr; socklen_t sockAddrLen = sizeof(sockAddr); int userSock = accept(_socket, (struct sockaddr *)&sockAddr, &sockAddrLen); if (userSock < 0) { return; } int flags = 1; setsockopt(userSock, IPPROTO_TCP, TCP_NODELAY, (void *)&flags, sizeof(flags)); std::string msg = readSocket(userSock); if (msg == "") { return; } inputSwitcher(userSock, msg); } void Server::inputSwitcher(int userSocket, std::string input) { Json::Value inputTree = getJsonTree(input); if (inputTree["type"] == "init") { initUser(userSocket, inputTree); } } bool Server::userExists(std::string userName) { for (auto &room: _rooms) { if (room->userNameExists(userName)) { return true; } } return false; } void Server::initUser(int userSocket, Json::Value data) { if (userExists(data["name"].asString())) { Json::Value errorJson; errorJson["type"] = User::error; errorJson["message"] = "loggedin"; send(userSocket, errorJson); close(userSocket); return; } std::string room = data["room"].asString(); bool added(false); for (auto &room: _rooms) { if (room->name() == data["room"].asString()) { if (room->addUser(data["name"].asString(), data["color"].asString(), data["password"].asString(), userSocket)) { added = true; break; } } } if (!added) { close(userSocket); } } } // namespace Lib } // namespace Yp