mirror-chatterino2/src/singletons/Paths.cpp
nerix e377c30192
Add Crashpad Support on Windows (#4351)
* feat: crashpad on windows

* feat: inline it

* feat: more crashpad

* chore: remove qBreakpad

* fix: add mention to crashpad

* refactor: version string

* feat: add crashpad module

* refactor: build crashpad from source

* fix: minor adjustments

* chore: add changelog entry

* fix: formatting and include

* fix: format

* build: use flags similar to release profile

* ci: build with crashpad on windows

* ci: recurse submodules

* ci: always include crashpad

* fix: try 7z

for some reason zstd just doesn't run

* fix: wrong path for symbols

* fix: copy

pls don't build

* ci: use new cache key

* fix: missing pragma

* ci: add workflow without crashpad

* docs: elevate changelog entry

* fix: add link to cmake issue

* fix: windows include issue

Someone (crashpad) includes Windows.h before winsock2.h

* fix: working directory

* fix: another working directory
2023-02-12 20:36:58 +01:00

154 lines
3.6 KiB
C++

#include "singletons/Paths.hpp"
#include "common/Modes.hpp"
#include "singletons/Settings.hpp"
#include "util/CombinePath.hpp"
#include <QCoreApplication>
#include <QCryptographicHash>
#include <QDir>
#include <QStandardPaths>
#include <cassert>
using namespace std::literals;
namespace chatterino {
Paths *Paths::instance = nullptr;
Paths::Paths()
{
this->instance = this;
this->initAppFilePathHash();
this->initCheckPortable();
this->initRootDirectory();
this->initSubDirectories();
}
bool Paths::createFolder(const QString &folderPath)
{
return QDir().mkpath(folderPath);
}
bool Paths::isPortable()
{
return Modes::instance().isPortable;
}
QString Paths::cacheDirectory()
{
static const auto pathSetting = [] {
QStringSetting cachePathSetting("/cache/path");
cachePathSetting.connect([](const auto &newPath, auto) {
if (!newPath.isEmpty())
{
QDir().mkpath(newPath);
}
});
return cachePathSetting;
}();
auto path = pathSetting.getValue();
if (path.isEmpty())
{
return this->cacheDirectory_;
}
return path;
}
void Paths::initAppFilePathHash()
{
this->applicationFilePathHash =
QCryptographicHash::hash(
QCoreApplication::applicationFilePath().toUtf8(),
QCryptographicHash::Sha224)
.toBase64()
.mid(0, 32)
.replace("+", "-")
.replace("/", "x");
}
void Paths::initCheckPortable()
{
this->portable_ = QFileInfo::exists(
combinePath(QCoreApplication::applicationDirPath(), "portable"));
}
void Paths::initRootDirectory()
{
assert(this->portable_.is_initialized());
// Root path = %APPDATA%/Chatterino or the folder that the executable
// resides in
this->rootAppDataDirectory = [&]() -> QString {
// portable
if (this->isPortable())
{
return QCoreApplication::applicationDirPath();
}
// permanent installation
QString path =
QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
if (path.isEmpty())
{
throw std::runtime_error("Could not create directory \""s +
path.toStdString() + "\"");
}
// create directory Chatterino2 instead of Chatterino on windows because the
// ladder one is takes by Chatterino 1 already
#ifdef Q_OS_WIN
path.replace("chatterino", "Chatterino");
path += "2";
#endif
return path;
}();
}
void Paths::initSubDirectories()
{
// required the app data directory to be set first
assert(!this->rootAppDataDirectory.isEmpty());
// create settings subdirectories and validate that they are created
// properly
auto makePath = [&](const std::string &name) -> QString {
auto path = combinePath(this->rootAppDataDirectory,
QString::fromStdString(name));
if (!QDir().mkpath(path))
{
throw std::runtime_error("Could not create directory \""s +
path.toStdString() + "\"");
}
return path;
};
makePath("");
this->settingsDirectory = makePath("Settings");
this->cacheDirectory_ = makePath("Cache");
this->messageLogDirectory = makePath("Logs");
this->miscDirectory = makePath("Misc");
this->twitchProfileAvatars = makePath("ProfileAvatars");
this->crashdumpDirectory = makePath("Crashes");
//QDir().mkdir(this->twitchProfileAvatars + "/twitch");
}
Paths *getPaths()
{
return Paths::instance;
}
} // namespace chatterino