void TabSupervisor::retranslateUi()
{
    QList<Tab *> tabs;
    tabs.append(tabServer);
    tabs.append(tabReplays);
    tabs.append(tabDeckStorage);
    tabs.append(tabAdmin);
    tabs.append(tabUserLists);
    tabs.append(tabLog);
    QMapIterator<int, TabRoom *> roomIterator(roomTabs);
    while (roomIterator.hasNext())
        tabs.append(roomIterator.next().value());
    QMapIterator<int, TabGame *> gameIterator(gameTabs);
    while (gameIterator.hasNext())
        tabs.append(gameIterator.next().value());
    QListIterator<TabGame *> replayIterator(replayTabs);
    while (replayIterator.hasNext())
        tabs.append(replayIterator.next());
    QListIterator<TabDeckEditor *> deckEditorIterator(deckEditorTabs);
    while (deckEditorIterator.hasNext())
        tabs.append(deckEditorIterator.next());
    QMapIterator<QString, TabMessage *> messageIterator(messageTabs);
    while (messageIterator.hasNext())
        tabs.append(messageIterator.next().value());
    
    for (int i = 0; i < tabs.size(); ++i)
        if (tabs[i]) {
            int idx = indexOf(tabs[i]);
            QString tabText = tabs[i]->getTabText();
            setTabText(idx, sanitizeTabName(tabText));
            setTabToolTip(idx, sanitizeHtml(tabText));
            tabs[i]->retranslateUi();
        }
}
Response::ResponseCode Server_ProtocolHandler::cmdGetGamesOfUser(const Command_GetGamesOfUser &cmd, ResponseContainer &rc)
{
	if (authState == NotLoggedIn)
		return Response::RespLoginNeeded;
	
	// We don't need to check whether the user is logged in; persistent games should also work.
	// The client needs to deal with an empty result list.
	
	Response_GetGamesOfUser *re = new Response_GetGamesOfUser;
	server->roomsLock.lockForRead();
	QMapIterator<int, Server_Room *> roomIterator(server->getRooms());
	while (roomIterator.hasNext()) {
		Server_Room *room = roomIterator.next().value();
		room->gamesLock.lockForRead();
		room->getInfo(*re->add_room_list(), false, true);
		QListIterator<ServerInfo_Game> gameIterator(room->getGamesOfUser(QString::fromStdString(cmd.user_name())));
		while (gameIterator.hasNext())
			re->add_game_list()->CopyFrom(gameIterator.next());
		room->gamesLock.unlock();
	}
	server->roomsLock.unlock();
	
	rc.setResponseExtension(re);
	return Response::RespOk;
}
IslInterface::~IslInterface()
{
	logger->logMessage("[ISL] session ended", this);
	
	flushOutputBuffer();
	
	// As these signals are connected with Qt::QueuedConnection implicitly,
	// we don't need to worry about them modifying the lists while we're iterating.
	
	server->roomsLock.lockForRead();
	QMapIterator<int, Server_Room *> roomIterator(server->getRooms());
	while (roomIterator.hasNext()) {
		Server_Room *room = roomIterator.next().value();
		room->usersLock.lockForRead();
		QMapIterator<QString, ServerInfo_User_Container> roomUsers(room->getExternalUsers());
		while (roomUsers.hasNext()) {
			roomUsers.next();
			if (roomUsers.value().getUserInfo()->server_id() == serverId)
				emit externalRoomUserLeft(room->getId(), roomUsers.key());
		}
		room->usersLock.unlock();
	}
	server->roomsLock.unlock();
	
	server->clientsLock.lockForRead();
	QMapIterator<QString, Server_AbstractUserInterface *> extUsers(server->getExternalUsers());
	while (extUsers.hasNext()) {
		extUsers.next();
		if (extUsers.value()->getUserInfo()->server_id() == serverId)
			emit externalUserLeft(extUsers.key());
	}
	server->clientsLock.unlock();
}
Exemple #4
0
void Server::prepareDestroy()
{
    roomsLock.lockForWrite();
    QMapIterator<int, Server_Room *> roomIterator(rooms);
    while (roomIterator.hasNext())
        delete roomIterator.next().value();
    rooms.clear();
    roomsLock.unlock();
}
Exemple #5
0
int Server::getGamesCount() const
{
    int result = 0;
    QReadLocker locker(&roomsLock);
    QMapIterator<int, Server_Room *> roomIterator(rooms);
    while (roomIterator.hasNext()) {
        Server_Room *room = roomIterator.next().value();
        QReadLocker roomLocker(&room->gamesLock);
        result += room->getGames().size();
    }
    return result;
}
Response::ResponseCode Server_ProtocolHandler::cmdListRooms(const Command_ListRooms & /*cmd*/, ResponseContainer &rc)
{
	if (authState == NotLoggedIn)
		return Response::RespLoginNeeded;
	
	Event_ListRooms event;
	QMapIterator<int, Server_Room *> roomIterator(server->getRooms());
	while (roomIterator.hasNext())
		roomIterator.next().value()->getInfo(*event.add_room_list(), false);
	rc.enqueuePreResponseItem(ServerMessage::SESSION_EVENT, prepareSessionEvent(event));
	
	acceptsRoomListChanges = true;
	return Response::RespOk;
}
ResponseCode Server_ProtocolHandler::cmdListRooms(Command_ListRooms * /*cmd*/, CommandContainer *cont)
{
	if (authState == PasswordWrong)
		return RespLoginNeeded;
	
	QList<ServerInfo_Room *> eventRoomList;
	QMapIterator<int, Server_Room *> roomIterator(server->getRooms());
	while (roomIterator.hasNext())
		eventRoomList.append(roomIterator.next().value()->getInfo(false));
	cont->enqueueItem(new Event_ListRooms(eventRoomList));
	
	acceptsRoomListChanges = true;
	return RespOk;
}
// This function must only be called from the thread this object lives in.
// The thread must not hold any server locks when calling this (e.g. clientsLock, roomsLock).
void Server_ProtocolHandler::prepareDestroy()
{
	if (deleted)
		return;
	deleted = true;
	
	QMapIterator<int, Server_Room *> roomIterator(rooms);
	while (roomIterator.hasNext())
		roomIterator.next().value()->removeClient(this);
	
	QMap<int, QPair<int, int> > tempGames(getGames());
	
	server->roomsLock.lockForRead();
	QMapIterator<int, QPair<int, int> > gameIterator(tempGames);
	while (gameIterator.hasNext()) {
		gameIterator.next();
		
		Server_Room *r = server->getRooms().value(gameIterator.value().first);
		if (!r)
			continue;
		r->gamesLock.lockForRead();
		Server_Game *g = r->getGames().value(gameIterator.key());
		if (!g) {
			r->gamesLock.unlock();
			continue;
		}
		g->gameMutex.lock();
		Server_Player *p = g->getPlayers().value(gameIterator.value().second);
		if (!p) {
			g->gameMutex.unlock();
			r->gamesLock.unlock();
			continue;
		}
		
		p->disconnectClient();
		
		g->gameMutex.unlock();
		r->gamesLock.unlock();
	}
	server->roomsLock.unlock();
	
	server->removeClient(this);
	
	deleteLater();
}
Exemple #9
0
void Server::prepareDestroy()
{
    // dirty :(
    if (threaded) {
        clientsLock.lockForRead();
        for (int i = 0; i < clients.size(); ++i)
            QMetaObject::invokeMethod(clients.at(i), "prepareDestroy", Qt::QueuedConnection);
        clientsLock.unlock();

        bool done = false;

        class SleeperThread : public QThread
        {
        public:
            static void msleep(unsigned long msecs) { QThread::usleep(msecs); }
        };

        do {
            SleeperThread::msleep(10);
            clientsLock.lockForRead();
            if (clients.isEmpty())
                done = true;
            clientsLock.unlock();
        } while (!done);
    } else {
        // no locking is needed in unthreaded mode
        while (!clients.isEmpty())
            clients.first()->prepareDestroy();
    }

    roomsLock.lockForWrite();
    QMapIterator<int, Server_Room *> roomIterator(rooms);
    while (roomIterator.hasNext())
        delete roomIterator.next().value();
    rooms.clear();
    roomsLock.unlock();
}
Server_ProtocolHandler::~Server_ProtocolHandler()
{
	// The socket has to be removed from the server's list before it is removed from the game's list
	// so it will not receive the game update event.
	server->removeClient(this);

	QMapIterator<int, Server_Room *> roomIterator(rooms);
	while (roomIterator.hasNext())
		roomIterator.next().value()->removeClient(this);
	
	QMapIterator<int, QPair<Server_Game *, Server_Player *> > gameIterator(games);
	while (gameIterator.hasNext()) {
		gameIterator.next();
		Server_Game *g = gameIterator.value().first;
		Server_Player *p = gameIterator.value().second;
		
		if (authState == UnknownUser)
			g->removePlayer(p);
		else
			p->setProtocolHandler(0);
	}

	delete userInfo;
}
void IslInterface::initServer()
{
	socket->setSocketDescriptor(socketDescriptor);
	
	logger->logMessage(QString("[ISL] incoming connection: %1").arg(socket->peerAddress().toString()));
	
	QList<ServerProperties> serverList = server->getServerList();
	int listIndex = -1;
	for (int i = 0; i < serverList.size(); ++i)
		if (serverList[i].address == socket->peerAddress()) {
			listIndex = i;
			break;
		}
	if (listIndex == -1) {
		logger->logMessage(QString("[ISL] address %1 unknown, terminating connection").arg(socket->peerAddress().toString()));
		deleteLater();
		return;
	}
	
	socket->startServerEncryption();
	if (!socket->waitForEncrypted(5000)) {
		QList<QSslError> sslErrors(socket->sslErrors());
		if (sslErrors.isEmpty())
			qDebug() << "[ISL] SSL handshake timeout, terminating connection";
		else
			qDebug() << "[ISL] SSL errors:" << sslErrors;
		deleteLater();
		return;
	}
	
	if (serverList[listIndex].cert == socket->peerCertificate())
		logger->logMessage(QString("[ISL] Peer authenticated as " + serverList[listIndex].hostname));
	else {
		logger->logMessage(QString("[ISL] Authentication failed, terminating connection"));
		deleteLater();
		return;
	}
	serverId = serverList[listIndex].id;
	
	Event_ServerCompleteList event;
	event.set_server_id(server->getServerId());
	
	server->clientsLock.lockForRead();
	QMapIterator<QString, Server_ProtocolHandler *> userIterator(server->getUsers());
	while (userIterator.hasNext())
		event.add_user_list()->CopyFrom(userIterator.next().value()->copyUserInfo(true, true));
	server->clientsLock.unlock();
	
	server->roomsLock.lockForRead();
	QMapIterator<int, Server_Room *> roomIterator(server->getRooms());
	while (roomIterator.hasNext()) {
		Server_Room *room = roomIterator.next().value();
		room->usersLock.lockForRead();
		room->gamesLock.lockForRead();
		room->getInfo(*event.add_room_list(), true, true, false, false);
	}
	
	IslMessage message;
	message.set_message_type(IslMessage::SESSION_EVENT);
	SessionEvent *sessionEvent = message.mutable_session_event();
	sessionEvent->GetReflection()->MutableMessage(sessionEvent, event.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(event);
	
	server->islLock.lockForWrite();
	if (server->islConnectionExists(serverId)) {
		qDebug() << "[ISL] Duplicate connection to #" << serverId << "terminating connection";
		deleteLater();
	} else {
		transmitMessage(message);
		server->addIslInterface(serverId, this);
	}
	server->islLock.unlock();
	
	roomIterator.toFront();
	while (roomIterator.hasNext()) {
		roomIterator.next();
		roomIterator.value()->gamesLock.unlock();
		roomIterator.value()->usersLock.unlock();
	}
	server->roomsLock.unlock();
}