#include <QTranslator>
#include <QNetworkInterface>
#include "serverapp.h"
static QSize minimalGridSize(const QMap<QString, QPoint>& clientPositions, QSize& clientSize);
ServerApp::ServerApp(int& argc, char** argv)
: QApplication(argc, argv),
_mainWindow(nullptr),
_managerOnly(false),
_isExam(false)
{
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 == "") {
::exit(0);
return;
}
// System strings
QTranslator *qtTranslator = new QTranslator(this);
qtTranslator->load(QLocale::system(), "qt", "_", QLibraryInfo::location(QLibraryInfo::TranslationsPath));
installTranslator(qtTranslator);
// App specific
QTranslator *translator = new QTranslator(this);
translator->load(QLocale::system(), ":", "l_");
installTranslator(translator);
/* Set the global path of the settings */
QSettings::setPath(QSettings::IniFormat, QSettings::SystemScope, "/opt/");
QSharedPointer<QSettings> sys = getSettings();
qDebug() << "System settings are in:" << sys->fileName();
_mainWindow = new MainWindow();
}
QStringList ServerApp::parseParameters()
{
QStringList rest;
for (QString a : QApplication::arguments()) {
if (a == "--manager-only") {
_managerOnly = true;
break;
} else if (a.startsWith("--config=")) {
_iniPath = a.mid(9);
} else {
rest << a;
}
}
return rest;
}
QStringList ServerApp::arguments()
{
return _arguments;
}
void ServerApp::loadRooms()
{
QSharedPointer<QSettings> conf = getSettings();
if (!conf->contains("rooms")) { qDebug() << "Invalid config file (no rooms are set)!"; return; }
QStringList rooms = conf->value("rooms").toStringList();
for (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 == "") {
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 != QHostAddress(QHostAddress::LocalHost) && mgrIP == address.toString()) {
qDebug("Found this 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()
{
if (_rooms.contains(_currentRoom)) {
return _rooms[_currentRoom];
} else {
static Room* defaultRoom = nullptr;
if (defaultRoom == nullptr) {
defaultRoom = new Room(QMap<QString,
QPoint>(), QSize(8, 6), QSize(1, 1), "", "");
}
return defaultRoom;
}
}
void ServerApp::setSessionName(const QString& name)
{
_sessionName = name;
_sessionNameArray = name.toUtf8();
}
void ServerApp::setSessionName()
{
const QString name = QString::number(qrand() % 9000 + 1000);
_sessionName = name;
_sessionNameArray = name.toUtf8();
}
QSharedPointer<QSettings> ServerApp::getSettings()
{
QSharedPointer<QSettings> set;
if (_iniPath == "") {
/* default location (system scope) */
set = QSharedPointer<QSettings>(new QSettings(QSettings::IniFormat, QSettings::SystemScope, "openslx/pvs2", "pvs2"));
} else {
/* use _iniPath to find ini file */
set = QSharedPointer<QSettings>(new QSettings(_iniPath, QSettings::IniFormat));
}
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 (auto it = clientPositions.begin(); it != clientPositions.end(); ++it) {
QPoint pos = it.value();
if (pos.x() > x) { x = pos.x(); }
if (pos.y() > y) { y = pos.y(); }
}
/* need a little extra space */
QSize size(x + clientSize.width(), y + clientSize.height());
return size;
}