summaryrefslogblamecommitdiffstats
path: root/src/server/serverapp/serverapp.cpp
blob: c91ed15f59c52215e5a517d5b87e8132d066496b (plain) (tree)
1
2
3
4
5
6
7
8
9



                                     
                      
                            

                       
 

                                                                                              
                                            
                                  






                                             



                                                                        

                                                     


                       
                         
                                                   




                                                                                                                           
                       
                                                 




                                                              


                                                                                  
                                       
                                                                 
 
                         




                                        

                                                            
                                            
                              
                                                                       













                                            

                           
                                        
 



                                                                      

                                                                
                                             



                                                                                             
                                         





























                                                                                                                     

                                                                                                                                       
















                                                                                                    
                                             
 





                                                    
                                                                                                              
         
                           








                                                   
                                                                      



                                          
                                    
 

                                 
                                                     
                                                                                                                

                                                   
                                                                          




                                  








                                                                                             






                                                 

                                       
                                                                      

 
#include "../mainwindow/mainwindow.h"
#include "serverapp.h"
#include "../../shared/util.h"

#include <QTranslator>
#include <QNetworkInterface>
#include <QSettings>
#include <QLibraryInfo>

static QSize minimalGridSize(const QMap<QString, QPoint>& clientPositions, QSize& clientSize);

ServerApp::ServerApp(int& argc, char** argv)
	: QApplication(argc, argv)
{
	setOrganizationName("openslx");
	setOrganizationDomain("openslx.org");
	setApplicationName("pvsmgr");

	_arguments = parseParameters();

	loadRooms();

	// If started in manager-only mode, and there is no current room
	// after reading the config, exit right away
	if (_managerOnly && _currentRoom.isEmpty()) {
		_doExit = true;
		return;
	}

	// System strings
	auto *qtTranslator = new QTranslator(this);
	if (!qtTranslator->load(QLocale::system(), "qt", "_", QLibraryInfo::location(QLibraryInfo::TranslationsPath))) {
		qDebug() << "Loading system translations failed" << QLibraryInfo::location(QLibraryInfo::TranslationsPath);
	} else {
		installTranslator(qtTranslator);
	}
	// App specific
	auto *translator = new QTranslator(this);
	if (!translator->load(QLocale::system(), ":", "l_")) {
		qDebug() << "Loading app translations failed";
	} else {
		installTranslator(translator);
	}

	/* Set the global path of the settings */
	QSettings::setPath(QSettings::IniFormat, QSettings::SystemScope, "/opt/");
	QSettings* sys = getSettings();
	qDebug() << "System settings are in:" << sys->fileName();

	new MainWindow();
}

QStringList ServerApp::parseParameters()
{
	QStringList rest;
	for (const QString& a : QApplication::arguments()) {
		if (a == QStringLiteral("--manager-only")) {
			_managerOnly = true;
			break;
		} else if (a.startsWith(QStringLiteral("--config="))) {
			_iniPath = a.mid(9);
		} else {
			rest << a;
		}
	}
	return rest;

}

QStringList ServerApp::arguments()
{
	return _arguments;
}

void ServerApp::loadRooms()
{
	QSettings* conf = getSettings();

	if (!conf->contains(QStringLiteral("rooms"))) {
		qDebug() << "Invalid config file (no rooms are set)!";
		return;
	}
	QStringList rooms = conf->value("rooms").toStringList();

	for (const QString& roomId : rooms) {
		conf->beginGroup(roomId);
		QString roomName = conf->value("name").toString();

		/* fallback to the old format where the room id was actually just the name */
		if (roomName.isEmpty()) {
			roomName = roomId;
		}
		if (!conf->contains("mgrIP")) {
			qDebug() << "Warning: Incomplete config file (room " << roomName << " needs a mgrIP)!";
		}
		QMap<QString, QPoint> clientPositions;
		// First store all room configurations in _rooms.
		int size = conf->beginReadArray("client");
		for (int j = 0; j < size; j++) {
			conf->setArrayIndex(j);
			clientPositions.insert(conf->value("ip").toString(), conf->value("pos").toPoint());
		}
		conf->endArray();

		/* read backgroundImage */
		QString image   = conf->contains("backgroundImage") ? conf->value("backgroundImage").toString() : "";
		QString mgrIP   = conf->value("mgrIP").toString();
		QString tutorIP = conf->value("tutorIP").toString();

		QSize gridSize;
		QSize clientSize(1, 1);
		/* read some other properties of the room */
		if (conf->contains("gridSize")) {
			gridSize = conf->value("gridSize").toSize();
		}
		if (conf->contains("clientSize")) {
			clientSize = conf->value("clientSize").toSize();
		}

		foreach (const QHostAddress & address, QNetworkInterface::allAddresses()) {
			if (!address.isBroadcast() && !address.isLoopback() && !address.isMulticast() && mgrIP == address.toString()) {
				qDebug() << "Found own ip in config.";
				_currentRoom = roomName;
			}
		}
		conf->endGroup();

		if (!gridSize.isValid()) {
			/* ok, let's choose the minimum gridSize to fit all clients */
			gridSize = minimalGridSize(clientPositions, clientSize);
			qDebug() << "had to use minimalGridSize(): = " << gridSize;

		}
		Room* r = new Room(clientPositions, gridSize, clientSize, image, tutorIP);
		qDebug() << "read new room: " << roomName << ": " << gridSize << ", " << clientSize;
		_rooms.insert(roomName, r);
	}
}

const Room* ServerApp::getCurrentRoom() const
{
	auto *room = _rooms.value(_currentRoom);
	if (room != nullptr)
		return room;
	static Room* defaultRoom = nullptr;
	if (defaultRoom == nullptr) {
		defaultRoom = new Room(QMap<QString,
							   QPoint>(), QSize(8, 6), QSize(1, 1), "", "<none>");
	}
	return defaultRoom;
}
void ServerApp::setSessionName(const QString& name)
{
	_sessionName = name;
	_sessionNameArray = name.toUtf8();
}

void ServerApp::setSessionName()
{
	const QString name = QString::number(slxrand() % 9000 + 1000);
	_sessionName = name;
	_sessionNameArray = name.toUtf8();
}

QSettings * ServerApp::getSettings()
{
	QSettings *set;
	if (_iniPath.isEmpty()) {
		/* default location (system scope) */
		set = new QSettings(QSettings::IniFormat, QSettings::SystemScope, "openslx/pvs2", "pvs2", this);
	} else {
		/* use _iniPath to find ini file */
		set = new QSettings(_iniPath, QSettings::IniFormat, this);
	}
	set->setIniCodec("UTF-8");
	return set;
}

/**
  * returns the minimal grid size such that all clients fit on the grid
  **/
static QSize minimalGridSize(const QMap<QString, QPoint>& clientPositions, QSize& clientSize)
{
	/* collect the maximum coordinates */
	int x = 0;
	int y = 0;

	for (const auto &pos : clientPositions) {
		if (pos.x() > x) {
			x = pos.x();
		}
		if (pos.y() > y) {
			y = pos.y();
		}
	}
	/* need a little extra space */
	return QSize(x + clientSize.width(), y + clientSize.height());
}