void MainSettingsDialog::fillAllAutoProfilesTable() { for (int i = ui->autoProfileTableWidget->rowCount()-1; i >= 0; i--) { ui->autoProfileTableWidget->removeRow(i); } //QStringList tableHeader; //tableHeader << tr("Active") << tr("GUID") << tr("Profile") << tr("Application") << tr("Default?") // << tr("Instance"); //ui->autoProfileTableWidget->setHorizontalHeaderLabels(tableHeader); ui->autoProfileTableWidget->horizontalHeader()->setVisible(true); #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) ui->autoProfileTableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); #else ui->autoProfileTableWidget->horizontalHeader()->setResizeMode(QHeaderView::Stretch); #endif ui->autoProfileTableWidget->hideColumn(5); int i = 0; AutoProfileInfo *info = allDefaultProfile; ui->autoProfileTableWidget->insertRow(i); QTableWidgetItem *item = new QTableWidgetItem(); item->setCheckState(info->isActive() ? Qt::Checked : Qt::Unchecked); ui->autoProfileTableWidget->setItem(i, 0, item); QString deviceName = info->getDeviceName(); QString guidDisplay = info->getGUID(); if (!deviceName.isEmpty()) { guidDisplay = QString("%1 ").arg(info->getDeviceName()); guidDisplay.append(QString("(%1)").arg(info->getGUID())); } item = new QTableWidgetItem(guidDisplay); item->setFlags(item->flags() & ~Qt::ItemIsEditable); item->setData(Qt::UserRole, info->getGUID()); item->setToolTip(info->getGUID()); ui->autoProfileTableWidget->setItem(i, 1, item); QFileInfo profilePath(info->getProfileLocation()); item = new QTableWidgetItem(profilePath.fileName()); item->setFlags(item->flags() & ~Qt::ItemIsEditable); item->setData(Qt::UserRole, info->getProfileLocation()); item->setToolTip(info->getProfileLocation()); ui->autoProfileTableWidget->setItem(i, 2, item); QFileInfo exeInfo(info->getExe()); item = new QTableWidgetItem(exeInfo.fileName()); item->setFlags(item->flags() & ~Qt::ItemIsEditable); item->setData(Qt::UserRole, info->getExe()); item->setToolTip(info->getExe()); ui->autoProfileTableWidget->setItem(i, 3, item); item = new QTableWidgetItem("Default"); item->setData(Qt::UserRole, "default"); ui->autoProfileTableWidget->setItem(i, 4, item); item = new QTableWidgetItem("Instance"); item->setData(Qt::UserRole, QVariant::fromValue<AutoProfileInfo*>(info)); ui->autoProfileTableWidget->setItem(i, 5, item); i++; QListIterator<AutoProfileInfo*> iterDefaults(defaultList); while (iterDefaults.hasNext()) { AutoProfileInfo *info = iterDefaults.next(); ui->autoProfileTableWidget->insertRow(i); QTableWidgetItem *item = new QTableWidgetItem(); item->setCheckState(info->isActive() ? Qt::Checked : Qt::Unchecked); ui->autoProfileTableWidget->setItem(i, 0, item); QString deviceName = info->getDeviceName(); QString guidDisplay = info->getGUID(); if (!deviceName.isEmpty()) { guidDisplay = QString("%1 ").arg(info->getDeviceName()); guidDisplay.append(QString("(%1)").arg(info->getGUID())); } item = new QTableWidgetItem(guidDisplay); item->setFlags(item->flags() & ~Qt::ItemIsEditable); item->setData(Qt::UserRole, info->getGUID()); item->setToolTip(info->getGUID()); ui->autoProfileTableWidget->setItem(i, 1, item); QFileInfo profilePath(info->getProfileLocation()); item = new QTableWidgetItem(profilePath.fileName()); item->setFlags(item->flags() & ~Qt::ItemIsEditable); item->setData(Qt::UserRole, info->getProfileLocation()); item->setToolTip(info->getProfileLocation()); ui->autoProfileTableWidget->setItem(i, 2, item); QFileInfo exeInfo(info->getExe()); item = new QTableWidgetItem(exeInfo.fileName()); item->setFlags(item->flags() & ~Qt::ItemIsEditable); item->setData(Qt::UserRole, info->getExe()); item->setToolTip(info->getExe()); ui->autoProfileTableWidget->setItem(i, 3, item); item = new QTableWidgetItem("Default"); item->setData(Qt::UserRole, "default"); ui->autoProfileTableWidget->setItem(i, 4, item); item = new QTableWidgetItem("Instance"); item->setData(Qt::UserRole, QVariant::fromValue<AutoProfileInfo*>(info)); ui->autoProfileTableWidget->setItem(i, 5, item); i++; } QListIterator<AutoProfileInfo*> iter(profileList); while (iter.hasNext()) { AutoProfileInfo *info = iter.next(); ui->autoProfileTableWidget->insertRow(i); QTableWidgetItem *item = new QTableWidgetItem(); item->setCheckState(info->isActive() ? Qt::Checked : Qt::Unchecked); ui->autoProfileTableWidget->setItem(i, 0, item); QString deviceName = info->getDeviceName(); QString guidDisplay = info->getGUID(); if (!deviceName.isEmpty()) { guidDisplay = QString("%1 ").arg(info->getDeviceName()); guidDisplay.append(QString("(%1)").arg(info->getGUID())); } item = new QTableWidgetItem(guidDisplay); item->setFlags(item->flags() & ~Qt::ItemIsEditable); item->setData(Qt::UserRole, info->getGUID()); item->setToolTip(info->getGUID()); ui->autoProfileTableWidget->setItem(i, 1, item); QFileInfo profilePath(info->getProfileLocation()); item = new QTableWidgetItem(profilePath.fileName()); item->setFlags(item->flags() & ~Qt::ItemIsEditable); item->setData(Qt::UserRole, info->getProfileLocation()); item->setToolTip(info->getProfileLocation()); ui->autoProfileTableWidget->setItem(i, 2, item); QFileInfo exeInfo(info->getExe()); item = new QTableWidgetItem(exeInfo.fileName()); item->setFlags(item->flags() & ~Qt::ItemIsEditable); item->setData(Qt::UserRole, info->getExe()); item->setToolTip(info->getExe()); ui->autoProfileTableWidget->setItem(i, 3, item); item = new QTableWidgetItem(); item->setData(Qt::UserRole, ""); ui->autoProfileTableWidget->setItem(i, 4, item); item = new QTableWidgetItem("Instance"); item->setData(Qt::UserRole, QVariant::fromValue<AutoProfileInfo*>(info)); ui->autoProfileTableWidget->setItem(i, 5, item); i++; } }
void UTLauncher::startServerBrowser() { splashTimer.singleShot(2000, this, SLOT(closeSplash())); if(!settings.value("StartMinimized", false).toBool()) { browser->show(); } else { qApp->setQuitOnLastWindowClosed(false); // workaround for app not starting } browser->setMOTD(bootstrap.MOTD()); auto hasEditorSupport = [=] { QString editorPath = bootstrap.editorExePath(); QString projectPath = bootstrap.projectPath(); return QFile::exists(editorPath) && QFile::exists(projectPath); }; auto openSettings = [=](bool mandatoryEditor = false) { ConfigDialog dialog(settings, mandatoryEditor); dialog.exec(); browser->setEditorSupport(hasEditorSupport()); browser->setHideOnClose(settings.value("MinimizeToTrayOnClose").toBool()); }; connect(browser, &ServerBrowser::openServer, [=](QString url, bool spectate, bool inEditor) { if(inEditor) { QString editorPath = bootstrap.editorExePath(); QString projectPath = bootstrap.projectPath(); if(!editorPath.length() || !projectPath.length()) { openSettings(true); return; } QProcess::startDetached(editorPath, QStringList() << projectPath << "-GAME" << (url + (spectate?"?SpectatorOnly=1":"")) ); } else { QString exePath = bootstrap.programExePath(); if(!exePath.length()) { openSettings(); return; } const auto serverEntry = browser->serverEntryFromAddress(url); auto launch = [=] { qDebug() << "Launching!!\n"; QProcess::startDetached(exePath, QStringList() #ifdef LAUNCH_WITH_UE4 << "UnrealTournament" #endif << (url + (spectate?"?SpectatorOnly=1":"")) << "-SaveToUserDir"); }; if(serverEntry) { if(bootstrap.isStockMap(serverEntry->map)) { launch(); return; } QString exePath = bootstrap.programExePath(); QFileInfo exeInfo(exePath); auto contentDir = QDir(exeInfo.dir()); contentDir.cdUp(); contentDir.cdUp(); contentDir.cd("Content"); auto zipFilePath = contentDir.absoluteFilePath(serverEntry->map + ".zip"); if(QFile::exists(zipFilePath)) { launch(); return; } Download mapDownload; mapDownload.setTarget("https://ut.rushbase.net/customcontent/Data/" + serverEntry->map + ".zip"); QProgressDialog dialog("Downloading map: " + serverEntry->map, "Cancel", 0, 100); QFile zipFile(zipFilePath); zipFile.open(QIODevice::WriteOnly); int httpCode = 200; connect(&mapDownload, &Download::error, [&](int code) { httpCode = code; if(code != 200) { zipFile.remove(); QMessageBox::critical(nullptr, "Unable to download map", QString("Got code %1 while trying to download map:<br>%2").arg(code).arg(serverEntry->map)); } }); connect(&mapDownload, &Download::chunk, [&](QByteArray chunk) { qDebug() << "Reading!\n"; zipFile.write(chunk); }); connect(&mapDownload, &Download::progress, [&](double progress) { dialog.setValue(100*progress); if(progress == 1.0) { dialog.accept(); } }); mapDownload.download(); qDebug() << "Downloading map " << serverEntry->map; if(!dialog.exec() || httpCode != 200) { zipFile.remove(); // remove unfinished download return; } zipFile.close(); QProgressDialog installDialog("Installing map: " + serverEntry->map, "", 0, 100); installDialog.setWindowModality(Qt::ApplicationModal); installDialog.show(); installDialog.setValue(0); qDebug() << "Installed!!\n"; QuaZip zip(zipFilePath); auto textCodec = QTextCodec::codecForName("TSCII"); zip.setFileNameCodec(textCodec); zip.setCommentCodec(textCodec); zip.open(QuaZip::mdUnzip); QuaZipFile file(&zip); size_t totalSize = 0; for(bool f=zip.goToFirstFile(); f; f=zip.goToNextFile()) { QuaZipFileInfo info; zip.getCurrentFileInfo(&info); totalSize += info.uncompressedSize; } qDebug() << "Total size " << totalSize; size_t accumulatedSize = 0; /* TODO!!!!: this whole thing needs to be redone asynchronously */ for(bool f=zip.goToFirstFile(); f; f=zip.goToNextFile()) { file.open(QIODevice::ReadOnly); //same functionality as QIODevice::readData() -- data is a char*, maxSize is qint64 //file.readData(data,maxSize); QString filename = file.getActualFileName(); if(file.isOpen()) { qApp->processEvents(); qDebug() << installDialog.isVisible() << installDialog.value(); if(!installDialog.isVisible() && installDialog.value() != 100 && installDialog.value() != -1) return; bool isDir = (filename.right(1) == "/"); if(isDir) { contentDir.mkpath(filename); } else { QFile f(contentDir.absoluteFilePath(filename)); f.open(QIODevice::WriteOnly); auto data = file.readAll(); accumulatedSize += data.size(); qDebug() << accumulatedSize; installDialog.setValue(100 * (double)accumulatedSize / totalSize); qApp->processEvents(); qDebug() << installDialog.isVisible() << installDialog.value(); if(!installDialog.isVisible() && installDialog.value() != 100 && installDialog.value() != -1) return; f.write(data); } qDebug() << file.getActualFileName() << isDir; //do something with the data if(file.isOpen()) file.close(); qApp->processEvents(); qDebug() << installDialog.isVisible() << installDialog.value(); if(!installDialog.isVisible() && installDialog.value() != 100 && installDialog.value() != -1) return; } else { qDebug() << "Cannot open" << filename << "inside zip";; } } qDebug() << "Closing zip\n"; zip.close(); launch(); } } }); disconnect(&bootstrap, &Bootstrap::ready, this, &UTLauncher::prepareConfig); connect(&bootstrap, &Bootstrap::ready, this, [=] { browser->setMOTD(bootstrap.MOTD()); }); connect(browser, &ServerBrowser::openSettings, openSettings); browser->setEditorSupport(hasEditorSupport()); browser->setHideOnClose(settings.value("MinimizeToTrayOnClose", false).toBool()); systemTray.setToolTip("UTLauncher"); auto systemTrayMenu = new QMenu(browser); auto showBrowser = new QAction(awesome->icon(fa::listalt), "Server List", this); connect(showBrowser, &QAction::triggered, [=]() { browser->showNormal(); browser->raise(); browser->activateWindow(); }); auto runUTAction = new QAction(awesome->icon( fa::gamepad ),"Run UT", this); connect(runUTAction, &QAction::triggered, [=]() { QString exePath = bootstrap.programExePath(); if(!exePath.length()) { browser->show(); openSettings(); return; } QProcess::startDetached(exePath #ifdef LAUNCH_WITH_UE4 , QStringList() << "UnrealTournament" << "-SaveToUserDir" #endif ); }); auto runEditorAction = new QAction(awesome->icon( fa::code ),"Run Editor", this); connect(runEditorAction, &QAction::triggered, [=]() { QString editorPath = bootstrap.editorExePath(); QString projectPath = bootstrap.projectPath(); QProcess::startDetached(editorPath, QStringList() << projectPath); }); auto quitAction = new QAction(awesome->icon( fa::signout ),"Quit", this); connect(quitAction, &QAction::triggered, [=]() { QApplication::quit(); }); systemTrayMenu->addAction(showBrowser); systemTrayMenu->addSeparator(); systemTrayMenu->addAction(runUTAction); systemTrayMenu->addAction(runEditorAction); systemTrayMenu->addSeparator(); systemTrayMenu->addAction(quitAction); systemTray.setContextMenu(systemTrayMenu); systemTray.show(); connect(&systemTray, &QSystemTrayIcon::activated, [=](QSystemTrayIcon::ActivationReason reason) { qApp->setQuitOnLastWindowClosed(true); runEditorAction->setVisible(hasEditorSupport()); switch(reason) { case QSystemTrayIcon::Trigger: { if(browser->isHidden()) { browser->show(); } else { browser->hide(); } break; } } }); }
int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QString serialPortName; QString serialPortFriendlyName; QString sisFile; QString exeFile; QStringList cmdLine; QStringList args = QCoreApplication::arguments(); QTextStream outstream(stdout); QTextStream errstream(stderr); QString uploadLocalFile; QString uploadRemoteFile; QString downloadRemoteFile; QString downloadLocalFile; int loglevel=1; int timeout=0; bool crashlog = true; QString crashlogpath; QListIterator<QString> it(args); it.next(); //skip name of program while (it.hasNext()) { QString arg = it.next(); if (arg.startsWith("-")) { if (arg == "--portname" || arg == "-p") { CHECK_PARAMETER_EXISTS serialPortName = it.next(); } else if (arg == "--portfriendlyname" || arg == "-f") { CHECK_PARAMETER_EXISTS serialPortFriendlyName = it.next(); } else if (arg == "--sis" || arg == "-s") { CHECK_PARAMETER_EXISTS sisFile = it.next(); if (!QFileInfo(sisFile).exists()) { errstream << "Sis file (" << sisFile << ") doesn't exist" << endl; return 1; } } else if (arg == "--upload" || arg == "-u") { CHECK_PARAMETER_EXISTS uploadLocalFile = it.next(); if (!QFileInfo(uploadLocalFile).exists()) { errstream << "Executable file (" << uploadLocalFile << ") doesn't exist" << endl; return 1; } CHECK_PARAMETER_EXISTS uploadRemoteFile = it.next(); } else if (arg == "--download" || arg == "-d") { CHECK_PARAMETER_EXISTS downloadRemoteFile = it.next(); CHECK_PARAMETER_EXISTS downloadLocalFile = it.next(); } else if (arg == "--timeout" || arg == "-t") { CHECK_PARAMETER_EXISTS bool ok; timeout = it.next().toInt(&ok); if (!ok) { errstream << "Timeout must be specified in milliseconds" << endl; return 1; } } else if (arg == "--verbose" || arg == "-v") loglevel=2; else if (arg == "--quiet" || arg == "-q") loglevel=0; else if (arg == "--nocrashlog") crashlog = false; else if (arg == "--crashlogpath") { CHECK_PARAMETER_EXISTS crashlogpath = it.next(); } else errstream << "unknown command line option " << arg << endl; } else { exeFile = arg; while(it.hasNext()) { cmdLine.append(it.next()); } } } if (exeFile.isEmpty() && sisFile.isEmpty() && (uploadLocalFile.isEmpty() || uploadRemoteFile.isEmpty()) && (downloadLocalFile.isEmpty() || downloadRemoteFile.isEmpty())) { printUsage(outstream, args[0]); return 1; } if (!uploadLocalFile.isEmpty() && (!downloadLocalFile.isEmpty() || !downloadRemoteFile.isEmpty())) { errstream << "Upload option can't be used together with download" << endl; printUsage(outstream, args[0]); return 1; } if (serialPortName.isEmpty()) { if (loglevel > 0) outstream << "Detecting serial ports" << endl; foreach (const SerialPortId &id, enumerateSerialPorts(loglevel)) { if (loglevel > 0) outstream << "Port Name: " << id.portName << ", " << "Friendly Name:" << id.friendlyName << endl; if (!id.friendlyName.isEmpty() && serialPortFriendlyName.isEmpty() && (id.friendlyName.contains("symbian", Qt::CaseInsensitive) || id.friendlyName.contains("s60", Qt::CaseInsensitive) || id.friendlyName.contains("nokia", Qt::CaseInsensitive))) { serialPortName = id.portName; break; } else if (!id.friendlyName.isEmpty() && !serialPortFriendlyName.isEmpty() && id.friendlyName.contains(serialPortFriendlyName)) { serialPortName = id.portName; break; } } if (serialPortName.isEmpty()) { errstream << "No phone found, ensure USB cable is connected or specify manually with -p" << endl; return 1; } } QScopedPointer<trk::Launcher> launcher; launcher.reset(new trk::Launcher(trk::Launcher::ActionPingOnly)); QFileInfo exeInfo(exeFile); QFileInfo uploadInfo(uploadLocalFile); if (!sisFile.isEmpty()) { launcher->addStartupActions(trk::Launcher::ActionCopyInstall); launcher->setCopyFileName(sisFile, "c:\\data\\testtemp.sis"); launcher->setInstallFileName("c:\\data\\testtemp.sis"); } else if (!uploadLocalFile.isEmpty() && uploadInfo.exists()) { launcher->addStartupActions(trk::Launcher::ActionCopy); launcher->setCopyFileName(uploadLocalFile, uploadRemoteFile); } if (!exeFile.isEmpty()) { launcher->addStartupActions(trk::Launcher::ActionRun); launcher->setFileName(QString("c:\\sys\\bin\\") + exeInfo.fileName()); launcher->setCommandLineArgs(cmdLine); } if (!downloadRemoteFile.isEmpty() && !downloadLocalFile.isEmpty()) { launcher->addStartupActions(trk::Launcher::ActionDownload); launcher->setDownloadFileName(downloadRemoteFile, downloadLocalFile); } if (loglevel > 0) outstream << "Connecting to target via " << serialPortName << endl; launcher->setTrkServerName(serialPortName); if (loglevel > 1) launcher->setVerbose(1); TrkSignalHandler handler; handler.setLogLevel(loglevel); handler.setCrashLogging(crashlog); handler.setCrashLogPath(crashlogpath); QObject::connect(launcher.data(), SIGNAL(copyingStarted()), &handler, SLOT(copyingStarted())); QObject::connect(launcher.data(), SIGNAL(canNotConnect(const QString &)), &handler, SLOT(canNotConnect(const QString &))); QObject::connect(launcher.data(), SIGNAL(canNotCreateFile(const QString &, const QString &)), &handler, SLOT(canNotCreateFile(const QString &, const QString &))); QObject::connect(launcher.data(), SIGNAL(canNotWriteFile(const QString &, const QString &)), &handler, SLOT(canNotWriteFile(const QString &, const QString &))); QObject::connect(launcher.data(), SIGNAL(canNotCloseFile(const QString &, const QString &)), &handler, SLOT(canNotCloseFile(const QString &, const QString &))); QObject::connect(launcher.data(), SIGNAL(installingStarted()), &handler, SLOT(installingStarted())); QObject::connect(launcher.data(), SIGNAL(canNotInstall(const QString &, const QString &)), &handler, SLOT(canNotInstall(const QString &, const QString &))); QObject::connect(launcher.data(), SIGNAL(installingFinished()), &handler, SLOT(installingFinished())); QObject::connect(launcher.data(), SIGNAL(startingApplication()), &handler, SLOT(startingApplication())); QObject::connect(launcher.data(), SIGNAL(applicationRunning(uint)), &handler, SLOT(applicationRunning(uint))); QObject::connect(launcher.data(), SIGNAL(canNotRun(const QString &)), &handler, SLOT(canNotRun(const QString &))); QObject::connect(launcher.data(), SIGNAL(applicationOutputReceived(const QString &)), &handler, SLOT(applicationOutputReceived(const QString &))); QObject::connect(launcher.data(), SIGNAL(copyProgress(int)), &handler, SLOT(copyProgress(int))); QObject::connect(launcher.data(), SIGNAL(stateChanged(int)), &handler, SLOT(stateChanged(int))); QObject::connect(launcher.data(), SIGNAL(processStopped(uint,uint,uint,QString)), &handler, SLOT(stopped(uint,uint,uint,QString))); QObject::connect(launcher.data(), SIGNAL(libraryLoaded(trk::Library)), &handler, SLOT(libraryLoaded(trk::Library))); QObject::connect(launcher.data(), SIGNAL(libraryUnloaded(trk::Library)), &handler, SLOT(libraryUnloaded(trk::Library))); QObject::connect(launcher.data(), SIGNAL(registersAndCallStackReadComplete(const QList<uint> &,const QByteArray &)), &handler, SLOT(registersAndCallStackReadComplete(const QList<uint> &,const QByteArray &))); QObject::connect(&handler, SIGNAL(resume(uint,uint)), launcher.data(), SLOT(resumeProcess(uint,uint))); QObject::connect(&handler, SIGNAL(terminate()), launcher.data(), SLOT(terminate())); QObject::connect(&handler, SIGNAL(getRegistersAndCallStack(uint,uint)), launcher.data(), SLOT(getRegistersAndCallStack(uint,uint))); QObject::connect(launcher.data(), SIGNAL(finished()), &handler, SLOT(finished())); QObject::connect(OsSignalConverter::instance(), SIGNAL(terminate()), launcher.data(), SLOT(terminate()), Qt::QueuedConnection); QTimer timer; timer.setSingleShot(true); QObject::connect(&timer, SIGNAL(timeout()), &handler, SLOT(timeout())); if (timeout > 0) { timer.start(timeout); } QString errorMessage; if (!launcher->startServer(&errorMessage)) { errstream << errorMessage << endl; return 1; } return a.exec(); }