GlosSITarget: Added Steambase URL

add `WS_EX_TOOLWINDOW` in extended windows styles for GlosSI-Target

https://learn.microsoft.com/en-us/windows/win32/winmsg/extended-window-styles

Goal is to remove GlosSI-Target window in Alt-Tab listing as it will induce issues with Steam Link and not particularly intuitive when switching from and to a game.

Currently untested, PR needed only for building a PoC of it and checking for possible issues

typo

added comment

Added proper setting value (default: off)

Added toggle inside ImGui

It's that time of the year again

Clone submodules via https instead of ssh

Uncamelcasify EGS game names

Fix shortcut names not editable

Add Configurator option to exclude target-window from windowlist

Hack together shitty method to retrieve original unhooking bytes via GlosSIConfig

Here's hoping that this will prevent access-violation issues for some users

Store SteamPath/SteamUserId in Settings and use as fallback

Option to disable GlosSIs additional overlay

Update Usage.md

Added steambase url

Update Usage.md

Update Usage.md

Update Usage.md
pull/231/head
Peter Repukat 2 years ago committed by Simon Ferns
parent be8e206683
commit 4374ec0429

8
.gitmodules vendored

@ -27,13 +27,13 @@
url = https://github.com/nlohmann/json url = https://github.com/nlohmann/json
[submodule "deps/traypp"] [submodule "deps/traypp"]
path = deps/traypp path = deps/traypp
url = https://github.com/Soundux/traypp.git url = https://github.com/Soundux/traypp
[submodule "deps/fifo_map"] [submodule "deps/fifo_map"]
path = deps/fifo_map path = deps/fifo_map
url = git@github.com:nlohmann/fifo_map.git url = https://github.com/nlohmann/fifo_map
[submodule "deps/Shortcuts_VDF"] [submodule "deps/Shortcuts_VDF"]
path = deps/Shortcuts_VDF path = deps/Shortcuts_VDF
url = git@github.com:Alia5/Shortcuts_VDF.git url = https://github.com/Alia5/Shortcuts_VDF
[submodule "deps/cpp-httplib"] [submodule "deps/cpp-httplib"]
path = deps/cpp-httplib path = deps/cpp-httplib
url = git@github.com:yhirose/cpp-httplib.git url = https://github.com/yhirose/cpp-httplib

@ -69,7 +69,7 @@
<AdditionalUsingDirectories>%(AdditionalUsingDirectories)</AdditionalUsingDirectories> <AdditionalUsingDirectories>%(AdditionalUsingDirectories)</AdditionalUsingDirectories>
<AdditionalOptions>/Zc:__cplusplus /Zc:twoPhase- %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/Zc:__cplusplus /Zc:twoPhase- %(AdditionalOptions)</AdditionalOptions>
<CompileAsWinRT>false</CompileAsWinRT> <CompileAsWinRT>false</CompileAsWinRT>
<PreprocessorDefinitions>NOMINMAX;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>NOMINMAX;CONFIGAPP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\deps\WinReg;..\deps\fifo_map\src;..\deps\Shortcuts_VDF\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\deps\WinReg;..\deps\fifo_map\src;..\deps\Shortcuts_VDF\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Manifest> <Manifest>
@ -92,7 +92,7 @@
<AdditionalUsingDirectories>%(AdditionalUsingDirectories)</AdditionalUsingDirectories> <AdditionalUsingDirectories>%(AdditionalUsingDirectories)</AdditionalUsingDirectories>
<AdditionalOptions>/Zc:__cplusplus /Zc:zwoPhase- /permissive- %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/Zc:__cplusplus /Zc:zwoPhase- /permissive- %(AdditionalOptions)</AdditionalOptions>
<CompileAsWinRT>false</CompileAsWinRT> <CompileAsWinRT>false</CompileAsWinRT>
<PreprocessorDefinitions>NOMINMAX;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>NOMINMAX;CONFIGAPP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\deps\WinReg;..\deps\fifo_map\src;..\deps\Shortcuts_VDF\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\deps\WinReg;..\deps\fifo_map\src;..\deps\Shortcuts_VDF\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Manifest> <Manifest>
@ -136,6 +136,7 @@
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\GlosSITarget\UnhookUtil.cpp" />
<ClCompile Include="ExeImageProvider.cpp" /> <ClCompile Include="ExeImageProvider.cpp" />
<ClCompile Include="main.cpp" /> <ClCompile Include="main.cpp" />
<ClCompile Include="UIModel.cpp" /> <ClCompile Include="UIModel.cpp" />

@ -37,6 +37,9 @@
<ClCompile Include="ExeImageProvider.cpp"> <ClCompile Include="ExeImageProvider.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\GlosSITarget\UnhookUtil.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="qml\main.qml"> <None Include="qml\main.qml">

@ -51,8 +51,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,1,1,101000823500 FILEVERSION 0,1,1,2012005004400
PRODUCTVERSION 0,1,1,101000823500 PRODUCTVERSION 0,1,1,2012005004400
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -69,12 +69,12 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "Peter Repukat - FlatspotSoftware" VALUE "CompanyName", "Peter Repukat - FlatspotSoftware"
VALUE "FileDescription", "GlosSI - Config" VALUE "FileDescription", "GlosSI - Config"
VALUE "FileVersion", "0.1.1.1-1-ga8235ca" VALUE "FileVersion", "0.1.1.2-12-g5fe44d0"
VALUE "InternalName", "GlosSIConfig" VALUE "InternalName", "GlosSIConfig"
VALUE "LegalCopyright", "Copyright (C) 2021 Peter Repukat - FlatspotSoftware" VALUE "LegalCopyright", "Copyright (C) 2021 Peter Repukat - FlatspotSoftware"
VALUE "OriginalFilename", "GlosSIConfig.exe" VALUE "OriginalFilename", "GlosSIConfig.exe"
VALUE "ProductName", "GlosSI" VALUE "ProductName", "GlosSI"
VALUE "ProductVersion", "0.1.1.1-1-ga8235ca" VALUE "ProductVersion", "0.1.1.2-12-g5fe44d0"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"
@ -1400,6 +1400,106 @@ IDI_ICON1 ICON "..\GlosSI_Icon.ico"

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -22,6 +22,8 @@ limitations under the License.
#include <QJsonArray> #include <QJsonArray>
#include <QNetworkAccessManager> #include <QNetworkAccessManager>
#include <QNetworkReply> #include <QNetworkReply>
#include <QMetaType>
#include <WinReg/WinReg.hpp> #include <WinReg/WinReg.hpp>
@ -36,6 +38,9 @@ limitations under the License.
#include "ExeImageProvider.h" #include "ExeImageProvider.h"
#include "../version.hpp" #include "../version.hpp"
#include "../../GlosSITarget/UnhookUtil.h"
UIModel::UIModel() : QObject(nullptr) UIModel::UIModel() : QObject(nullptr)
{ {
wchar_t* localAppDataFolder; wchar_t* localAppDataFolder;
@ -60,9 +65,13 @@ UIModel::UIModel() : QObject(nullptr)
if (!std::filesystem::exists(path)) if (!std::filesystem::exists(path))
std::filesystem::create_directories(path); std::filesystem::create_directories(path);
auto defaultConf = getDefaultConf();
saveDefaultConf(defaultConf);
parseShortcutVDF(); parseShortcutVDF();
readTargetConfigs(); readTargetConfigs();
updateCheck(); updateCheck();
readUnhookBytes();
auto font = QGuiApplication::font(); auto font = QGuiApplication::font();
font.setPointSize(11); font.setPointSize(11);
@ -115,6 +124,8 @@ bool UIModel::updateTarget(int index, QVariant shortcut)
const auto map = shortcut.toMap(); const auto map = shortcut.toMap();
const auto json = QJsonObject::fromVariantMap(map); const auto json = QJsonObject::fromVariantMap(map);
const auto was_in_steam_ = isInSteam(shortcut);
auto oldSteamName = targets_[index].toMap()["name"].toString(); auto oldSteamName = targets_[index].toMap()["name"].toString();
auto oldName = auto oldName =
targets_[index].toMap()["name"].toString().replace(QRegularExpression("[\\\\/:*?\"<>|]"), "") + ".json"; targets_[index].toMap()["name"].toString().replace(QRegularExpression("[\\\\/:*?\"<>|]"), "") + ".json";
@ -132,15 +143,19 @@ bool UIModel::updateTarget(int index, QVariant shortcut)
path /= config_dir_name_.toStdString(); path /= config_dir_name_.toStdString();
path /= (map["name"].toString()).toStdString(); path /= (map["name"].toString()).toStdString();
if (removeFromSteam(oldSteamName, QString::fromStdWString(path.wstring()))) { if (was_in_steam_) {
if (!addToSteam(shortcut, QString::fromStdWString(path.wstring()))) { if (removeFromSteam(oldSteamName, QString::fromStdWString(path.wstring()))) {
qDebug() << "Couldn't add shortcut \"" << (map["name"].toString()) << "\" to Steam when updating"; if (!addToSteam(shortcut, QString::fromStdWString(path.wstring()))) {
return false; qDebug() << "Couldn't add shortcut \"" << (map["name"].toString()) << "\" to Steam when updating";
return false;
}
return true;
} }
qDebug() << "Couldn't remove shortcut \"" << oldName << "\" from Steam when updating";
return false;
} else {
return true; return true;
} }
qDebug() << "Couldn't remove shortcut \"" << oldName << "\" from Steam when updating";
return false;
} }
void UIModel::deleteTarget(int index) void UIModel::deleteTarget(int index)
@ -159,7 +174,9 @@ bool UIModel::isInSteam(QVariant shortcut) const
{ {
const auto map = shortcut.toMap(); const auto map = shortcut.toMap();
for (auto& steam_shortcut : shortcuts_vdf_) { for (auto& steam_shortcut : shortcuts_vdf_) {
if (map["name"].toString() == QString::fromStdString(steam_shortcut.appname)) { if (
map["name"].toString() == QString::fromStdString(steam_shortcut.appname) ||
map["oldName"].toString() == QString::fromStdString(steam_shortcut.appname)) {
if (QString::fromStdString(steam_shortcut.exe).toLower().contains("glossitarget.exe")) { if (QString::fromStdString(steam_shortcut.exe).toLower().contains("glossitarget.exe")) {
return true; return true;
} }
@ -383,6 +400,10 @@ QVariantMap UIModel::getDefaultConf() const
{"extendedLogging", false}, {"extendedLogging", false},
{"snapshotNotify", false}, {"snapshotNotify", false},
{"steamgridApiKey", QJsonValue::Null}, {"steamgridApiKey", QJsonValue::Null},
{"steamPath",
QJsonValue::fromVariant(QString::fromStdWString(getSteamPath(false).wstring()))},
{"steamUserId",
QJsonValue::fromVariant(QString::fromStdWString(getSteamUserId(false)))},
{"controller", QJsonObject{{"maxControllers", 1}, {"emulateDS4", false}, {"allowDesktopConfig", false}}}, {"controller", QJsonObject{{"maxControllers", 1}, {"emulateDS4", false}, {"allowDesktopConfig", false}}},
{"devices", {"devices",
QJsonObject{ QJsonObject{
@ -403,9 +424,11 @@ QVariantMap UIModel::getDefaultConf() const
{"window", {"window",
QJsonObject{ QJsonObject{
{"disableOverlay", false}, {"disableOverlay", false},
{"hideAltTab", false},
{"maxFps", QJsonValue::Null}, {"maxFps", QJsonValue::Null},
{"scale", QJsonValue::Null}, {"scale", QJsonValue::Null},
{"windowMode", false}, {"windowMode", false},
{"disableGlosSIOverlay", false},
}}, }},
}; };
@ -719,20 +742,33 @@ QString UIModel::getVersionString() const { return QString(version::VERSION_STR)
QString UIModel::getNewVersionName() const { return new_version_name_; } QString UIModel::getNewVersionName() const { return new_version_name_; }
std::filesystem::path UIModel::getSteamPath() const std::filesystem::path UIModel::getSteamPath(bool tryConfig) const
{ {
QVariantMap defaultConf;
if (tryConfig) {
defaultConf = getDefaultConf();
}
try { try {
#ifdef _WIN32 #ifdef _WIN32
// TODO: check if keys/value exist // TODO: check if keys/value exist
// steam should always be open and have written reg values... // steam should always be open and have written reg values...
winreg::RegKey key{HKEY_CURRENT_USER, L"SOFTWARE\\Valve\\Steam"}; winreg::RegKey key{HKEY_CURRENT_USER, L"SOFTWARE\\Valve\\Steam"};
if (!key.IsValid()) { if (!key.IsValid()) {
if (defaultConf.contains("steamPath") &&
QMetaType::canConvert(defaultConf["steamPath"].metaType(), QMetaType(QMetaType::QString))) {
return defaultConf["steamPath"].toString().toStdWString();
}
return ""; return "";
} }
const auto res = key.GetStringValue(L"SteamPath"); const auto res = key.GetStringValue(L"SteamPath");
return res; return res;
} }
catch (...) { catch (...) {
if (defaultConf.contains("steamPath") &&
QMetaType::canConvert(defaultConf["steamPath"].metaType(), QMetaType(QMetaType::QString))) {
return defaultConf["steamPath"].toString().toStdWString();
}
return ""; return "";
} }
#else #else
@ -740,23 +776,39 @@ std::filesystem::path UIModel::getSteamPath() const
#endif #endif
} }
std::wstring UIModel::getSteamUserId() const std::wstring UIModel::getSteamUserId(bool tryConfig) const
{ {
QVariantMap defaultConf;
if (tryConfig) {
defaultConf = getDefaultConf();
}
#ifdef _WIN32 #ifdef _WIN32
try { try {
// TODO: check if keys/value exist // TODO: check if keys/value exist
// steam should always be open and have written reg values... // steam should always be open and have written reg values...
winreg::RegKey key{HKEY_CURRENT_USER, L"SOFTWARE\\Valve\\Steam\\ActiveProcess"}; winreg::RegKey key{HKEY_CURRENT_USER, L"SOFTWARE\\Valve\\Steam\\ActiveProcess"};
if (!key.IsValid()) { if (!key.IsValid()) {
if (defaultConf.contains("steamUserId") &&
QMetaType::canConvert(defaultConf["steamUserId"].metaType(), QMetaType(QMetaType::QString))) {
return defaultConf["steamUserId"].toString().toStdWString();
}
return L"0"; return L"0";
} }
const auto res = std::to_wstring(key.GetDwordValue(L"ActiveUser")); const auto res = std::to_wstring(key.GetDwordValue(L"ActiveUser"));
if (res == L"0") { if (res == L"0") {
qDebug() << "Steam not open?"; qDebug() << "Steam not open?";
if (defaultConf.contains("steamUserId") &&
QMetaType::canConvert(defaultConf["steamUserId"].metaType(), QMetaType(QMetaType::QString))) {
return defaultConf["steamUserId"].toString().toStdWString();
}
} }
return res; return res;
} }
catch (...) { catch (...) {
if (defaultConf.contains("steamUserId") &&
QMetaType::canConvert(defaultConf["steamUserId"].metaType(), QMetaType(QMetaType::QString))) {
return defaultConf["steamUserId"].toString().toStdWString();
}
return L"0"; return L"0";
} }
#else #else
@ -830,3 +882,35 @@ bool UIModel::isSteamInputXboxSupportEnabled() const
} }
return true; return true;
} }
void UIModel::readUnhookBytes() const
{
std::map<std::string, std::string> unhook_bytes;
for (const auto& name : UnhookUtil::UNHOOK_BYTES_ORIGINAL_22000 | std::views::keys) {
auto bytes = UnhookUtil::ReadOriginalBytes(
name,
name.starts_with("Hid")
? L"hid.dll"
: name.starts_with("Setup")
? L"setupapi.dll"
: L"Kernel32.dll"
);
unhook_bytes[name] = bytes;
}
auto path = config_path_;
path /= "unhook_bytes";
QFile file(path);
if (!file.open(QIODevice::Truncate | QIODevice::ReadWrite)) {
qDebug() << "Couldn't open file for writing: " << path;
return;
}
for (const auto& [name, bytes] : unhook_bytes) {
file.write(
QString::fromStdString(name + ":").toStdString().data()
);
file.write(bytes.data(), bytes.size());
file.write("\n");
}
file.close();
}

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -125,10 +125,12 @@ class UIModel : public QObject {
QString getVersionString() const; QString getVersionString() const;
QString getNewVersionName() const; QString getNewVersionName() const;
std::filesystem::path getSteamPath() const; std::filesystem::path getSteamPath(bool tryConfig = true) const;
std::wstring getSteamUserId() const; std::wstring getSteamUserId(bool tryConfig = true) const;
bool foundSteam() const; bool foundSteam() const;
void parseShortcutVDF(); void parseShortcutVDF();
bool isSteamInputXboxSupportEnabled() const; bool isSteamInputXboxSupportEnabled() const;
void readUnhookBytes() const;
}; };

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -140,7 +140,7 @@ CollapsiblePane {
RPane { RPane {
width: parent.width / 2 - 8 width: parent.width / 2 - 8
height: 248 height: 324
radius: 4 radius: 4
Material.elevation: 32 Material.elevation: 32
bgOpacity: 0.97 bgOpacity: 0.97
@ -290,7 +290,7 @@ CollapsiblePane {
} }
RPane { RPane {
width: parent.width / 2 - 8 width: parent.width / 2 - 8
height: 248 height: 324
radius: 4 radius: 4
Material.elevation: 32 Material.elevation: 32
bgOpacity: 0.97 bgOpacity: 0.97
@ -359,6 +359,76 @@ CollapsiblePane {
height: 24 height: 24
} }
} }
}
Item {
width: 1
height: 4
}
Row {
CheckBox {
id: hideAltTabCheckbox
text: qsTr("Hide GlosSI from Windowlist (Alt+Tab)")
checked: shortcutInfo.window.hideAltTab
onCheckedChanged: shortcutInfo.window.hideAltTab = checked
}
RoundButton {
onClicked: () => {
helpInfoDialog.titleText = qsTr("Hide GlosSI from Windowlist (Alt+Tab)")
helpInfoDialog.text =
qsTr("Hides GlosSI from the Windowlist (Alt+Tab)")
+ "\n"
+ qsTr("You can close the GlosSI-Window via the system-tray")
+ "\n"
+ "\n"
+ qsTr("Might help with Steam remote play.")
helpInfoDialog.open()
}
width: 48
height: 48
Material.elevation: 0
anchors.topMargin: 16
Image {
anchors.centerIn: parent
source: "qrc:/svg/help_outline_white_24dp.svg"
width: 24
height: 24
}
}
}
Item {
width: 1
height: 4
}
Row {
CheckBox {
id: disableGlosSIOverlayCheckbox
text: qsTr("Disable GlosSI overlay")
checked: shortcutInfo.window.disableGlosSIOverlay
onCheckedChanged: shortcutInfo.window.disableGlosSIOverlay = checked
}
RoundButton {
onClicked: () => {
helpInfoDialog.titleText = qsTr("Disable GlosSI overlay")
helpInfoDialog.text =
qsTr("Disables the additional GlosSI overlay")
+ "\n"
+ qsTr("but keeps the Steam overlay");
helpInfoDialog.open()
}
width: 48
height: 48
Material.elevation: 0
anchors.topMargin: 16
Image {
anchors.centerIn: parent
source: "qrc:/svg/help_outline_white_24dp.svg"
width: 24
height: 24
}
}
} }
Item { Item {
width: 1 width: 1

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -189,7 +189,7 @@ Dialog {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
spacing: 2 spacing: 2
Label { Label {
text: modelData.InstallLocation.split('/').pop().split('\\').pop() text: modelData.InstallLocation.split('/').pop().split('\\').pop().replace(/([a-z])([A-Z])/g, '$1 $2')
font.pixelSize: 18 font.pixelSize: 18
font.bold: true font.bold: true
} }

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -136,7 +136,11 @@ Item {
id: nameInput id: nameInput
placeholderText: qsTr("...") placeholderText: qsTr("...")
text: shortcutInfo.name text: shortcutInfo.name
onTextChanged: shortcutInfo.name = text onTextChanged: function() {
shortcutInfo.oldName = shortcutInfo.oldName || shortcutInfo.name
shortcutInfo.name = nameInput.text
shortcutInfo = shortcutInfo
}
validator: RegularExpressionValidator { regularExpression: /([0-z]|\s|.)+/gm } validator: RegularExpressionValidator { regularExpression: /([0-z]|\s|.)+/gm }
} }
} }
@ -374,7 +378,7 @@ Item {
id: egsSelectDialog id: egsSelectDialog
onConfirmed: function(modelData) { onConfirmed: function(modelData) {
if (nameInput.text == "") { if (nameInput.text == "") {
nameInput.text = modelData.InstallLocation.split('/').pop().split('\\').pop() nameInput.text = modelData.InstallLocation.split('/').pop().split('\\').pop().replace(/([a-z])([A-Z])/g, '$1 $2')
} }
pathInput.text = "com.epicgames.launcher://apps/" pathInput.text = "com.epicgames.launcher://apps/"
+ modelData.NamespaceId + modelData.NamespaceId

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -492,12 +492,12 @@ Window {
if (windowContent.editedIndex < 0) { if (windowContent.editedIndex < 0) {
uiModel.addTarget(shortcut) uiModel.addTarget(shortcut)
} else { } else {
if (uiModel.isInSteam(shortcut)) { if (uiModel.updateTarget(windowContent.editedIndex, shortcut)) {
if (uiModel.updateTarget(windowContent.editedIndex, shortcut)) { if (uiModel.isInSteam(shortcut) && steamShortcutsChanged == false) {
if (steamShortcutsChanged == false) { steamChangedDialog.open();
steamChangedDialog.open(); }
} } else {
} else { if (uiModel.isInSteam(shortcut)) {
manualInfo = uiModel.manualProps(shortcut); manualInfo = uiModel.manualProps(shortcut);
writeErrorDialog.open(); writeErrorDialog.open();
} }

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -21,7 +21,7 @@ limitations under the License.
#include "AppLauncher.h" #include "AppLauncher.h"
#include "Settings.h" #include "Settings.h"
HttpServer::HttpServer(AppLauncher& app_launcher) : app_launcher_(app_launcher) HttpServer::HttpServer(AppLauncher& app_launcher, std::function<void()> close) : app_launcher_(app_launcher), close_(close)
{ {
} }
@ -62,6 +62,10 @@ void HttpServer::run()
res.set_content(j.dump(), "text/json"); res.set_content(j.dump(), "text/json");
}); });
server_.Post("/quit", [this](const httplib::Request& req, httplib::Response& res) {
close_();
});
server_.Get("/settings", [this](const httplib::Request& req, httplib::Response& res) { server_.Get("/settings", [this](const httplib::Request& req, httplib::Response& res) {
res.set_content(Settings::toJson().dump(), "text/json"); res.set_content(Settings::toJson().dump(), "text/json");
}); });

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -23,7 +23,7 @@ class AppLauncher;
class HttpServer { class HttpServer {
public: public:
explicit HttpServer(AppLauncher& app_launcher); explicit HttpServer(AppLauncher& app_launcher, std::function<void()> close);
void run(); void run();
void stop(); void stop();
@ -34,4 +34,5 @@ class HttpServer {
uint16_t port_ = 8756; uint16_t port_ = 8756;
AppLauncher& app_launcher_; AppLauncher& app_launcher_;
std::function<void()> close_;
}; };

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -182,6 +182,11 @@ void Overlay::update()
} }
} }
if (Settings::window.disableGlosSIOverlay) {
ImGui::SFML::Render(window_);
return;
}
showLogs(0); showLogs(0);
if (enabled_ || force_enable_) { if (enabled_ || force_enable_) {

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -54,6 +54,8 @@ inline struct Window {
int maxFps = 0; int maxFps = 0;
float scale = 0.f; float scale = 0.f;
bool disableOverlay = false; bool disableOverlay = false;
bool hideAltTab = false;
bool disableGlosSIOverlay = false;
} window; } window;
inline struct Controller { inline struct Controller {
@ -69,6 +71,8 @@ inline struct Common {
std::wstring name; std::wstring name;
std::wstring icon; std::wstring icon;
int version; int version;
std::wstring steamPath;
std::wstring steamUserId;
} common; } common;
inline std::filesystem::path settings_path_ = ""; inline std::filesystem::path settings_path_ = "";
@ -189,6 +193,8 @@ inline void Parse(const nlohmann::basic_json<>& json)
safeParseValue(winconf, "maxFps", window.maxFps); safeParseValue(winconf, "maxFps", window.maxFps);
safeParseValue(winconf, "scale", window.scale); safeParseValue(winconf, "scale", window.scale);
safeParseValue(winconf, "disableOverlay", window.disableOverlay); safeParseValue(winconf, "disableOverlay", window.disableOverlay);
safeParseValue(winconf, "hideAltTab", window.hideAltTab);
safeParseValue(winconf, "disableGlosSIOverlay", window.disableGlosSIOverlay);
} }
if (auto controllerConf = json["controller"]; !controllerConf.is_null() && !controllerConf.empty() && controllerConf.is_object()) { if (auto controllerConf = json["controller"]; !controllerConf.is_null() && !controllerConf.empty() && controllerConf.is_object()) {
@ -200,6 +206,9 @@ inline void Parse(const nlohmann::basic_json<>& json)
safeWStringParse(json, "name", common.name); safeWStringParse(json, "name", common.name);
safeWStringParse(json, "icon", common.icon); safeWStringParse(json, "icon", common.icon);
safeParseValue(json, "version", common.version); safeParseValue(json, "version", common.version);
safeWStringParse(json, "steamPath", common.steamPath);
safeWStringParse(json, "steamUserId", common.steamUserId);
} }
catch (const nlohmann::json::exception& e) { catch (const nlohmann::json::exception& e) {
spdlog::warn("Err parsing config: {}", e.what()); spdlog::warn("Err parsing config: {}", e.what());
@ -293,6 +302,7 @@ inline nlohmann::json toJson()
json["window"]["maxFps"] = window.maxFps; json["window"]["maxFps"] = window.maxFps;
json["window"]["scale"] = window.scale; json["window"]["scale"] = window.scale;
json["window"]["disableOverlay"] = window.disableOverlay; json["window"]["disableOverlay"] = window.disableOverlay;
json["window"]["hideAltTab"] = window.hideAltTab;
json["controller"]["maxControllers"] = controller.maxControllers; json["controller"]["maxControllers"] = controller.maxControllers;
json["controller"]["allowDesktopConfig"] = controller.allowDesktopConfig; json["controller"]["allowDesktopConfig"] = controller.allowDesktopConfig;
json["controller"]["emulateDS4"] = controller.emulateDS4; json["controller"]["emulateDS4"] = controller.emulateDS4;

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -46,7 +46,7 @@ SteamTarget::SteamTarget()
delayed_shutdown_ = true; delayed_shutdown_ = true;
delay_shutdown_clock_.restart(); delay_shutdown_clock_.restart();
}), }),
server_(launcher_) server_(launcher_, [this] { run_ = false; })
{ {
target_window_handle_ = window_.getSystemHandle(); target_window_handle_ = window_.getSystemHandle();
#ifdef _WIN32 #ifdef _WIN32
@ -180,6 +180,9 @@ void SteamTarget::onOverlayChanged(bool overlay_open)
void SteamTarget::toggleGlossiOverlay() void SteamTarget::toggleGlossiOverlay()
{ {
if (Settings::window.disableGlosSIOverlay) {
return;
}
if (overlay_.expired()) { if (overlay_.expired()) {
return; return;
} }
@ -253,7 +256,7 @@ std::filesystem::path SteamTarget::getSteamPath() const
catch (const winreg::RegException& e) { catch (const winreg::RegException& e) {
spdlog::error("Couldn't get Steam path from Registry; {}", e.what()); spdlog::error("Couldn't get Steam path from Registry; {}", e.what());
} }
return L""; return Settings::common.steamPath;
#else #else
return L""; // TODO return L""; // TODO
#endif #endif
@ -273,7 +276,7 @@ std::wstring SteamTarget::getSteamUserId() const
catch (const winreg::RegException& e) { catch (const winreg::RegException& e) {
spdlog::error("Couldn't get Steam path from Registry; {}", e.what()); spdlog::error("Couldn't get Steam path from Registry; {}", e.what());
} }
return L""; return Settings::common.steamUserId;
#else #else
return L""; // TODO return L""; // TODO
#endif #endif

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -56,6 +56,11 @@ TargetWindow::TargetWindow(
if (ImGui::Checkbox("Window mode", &Settings::window.windowMode)) { if (ImGui::Checkbox("Window mode", &Settings::window.windowMode)) {
toggle_window_mode_after_frame_ = true; toggle_window_mode_after_frame_ = true;
} }
#ifdef _WIN32
if (ImGui::Checkbox("Hide from Alt+Tab", &Settings::window.hideAltTab)) {
toggle_hidealttab_after_frame_ = true;
}
#endif
ImGui::Text("Max. FPS"); ImGui::Text("Max. FPS");
ImGui::SameLine(); ImGui::SameLine();
int max_fps_copy = Settings::window.maxFps; int max_fps_copy = Settings::window.maxFps;
@ -116,13 +121,30 @@ void TargetWindow::setClickThrough(bool click_through)
} }
#ifdef _WIN32 #ifdef _WIN32
HWND hwnd = window_.getSystemHandle(); HWND hwnd = window_.getSystemHandle();
if (click_through) {
SetWindowLong(hwnd, GWL_EXSTYLE, WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_TOPMOST | WS_EX_COMPOSITED); // hiding GlosSI from Alt-Tab list
SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); // https://learn.microsoft.com/en-us/windows/win32/winmsg/extended-window-styles
if (Settings::window.hideAltTab) {
toggle_hidealttab_after_frame_ = false;
if (click_through) {
SetWindowLong(hwnd, GWL_EXSTYLE, WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_TOPMOST | WS_EX_COMPOSITED | WS_EX_TOOLWINDOW);
SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
}
else {
SetWindowLong(hwnd, GWL_EXSTYLE, WS_EX_LAYERED | WS_EX_COMPOSITED | WS_EX_TOOLWINDOW);
SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
}
} }
else { else {
SetWindowLong(hwnd, GWL_EXSTYLE, WS_EX_LAYERED | WS_EX_COMPOSITED); if (click_through) {
SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); SetWindowLong(hwnd, GWL_EXSTYLE, WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_TOPMOST | WS_EX_COMPOSITED);
SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
}
else {
SetWindowLong(hwnd, GWL_EXSTYLE, WS_EX_LAYERED | WS_EX_COMPOSITED);
SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
}
} }
#endif #endif
} }
@ -142,9 +164,15 @@ void TargetWindow::update()
screenShotWorkaround(); screenShotWorkaround();
overlay_->update(); overlay_->update();
window_.display(); window_.display();
#ifdef _WIN32
if (toggle_hidealttab_after_frame_) {
toggle_hidealttab_after_frame_ = false;
}
#endif
if (toggle_window_mode_after_frame_) { if (toggle_window_mode_after_frame_) {
createWindow(); createWindow();
} }
// As SFML screws us out of most windows-events, just poll resolution every once in a while // As SFML screws us out of most windows-events, just poll resolution every once in a while
// If changed, recreate window. // If changed, recreate window.
// Fixes Blackscreen issues when user does funky stuff and still uses GlosSI in non windowed mod... // Fixes Blackscreen issues when user does funky stuff and still uses GlosSI in non windowed mod...
@ -335,6 +363,7 @@ void TargetWindow::createWindow()
style &= ~WS_OVERLAPPED; style &= ~WS_OVERLAPPED;
style |= WS_POPUP; style |= WS_POPUP;
SetWindowLong(hwnd, GWL_STYLE, style); SetWindowLong(hwnd, GWL_STYLE, style);
MARGINS margins; MARGINS margins;
margins.cxLeftWidth = -1; margins.cxLeftWidth = -1;

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -82,4 +82,5 @@ class TargetWindow {
void createWindow(); void createWindow();
bool toggle_window_mode_after_frame_ = false; bool toggle_window_mode_after_frame_ = false;
bool toggle_hidealttab_after_frame_ = false;
}; };

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -15,12 +15,63 @@ limitations under the License.
*/ */
#include "UnhookUtil.h" #include "UnhookUtil.h"
#ifndef CONFIGAPP
#include <spdlog/spdlog.h> #include <spdlog/spdlog.h>
#include "Settings.h" #include "Settings.h"
#endif
void UnhookUtil::UnPatchHook(const std::string& name, HMODULE module) void UnhookUtil::UnPatchHook(const std::string& name, HMODULE module)
{ {
#ifndef CONFIGAPP
std::map<std::string, std::string> original_bytes_from_file;
wchar_t* localAppDataFolder;
std::filesystem::path configDirPath;
if (SHGetKnownFolderPath(FOLDERID_LocalAppData, KF_FLAG_CREATE, NULL, &localAppDataFolder) != S_OK) {
configDirPath = std::filesystem::temp_directory_path().parent_path().parent_path().parent_path();
}
else {
configDirPath = std::filesystem::path(localAppDataFolder).parent_path();
}
configDirPath /= "Roaming";
configDirPath /= "GlosSI";
if (std::filesystem::exists(configDirPath)) {
auto unhook_file_path = configDirPath / "unhook_bytes";
if (std::filesystem::exists(unhook_file_path)) {
std::ifstream ifile;
ifile.open(unhook_file_path, std::ios::binary | std::ios::in);
if (ifile.is_open()) {
std::string funcName;
char buff;
do {
if (ifile.eof()) {
break;
}
ifile.read(&buff, sizeof(char));
if (buff != ':') {
funcName.push_back(buff);
} else {
char bytes[8];
ifile.read(bytes, sizeof(char) * 8);
ifile.read(&buff, sizeof(char)); // newline
original_bytes_from_file[funcName] = std::string(bytes, 8);
funcName = "";
}
} while (!ifile.eof());
ifile.close();
}
}
}
spdlog::trace("Patching \"{}\"...", name); spdlog::trace("Patching \"{}\"...", name);
BYTE* address = reinterpret_cast<BYTE*>(GetProcAddress(module, name.c_str())); BYTE* address = reinterpret_cast<BYTE*>(GetProcAddress(module, name.c_str()));
@ -28,11 +79,19 @@ void UnhookUtil::UnPatchHook(const std::string& name, HMODULE module)
spdlog::error("failed to unpatch \"{}\"", name); spdlog::error("failed to unpatch \"{}\"", name);
} }
std::string bytes; std::string bytes;
if (Settings::isWin10 && UNHOOK_BYTES_ORIGINAL_WIN10.contains(name)) {
bytes = UNHOOK_BYTES_ORIGINAL_WIN10.at(name); if (original_bytes_from_file.contains(name)) {
bytes = original_bytes_from_file.at(name);
spdlog::trace("Using originalBytes from file for {}", name);
} }
else { else {
bytes = UNHOOK_BYTES_ORIGINAL_22000.at(name); if (Settings::isWin10 && UNHOOK_BYTES_ORIGINAL_WIN10.contains(name)) {
bytes = UNHOOK_BYTES_ORIGINAL_WIN10.at(name);
}
else {
bytes = UNHOOK_BYTES_ORIGINAL_22000.at(name);
}
spdlog::trace("Using fallback originalBytes for {}", name);
} }
DWORD dw_old_protect, dw_bkup; DWORD dw_old_protect, dw_bkup;
const auto len = bytes.size(); const auto len = bytes.size();
@ -52,4 +111,18 @@ void UnhookUtil::UnPatchHook(const std::string& name, HMODULE module)
spdlog::trace("Unpatched \"{}\"", name); spdlog::trace("Unpatched \"{}\"", name);
} }
VirtualProtect(address, len, dw_old_protect, &dw_bkup); // Revert permission change... VirtualProtect(address, len, dw_old_protect, &dw_bkup); // Revert permission change...
#endif
}
std::string UnhookUtil::ReadOriginalBytes(const std::string& name, const std::wstring& moduleName)
{
auto module = LoadLibraryW(moduleName.c_str());
auto address = reinterpret_cast<BYTE*>(GetProcAddress(module, name.c_str()));
std::string res;
res.resize(8);
for (int i = 0; i < 8; i++) {
res[i] = static_cast<char>(*(address + i));
}
return res;
} }

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -25,6 +25,8 @@ limitations under the License.
namespace UnhookUtil { namespace UnhookUtil {
void UnPatchHook(const std::string& name, HMODULE module); void UnPatchHook(const std::string& name, HMODULE module);
std::string ReadOriginalBytes(const std::string& name, const std::wstring& moduleName);
static inline const std::vector<uint8_t> JUMP_INSTR_OPCODES = { static inline const std::vector<uint8_t> JUMP_INSTR_OPCODES = {
0xE9, 0xE9,
0xE8, 0xE8,
@ -34,6 +36,9 @@ static inline const std::vector<uint8_t> JUMP_INSTR_OPCODES = {
// Valve Hooks various functions and hides Gaming devices like this. // Valve Hooks various functions and hides Gaming devices like this.
// To be able to query them, unpatch the hook with the original bytes... // To be able to query them, unpatch the hook with the original bytes...
// Bytes here are just fallbacks; originalbytes will get read from GlosSIConfig and stored in %APPDATA%\GlosSI\unhook_bytes
// 22000 ^= Windows build number // 22000 ^= Windows build number
static inline const std::map<std::string, std::string> UNHOOK_BYTES_ORIGINAL_22000 = { static inline const std::map<std::string, std::string> UNHOOK_BYTES_ORIGINAL_22000 = {
{"SetupDiEnumDeviceInfo", "\x48\x89\x5C\x24\x08"}, {"SetupDiEnumDeviceInfo", "\x48\x89\x5C\x24\x08"},

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -168,8 +168,9 @@ int main(int argc, char* argv[])
auto existingwindow = FindWindowA(nullptr, "GlosSITarget"); auto existingwindow = FindWindowA(nullptr, "GlosSITarget");
if (existingwindow) { if (existingwindow) {
spdlog::error("GlosSITarget is already running!"); spdlog::error("GlosSITarget is already running! Closing old process...");
return 1; httplib::Client client("http://localhost:8756");
client.Post("/quit");
} }
int numArgs; int numArgs;

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

@ -67,7 +67,7 @@ For Building instructions refer to [BUILDING.md](./docs/BUILDING.md)
## License ## License
```license ```license
Copyright 2017-2022 Peter Repukat - FlatspotSoftware Copyright 2017-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

@ -1,5 +1,5 @@
/* /*
Copyright 2021-2022 Peter Repukat - FlatspotSoftware Copyright 2021-2023 Peter Repukat - FlatspotSoftware
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

@ -121,11 +121,11 @@ The GlosSI overlay can also be navigated with controller-inputs
Rename the shortcut in Steam to the Steam-AppID of the game you want to access to community-configs. Rename the shortcut in Steam to the Steam-AppID of the game you want to access to community-configs.
Community configs may only be available **before** you launch the shortcut. Community configs may only be available **before** you launch the shortcut.
AppIDs can be retrieved from [SteamDB](https://steamdb.info/apps/) AppIDs can be retrieved from [SteamDB](https://steamdb.info/apps/) or [Steambase](https://steambase.io/apps)
<details> <details>
<summary>Screenie 📸</summary> <summary>Screenie 📸</summary>
![appid-trick](./appid_trick.png) ![appid-trick](./appid_trick.png)
</details> </details>

Loading…
Cancel
Save