Skip to content

Commit

Permalink
Merge pull request PrismLauncher#2900 from TheKodeToad/log-utf8
Browse files Browse the repository at this point in the history
Use UTF-8 to decode logs on Java 18 or newer
  • Loading branch information
TayouVR authored Oct 11, 2024
2 parents 2abbcdf + 98adcc6 commit 0c4c86c
Show file tree
Hide file tree
Showing 14 changed files with 49 additions and 43 deletions.
3 changes: 2 additions & 1 deletion launcher/LoggedProcess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@
#include <QTextDecoder>
#include "MessageLevel.h"

LoggedProcess::LoggedProcess(QObject* parent) : QProcess(parent)
LoggedProcess::LoggedProcess(const QTextCodec* output_codec, QObject* parent)
: QProcess(parent), m_err_decoder(output_codec), m_out_decoder(output_codec)
{
// QProcess has a strange interface... let's map a lot of those into a few.
connect(this, &QProcess::readyReadStandardOutput, this, &LoggedProcess::on_stdOut);
Expand Down
6 changes: 3 additions & 3 deletions launcher/LoggedProcess.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class LoggedProcess : public QProcess {
enum State { NotRunning, Starting, FailedToStart, Running, Finished, Crashed, Aborted };

public:
explicit LoggedProcess(QObject* parent = 0);
explicit LoggedProcess(const QTextCodec* output_codec = QTextCodec::codecForLocale(), QObject* parent = 0);
virtual ~LoggedProcess();

State state() const;
Expand Down Expand Up @@ -80,8 +80,8 @@ class LoggedProcess : public QProcess {
QStringList reprocess(const QByteArray& data, QTextDecoder& decoder);

private:
QTextDecoder m_err_decoder = QTextDecoder(QTextCodec::codecForLocale());
QTextDecoder m_out_decoder = QTextDecoder(QTextCodec::codecForLocale());
QTextDecoder m_err_decoder;
QTextDecoder m_out_decoder;
QString m_leftover_line;
bool m_killed = false;
State m_state = NotRunning;
Expand Down
6 changes: 6 additions & 0 deletions launcher/java/JavaVersion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ bool JavaVersion::requiresPermGen() const
return !m_parseable || m_major < 8;
}

bool JavaVersion::defaultsToUtf8() const
{
// starting from Java 18, UTF-8 is the default charset: https://openjdk.org/jeps/400
return m_parseable && m_major >= 18;
}

bool JavaVersion::isModular() const
{
return m_parseable && m_major >= 9;
Expand Down
2 changes: 1 addition & 1 deletion launcher/java/JavaVersion.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class JavaVersion {
bool operator>(const JavaVersion& rhs);

bool requiresPermGen() const;

bool defaultsToUtf8() const;
bool isModular() const;

QString toString() const;
Expand Down
4 changes: 2 additions & 2 deletions launcher/launch/LaunchTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,14 @@ void LaunchTask::init()
m_instance->setRunning(true);
}

shared_qobject_ptr<LaunchTask> LaunchTask::create(InstancePtr inst)
shared_qobject_ptr<LaunchTask> LaunchTask::create(MinecraftInstancePtr inst)
{
shared_qobject_ptr<LaunchTask> proc(new LaunchTask(inst));
proc->init();
return proc;
}

LaunchTask::LaunchTask(InstancePtr instance) : m_instance(instance) {}
LaunchTask::LaunchTask(MinecraftInstancePtr instance) : m_instance(instance) {}

void LaunchTask::appendStep(shared_qobject_ptr<LaunchStep> step)
{
Expand Down
9 changes: 5 additions & 4 deletions launcher/launch/LaunchTask.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@

#pragma once
#include <QObjectPtr.h>
#include <minecraft/MinecraftInstance.h>
#include <QProcess>
#include "BaseInstance.h"
#include "LaunchStep.h"
Expand All @@ -46,21 +47,21 @@
class LaunchTask : public Task {
Q_OBJECT
protected:
explicit LaunchTask(InstancePtr instance);
explicit LaunchTask(MinecraftInstancePtr instance);
void init();

public:
enum State { NotStarted, Running, Waiting, Failed, Aborted, Finished };

public: /* methods */
static shared_qobject_ptr<LaunchTask> create(InstancePtr inst);
static shared_qobject_ptr<LaunchTask> create(MinecraftInstancePtr inst);
virtual ~LaunchTask() = default;

void appendStep(shared_qobject_ptr<LaunchStep> step);
void prependStep(shared_qobject_ptr<LaunchStep> step);
void setCensorFilter(QMap<QString, QString> filter);

InstancePtr instance() { return m_instance; }
MinecraftInstancePtr instance() { return m_instance; }

void setPid(qint64 pid) { m_pid = pid; }

Expand Down Expand Up @@ -115,7 +116,7 @@ class LaunchTask : public Task {
void finalizeSteps(bool successful, const QString& error);

protected: /* data */
InstancePtr m_instance;
MinecraftInstancePtr m_instance;
shared_qobject_ptr<LogModel> m_logModel;
QList<shared_qobject_ptr<LaunchStep>> m_steps;
QMap<QString, QString> m_censorFilter;
Expand Down
2 changes: 1 addition & 1 deletion launcher/minecraft/launch/AutoInstallJava.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@

AutoInstallJava::AutoInstallJava(LaunchTask* parent)
: LaunchStep(parent)
, m_instance(std::dynamic_pointer_cast<MinecraftInstance>(m_parent->instance()))
, m_instance(m_parent->instance())
, m_supported_arch(SysInfo::getSupportedJavaArchitecture()) {};

void AutoInstallJava::executeTask()
Expand Down
5 changes: 2 additions & 3 deletions launcher/minecraft/launch/CreateGameFolders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,15 @@ CreateGameFolders::CreateGameFolders(LaunchTask* parent) : LaunchStep(parent) {}
void CreateGameFolders::executeTask()
{
auto instance = m_parent->instance();
std::shared_ptr<MinecraftInstance> minecraftInstance = std::dynamic_pointer_cast<MinecraftInstance>(instance);

if (!FS::ensureFolderPathExists(minecraftInstance->gameRoot())) {
if (!FS::ensureFolderPathExists(instance->gameRoot())) {
emit logLine("Couldn't create the main game folder", MessageLevel::Error);
emitFailed(tr("Couldn't create the main game folder"));
return;
}

// HACK: this is a workaround for MCL-3732 - 'server-resource-packs' folder is created.
if (!FS::ensureFolderPathExists(FS::PathCombine(minecraftInstance->gameRoot(), "server-resource-packs"))) {
if (!FS::ensureFolderPathExists(FS::PathCombine(instance->gameRoot(), "server-resource-packs"))) {
emit logLine("Couldn't create the 'server-resource-packs' folder", MessageLevel::Error);
}
emitSucceeded();
Expand Down
9 changes: 4 additions & 5 deletions launcher/minecraft/launch/ExtractNatives.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,17 +70,16 @@ static bool unzipNatives(QString source, QString targetFolder, bool applyJnilibH
void ExtractNatives::executeTask()
{
auto instance = m_parent->instance();
std::shared_ptr<MinecraftInstance> minecraftInstance = std::dynamic_pointer_cast<MinecraftInstance>(instance);
auto toExtract = minecraftInstance->getNativeJars();
auto toExtract = instance->getNativeJars();
if (toExtract.isEmpty()) {
emitSucceeded();
return;
}
auto settings = minecraftInstance->settings();
auto settings = instance->settings();

auto outputPath = minecraftInstance->getNativePath();
auto outputPath = instance->getNativePath();
FS::ensureFolderPathExists(outputPath);
auto javaVersion = minecraftInstance->getJavaVersion();
auto javaVersion = instance->getJavaVersion();
bool jniHackEnabled = javaVersion.major() >= 8;
for (const auto& source : toExtract) {
if (!unzipNatives(source, outputPath, jniHackEnabled)) {
Expand Down
33 changes: 17 additions & 16 deletions launcher/minecraft/launch/LauncherPartLaunch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,20 @@
#include "gamemode_client.h"
#endif

LauncherPartLaunch::LauncherPartLaunch(LaunchTask* parent) : LaunchStep(parent)
LauncherPartLaunch::LauncherPartLaunch(LaunchTask* parent)
: LaunchStep(parent)
, m_process(parent->instance()->getJavaVersion().defaultsToUtf8() ? QTextCodec::codecForName("UTF-8") : QTextCodec::codecForLocale())
{
auto instance = parent->instance();
if (instance->settings()->get("CloseAfterLaunch").toBool()) {
if (parent->instance()->settings()->get("CloseAfterLaunch").toBool()) {
std::shared_ptr<QMetaObject::Connection> connection{ new QMetaObject::Connection };
*connection = connect(&m_process, &LoggedProcess::log, this, [=](QStringList lines, [[maybe_unused]] MessageLevel::Enum level) {
qDebug() << lines;
if (lines.filter(QRegularExpression(".*Setting user.+", QRegularExpression::CaseInsensitiveOption)).length() != 0) {
APPLICATION->closeAllWindows();
disconnect(*connection);
}
});
*connection =
connect(&m_process, &LoggedProcess::log, this, [=](const QStringList& lines, [[maybe_unused]] MessageLevel::Enum level) {
qDebug() << lines;
if (lines.filter(QRegularExpression(".*Setting user.+", QRegularExpression::CaseInsensitiveOption)).length() != 0) {
APPLICATION->closeAllWindows();
disconnect(*connection);
}
});
}

connect(&m_process, &LoggedProcess::log, this, &LauncherPartLaunch::logLines);
Expand All @@ -77,10 +79,9 @@ void LauncherPartLaunch::executeTask()
}

auto instance = m_parent->instance();
std::shared_ptr<MinecraftInstance> minecraftInstance = std::dynamic_pointer_cast<MinecraftInstance>(instance);

QString legacyJarPath;
if (minecraftInstance->getLauncher() == "legacy" || minecraftInstance->shouldApplyOnlineFixes()) {
if (instance->getLauncher() == "legacy" || instance->shouldApplyOnlineFixes()) {
legacyJarPath = APPLICATION->getJarPath("NewLaunchLegacy.jar");
if (legacyJarPath.isEmpty()) {
const char* reason = QT_TR_NOOP("Legacy launcher library could not be found. Please check your installation.");
Expand All @@ -90,8 +91,8 @@ void LauncherPartLaunch::executeTask()
}
}

m_launchScript = minecraftInstance->createLaunchScript(m_session, m_targetToJoin);
QStringList args = minecraftInstance->javaArguments();
m_launchScript = instance->createLaunchScript(m_session, m_targetToJoin);
QStringList args = instance->javaArguments();
QString allArgs = args.join(", ");
emit logLine("Java Arguments:\n[" + m_parent->censorPrivateInfo(allArgs) + "]\n\n", MessageLevel::Launcher);

Expand All @@ -102,13 +103,13 @@ void LauncherPartLaunch::executeTask()
// make detachable - this will keep the process running even if the object is destroyed
m_process.setDetachable(true);

auto classPath = minecraftInstance->getClassPath();
auto classPath = instance->getClassPath();
classPath.prepend(jarPath);

if (!legacyJarPath.isEmpty())
classPath.prepend(legacyJarPath);

auto natPath = minecraftInstance->getNativePath();
auto natPath = instance->getNativePath();
#ifdef Q_OS_WIN
natPath = FS::getPathNameInLocal8bit(natPath);
#endif
Expand Down
4 changes: 2 additions & 2 deletions launcher/minecraft/launch/ModMinecraftJar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@

void ModMinecraftJar::executeTask()
{
auto m_inst = std::dynamic_pointer_cast<MinecraftInstance>(m_parent->instance());
auto m_inst = m_parent->instance();

if (!m_inst->getJarMods().size()) {
emitSucceeded();
Expand Down Expand Up @@ -82,7 +82,7 @@ void ModMinecraftJar::finalize()

bool ModMinecraftJar::removeJar()
{
auto m_inst = std::dynamic_pointer_cast<MinecraftInstance>(m_parent->instance());
auto m_inst = m_parent->instance();
auto finalJarPath = QDir(m_inst->binRoot()).absoluteFilePath("minecraft.jar");
QFile finalJar(finalJarPath);
if (finalJar.exists()) {
Expand Down
5 changes: 2 additions & 3 deletions launcher/minecraft/launch/ReconstructAssets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,11 @@
void ReconstructAssets::executeTask()
{
auto instance = m_parent->instance();
std::shared_ptr<MinecraftInstance> minecraftInstance = std::dynamic_pointer_cast<MinecraftInstance>(instance);
auto components = minecraftInstance->getPackProfile();
auto components = instance->getPackProfile();
auto profile = components->getProfile();
auto assets = profile->getMinecraftAssets();

if (!AssetsUtils::reconstructAssets(assets->id, minecraftInstance->resourcesDir())) {
if (!AssetsUtils::reconstructAssets(assets->id, instance->resourcesDir())) {
emit logLine("Failed to reconstruct Minecraft assets.", MessageLevel::Error);
}

Expand Down
2 changes: 1 addition & 1 deletion launcher/minecraft/launch/ScanModFolders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@

void ScanModFolders::executeTask()
{
auto m_inst = std::dynamic_pointer_cast<MinecraftInstance>(m_parent->instance());
auto m_inst = m_parent->instance();

auto loaders = m_inst->loaderModList();
connect(loaders.get(), &ModFolderModel::updateFinished, this, &ScanModFolders::modsDone);
Expand Down
2 changes: 1 addition & 1 deletion launcher/minecraft/launch/VerifyJavaInstall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@

void VerifyJavaInstall::executeTask()
{
auto instance = std::dynamic_pointer_cast<MinecraftInstance>(m_parent->instance());
auto instance = m_parent->instance();
auto packProfile = instance->getPackProfile();
auto settings = instance->settings();
auto storedVersion = settings->get("JavaVersion").toString();
Expand Down

0 comments on commit 0c4c86c

Please sign in to comment.