More work on CEFInject / SteamTweaks

pull/239/head
Peter Repukat 1 year ago
parent 4c847543fc
commit cb6cbdeac6

@ -27,6 +27,10 @@ limitations under the License.
#include <fstream>
#include <streambuf>
#include <spdlog/spdlog.h>
#include "../common/Settings.h"
namespace CEFInject
{
namespace internal
@ -34,7 +38,8 @@ namespace CEFInject
httplib::Client GetHttpClient(uint16_t port)
{
httplib::Client cli("localhost", port);
cli.set_connection_timeout(1000);
cli.set_connection_timeout(0, 200000);
cli.set_read_timeout(0, 500000);
return cli;
}
@ -44,8 +49,6 @@ namespace CEFInject
bool CEFDebugAvailable(uint16_t port)
{
auto cli = internal::GetHttpClient(port);
cli.set_connection_timeout(500);
cli.set_read_timeout(500);
if (auto res = cli.Get("/json")) {
if (res->status == 200) {
return true;
@ -64,21 +67,28 @@ namespace CEFInject
return tabs;
}
nlohmann::json::array_t AvailableTabs(uint16_t port)
nlohmann::basic_json<> AvailableTabs(uint16_t port)
{
if (!CEFDebugAvailable()) {
return nlohmann::json::array();
}
//if (Settings::common.extendedLogging)
//{
spdlog::trace("Fetching available Steam CEF tabs");
//}
auto cli = internal::GetHttpClient(port);
if (auto res = cli.Get("/json")) {
if (res->status == 200) {
return nlohmann::json::parse(res->body);
}
}
return nlohmann::json::array();
}
nlohmann::json InjectJs(std::string_view debug_url, std::wstring_view js, uint16_t port)
nlohmann::basic_json<> InjectJs(std::string_view tab_name, std::string_view debug_url, std::wstring_view js, uint16_t port)
{
#ifdef _WIN32
INT rc;
@ -96,43 +106,50 @@ namespace CEFInject
};
if (ws)
{
auto json_payload = nlohmann::json{
{"id", internal::msg_id++},
{"method", "Runtime.evaluate"},
{"params", {
{"userGesture", true},
{"expression", std::wstring{js.data()}}
//{"expression", js}
}}
};
auto payload_string = json_payload.dump();
ws->send(payload_string);
nlohmann::json res = nullptr;
bool exit = false;
while (ws->getReadyState() != easywsclient::WebSocket::CLOSED) {
ws->poll();
ws->dispatch([&ws, &res, &exit](const std::string& message) {
const auto msg = nlohmann::json::parse(message);
try
{
res = msg.at("result").at("result").at("value");
} catch (...){
//
}
try
{
auto json_payload = nlohmann::json{
{"id", internal::msg_id++},
{"method", "Runtime.evaluate"},
{"params", {
{"userGesture", true},
{"expression", std::wstring{js.data()}}
//{"expression", js}
}}
};
auto payload_string = json_payload.dump();
spdlog::debug("Injecting JS into tab: {}, {}; JS: {}", tab_name, debug_url, payload_string);
ws->send(payload_string);
bool exit = false;
while (ws->getReadyState() != easywsclient::WebSocket::CLOSED) {
ws->poll();
ws->dispatch([&ws, &res, &exit](const std::string& message) {
const auto msg = nlohmann::json::parse(message);
try
{
if (res.is_null() && msg.at("result").at("result").at("type").get<std::string>() != "undefined") {
res = nlohmann::json::parse(message);
if (msg.at("result").at("result").at("type").get<std::string>() != "undefined") {
res = msg.at("result").at("result").at("value");
}
} catch (...) {
res = nlohmann::json::parse(message);
}
exit = true;
});
if (exit) {
ws->close();
return res;
catch (...) {
spdlog::error("CEFInject: Error parsing injection-result value: {}", message);
res = msg;
}
exit = true;
});
if (exit) {
ws->close();
return res;
}
}
} catch (...) {
spdlog::error(
"CEFInject: Error injecting JS into tab: {}, {}",
std::string(tab_name.data()),
std::string(debug_url.data()));
}
#ifdef _WIN32
WSACleanup();
@ -145,7 +162,7 @@ namespace CEFInject
return nullptr;
}
nlohmann::json InjectJsByName(std::wstring_view tabname, std::wstring_view js, uint16_t port)
nlohmann::basic_json<> InjectJsByName(std::wstring_view tabname, std::wstring_view js, uint16_t port)
{
auto cli = internal::GetHttpClient(port);
if (auto res = cli.Get("/json")) {
@ -153,7 +170,7 @@ namespace CEFInject
const auto json = nlohmann::json::parse(res->body);
for (const auto& tab : json) {
if (tab["title"].get<std::wstring>().starts_with(tabname)) {
return InjectJs(tab["webSocketDebuggerUrl"].get<std::string>(), js, port);
return InjectJs(tab["title"].get<std::string>(), tab["webSocketDebuggerUrl"].get<std::string>(), js, port);
}
}
}
@ -165,7 +182,7 @@ namespace CEFInject
bool SteamTweaks::injectGlosSITweaks(std::string_view tab_name, uint16_t port)
{
if (tab_name.empty()) {
for (const auto& tn : AvailableTabNames())
for (auto ts = AvailableTabNames(); const auto & tn : ts)
{
// meh!
injectGlosSITweaks(util::string::to_string(tn), port);
@ -181,20 +198,11 @@ namespace CEFInject
return false;
}
auto glossi_path = util::path::getGlosSIDir();
glossi_path /= steam_tweaks_path_;
glossi_path /= "GlosSITweaks.js";
if (!std::filesystem::exists(glossi_path))
if (glossi_tweaks_js_.empty())
{
return false;
}
std::wifstream js_file(glossi_path);
std::wstring glossitweaks_js{ (std::istreambuf_iterator<wchar_t>(js_file)),
std::istreambuf_iterator<wchar_t>() };
if (glossitweaks_js.empty()) {
return false;
if (!readGlosSITweaksJs()) {
return false;
}
}
const auto find_tab = (
@ -212,34 +220,34 @@ namespace CEFInject
return nlohmann::json{};
};
}
if (!info.id.empty())
{
return [&info](const nlohmann::json::array_t& tabList)
{
for (const auto& tab : tabList) {
if (tab["id"].get<std::string>() == info.id) {
return tab;
}
}
return nlohmann::json{};
};
if (!info.id.empty())
{
return [&info](const nlohmann::json::array_t& tabList)
{
for (const auto& tab : tabList) {
if (tab["id"].get<std::string>() == info.id) {
return tab;
}
}
if (!info.webSocketDebuggerUrl.empty())
{
return [&info](const nlohmann::json::array_t& tabList)
{
for (const auto& tab : tabList) {
if (tab["webSocketDebuggerUrl"].get<std::string>() == info.webSocketDebuggerUrl) {
return tab;
}
}
return nlohmann::json{};
};
return nlohmann::json{};
};
}
return nullptr;
}
if (!info.webSocketDebuggerUrl.empty())
{
return [&info](const nlohmann::json::array_t& tabList)
{
for (const auto& tab : tabList) {
if (tab["webSocketDebuggerUrl"].get<std::string>() == info.webSocketDebuggerUrl) {
return tab;
}
}
return nlohmann::json{};
};
}
return nullptr;
}
)();
if (find_tab == nullptr) {
return false;
@ -250,9 +258,13 @@ namespace CEFInject
return false;
}
InjectJs(tab["webSocketDebuggerUrl"].get<std::string>(), glossitweaks_js, port);
glossi_tweaks_injected_map_[tab["id"].get<std::string>()] = true;
return true;
const auto res = InjectJs(tab["title"].get<std::string>(), tab["webSocketDebuggerUrl"].get<std::string>(), glossi_tweaks_js_, port);
if (res.is_boolean() && res.get<bool>()) {
glossi_tweaks_injected_map_[tab["id"].get<std::string>()] = true;
spdlog::trace("CEFInject: GlosSITweaks injected into tab: {}", tab["title"].get<std::string>());
return true;
}
return false;
}
bool SteamTweaks::uninstallTweaks(bool force)
@ -260,16 +272,179 @@ namespace CEFInject
if (!CEFDebugAvailable()) {
return false;
}
auto_inject_ = false;
if (auto_inject_future_.valid()) {
auto_inject_future_.wait();
}
if (glossi_tweaks_injected_map_.empty() && !force) {
return false;
}
for (auto& tab : AvailableTabNames()) {
InjectJsByName(tab, uninstall_glossi_tweaks_js_);
std::vector<std::future<void>> futures;
for (auto ts = AvailableTabs(); auto & tab : ts) {
futures.push_back(std::async(std::launch::async, [this, &tab]()
{
InjectJs(tab["title"].get<std::string>(), tab["webSocketDebuggerUrl"].get<std::string>(), uninstall_glossi_tweaks_js_);
}));
}
for (auto& f : futures)
{
if (f.valid()){
f.wait();
}
}
glossi_tweaks_injected_map_.clear();
return true;
}
void SteamTweaks::update(float elapsed_time)
{
if (!auto_inject_) {
return;
}
using namespace std::chrono_literals;
if (auto_inject_future_.valid() && auto_inject_future_.wait_for(0ms) != std::future_status::ready) {
time_since_last_update_ = 0.0f;
return;
}
time_since_last_update_ += elapsed_time;
if (time_since_last_update_ < update_interval_) {
return;
}
time_since_last_update_ = 0.0f;
spdlog::trace("CEFInject: Starting auto inject GlosSITweaks");
auto_inject_future_ = std::async(std::launch::async, [this]() {
if (js_tweaks_cache_.empty()) [[unlikely]] {
readAvailableTweaks();
}
if (glossi_tweaks_js_.empty()) [[unlikely]]
{
if (!readGlosSITweaksJs()) {
return;
}
}
auto futures = std::vector<std::future<void>>{};
auto tabs = AvailableTabs();
for (auto& tab : tabs) {
if (glossi_tweaks_injected_map_.contains(tab["id"].get<std::string>())) {
continue;
}
glossi_tweaks_injected_map_[tab["id"].get<std::string>()] = true;
futures.push_back(std::async([this, &tab]()
{
InjectJs(tab["title"].get<std::string>(), tab["webSocketDebuggerUrl"].get<std::string>(), glossi_tweaks_js_);
for (auto& [path, js] : js_tweaks_cache_) {
const auto dir_name = path.parent_path().filename();
if (path_tab_map_.contains(dir_name.wstring())) {
if (tab["title"].get<std::string>().starts_with(path_tab_map_.at(dir_name.wstring()))) {
InjectJs(tab["title"].get<std::string>(), tab["webSocketDebuggerUrl"].get<std::string>(), js);
}
}
}
}));
}
for (auto& f : futures)
{
if (f.valid()) {
f.wait();
}
}
spdlog::trace("CEFInject: Auto Inject thread done");
});
}
bool SteamTweaks::isAutoInject() const
{
return auto_inject_;
}
void SteamTweaks::setAutoInject(const bool auto_inject)
{
auto_inject_ = auto_inject;
}
bool SteamTweaks::readGlosSITweaksJs()
{
if (glossi_tweaks_js_.empty())
{
spdlog::trace("CEFInject: Loadings GlosSITweaks.js");
auto glossi_path = util::path::getGlosSIDir();
glossi_path /= steam_tweaks_path_;
glossi_path /= "GlosSITweaks.js";
if (!std::filesystem::exists(glossi_path))
{
spdlog::error("CEFInject: GlosSITweaks.js not found");
return false;
}
std::wifstream js_file(glossi_path);
glossi_tweaks_js_ = { (std::istreambuf_iterator<wchar_t>(js_file)),
std::istreambuf_iterator<wchar_t>() };
if (glossi_tweaks_js_.empty()) {
spdlog::error("CEFInject: GlosSITweaks.js empty?");
return false;
}
js_file.close();
}
return true;
}
void SteamTweaks::readAvailableTweaks(bool builtin)
{
auto tweaks_path = builtin ? util::path::getGlosSIDir() : util::path::getDataDirPath();
spdlog::log(
builtin ? spdlog::level::trace : spdlog::level::debug,
"CEFInject: Loading {} {} {}",
builtin ? "builtin" : "user",
"tweaks from",
tweaks_path.string()
);
tweaks_path /= steam_tweaks_path_;
if (!std::filesystem::exists(tweaks_path))
{
return;
}
auto find_tweak_files = [this](std::wstring_view path, auto&& recurse) -> void
{
for (const auto& dir_file : std::filesystem::directory_iterator(path))
{
if (std::filesystem::is_directory(dir_file))
{
recurse(dir_file.path().wstring(), recurse);
continue;
}
if (std::filesystem::is_regular_file(dir_file) && dir_file.path().extension() == ".js")
{
if (dir_file.path().filename() == "GlosSITweaks.js") {
continue;
}
std::wifstream js_file(dir_file.path());
std::wstring tweaks_js = { (std::istreambuf_iterator<wchar_t>(js_file)),
std::istreambuf_iterator<wchar_t>() };
if (tweaks_js.empty()) {
continue;
}
js_file.close();
js_tweaks_cache_[dir_file.path().wstring()] = tweaks_js;
}
}
};
find_tweak_files(tweaks_path.wstring(), find_tweak_files);
}
}

@ -15,6 +15,7 @@ limitations under the License.
*/
#pragma once
#include <future>
#include <httplib.h>
#include <nlohmann/json.hpp>
@ -31,9 +32,9 @@ namespace CEFInject
}
bool CEFDebugAvailable(uint16_t port = internal::port_);
std::vector<std::wstring> AvailableTabNames(uint16_t port = internal::port_);
nlohmann::json::array_t AvailableTabs(uint16_t port = internal::port_);
nlohmann::json InjectJs(std::string_view debug_url, std::wstring_view js, uint16_t port = internal::port_);
nlohmann::json InjectJsByName(std::wstring_view tabname, std::wstring_view js, uint16_t port = internal::port_);
nlohmann::basic_json<> AvailableTabs(uint16_t port = internal::port_);
nlohmann::basic_json<> InjectJs(std::string_view tab_name, std::string_view debug_url, std::wstring_view js, uint16_t port = internal::port_);
nlohmann::basic_json<> InjectJsByName(std::wstring_view tabname, std::wstring_view js, uint16_t port = internal::port_);
class SteamTweaks
{
@ -48,17 +49,36 @@ namespace CEFInject
};
bool injectGlosSITweaks(std::string_view tab_name, uint16_t port = internal::port_);
bool injectGlosSITweaks(const Tab_Info& info, uint16_t port = internal::port_);
public:
bool uninstallTweaks(bool force = false);
// TODO: Provide API to auto-inject
// TODO: build system to auto inject "user plugins"
void update(float elapsed_time);
[[nodiscard]] bool isAutoInject() const;
void setAutoInject(const bool auto_inject);
private:
bool readGlosSITweaksJs();
void readAvailableTweaks(bool builtin = true);
bool auto_inject_ = false;
static constexpr float update_interval_ = 30.f;
float time_since_last_update_ = update_interval_;
using tab_id = std::string;
std::map<tab_id, bool> glossi_tweaks_injected_map_;
std::future<void> auto_inject_future_;
std::wstring glossi_tweaks_js_;
std::map<std::filesystem::path, std::wstring> js_tweaks_cache_;
using path_name = std::wstring;
using tab_name = std::string;
static inline const std::map<path_name, tab_name> path_tab_map_ = {
{L"SharedContext", "Steam Shared Context"},
{L"Overlay", "HOW TF GET OVERLAY TAB NAME?"}, // TODO: Figure out how to get the overlay tab name
};
static constexpr std::string_view steam_shared_ctx_tab_name_ = "Steam Shared Context";
static constexpr std::string_view steam_tweaks_path_ = "SteamTweaks";
static constexpr std::wstring_view uninstall_glossi_tweaks_js_ = LR"(
(() => {

@ -77,10 +77,10 @@
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<IncludePath>..\deps\cpp-httplib;..\deps\json\include;..\deps\easywsclient;$(IncludePath)</IncludePath>
<IncludePath>..\deps\cpp-httplib;..\deps\json\include;..\deps\easywsclient;..\deps\spdlog\include;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<IncludePath>..\deps\cpp-httplib;..\deps\json\include;..\deps\easywsclient;$(IncludePath)</IncludePath>
<IncludePath>..\deps\cpp-httplib;..\deps\json\include;..\deps\easywsclient;..\deps\spdlog\include;$(IncludePath)</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
@ -120,7 +120,7 @@
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>SPDLOG_WCHAR_TO_UTF8_SUPPORT;SPDLOG_WCHAR_FILENAMES;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_CRT_SECURE_NO_WARNINGS;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
@ -142,7 +142,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>SPDLOG_WCHAR_TO_UTF8_SUPPORT;SPDLOG_WCHAR_FILENAMES;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_CRT_SECURE_NO_WARNINGS;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>

@ -13,6 +13,9 @@ EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UWPOverlayEnablerDLL", "UWPOverlayEnablerDLL\UWPOverlayEnablerDLL.vcxproj", "{50212575-87E2-40AB-87EE-EAED19C8EBB2}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GlosSIWatchdog", "GlosSIWatchdog\GlosSIWatchdog.vcxproj", "{BF273B90-CB69-43C8-9AF6-F3256DAFD41E}"
ProjectSection(ProjectDependencies) = postProject
{74FBA967-AB7E-43EA-B561-3F4821954B3B} = {74FBA967-AB7E-43EA-B561-3F4821954B3B}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CEFInjectLib", "CEFInjectLib\CEFInjectLib.vcxproj", "{74FBA967-AB7E-43EA-B561-3F4821954B3B}"
EndProject
@ -75,7 +78,7 @@ Global
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {789386B6-7D1E-4F9C-BF2E-9B5EDC3BB7C8}
Qt5Version = 6.2.2_msvc2019_64
SolutionGuid = {789386B6-7D1E-4F9C-BF2E-9B5EDC3BB7C8}
EndGlobalSection
EndGlobal

@ -51,8 +51,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,1,2,0030000050130
PRODUCTVERSION 0,1,2,0030000050130
FILEVERSION 0,1,2,0041001700025
PRODUCTVERSION 0,1,2,0041001700025
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -69,12 +69,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "Peter Repukat - FlatspotSoftware"
VALUE "FileDescription", "GlosSI - Config"
VALUE "FileVersion", "0.1.2.0-30-geb5f13f"
VALUE "FileVersion", "0.1.2.0-41-g17b0d25"
VALUE "InternalName", "GlosSIConfig"
VALUE "LegalCopyright", "Copyright (C) 2021 Peter Repukat - FlatspotSoftware"
VALUE "OriginalFilename", "GlosSIConfig.exe"
VALUE "ProductName", "GlosSI"
VALUE "ProductVersion", "0.1.2.0-30-geb5f13f"
VALUE "ProductVersion", "0.1.2.0-41-g17b0d25"
END
END
BLOCK "VarFileInfo"

@ -32,6 +32,12 @@ void HttpServer::run()
auto setCorsHeader = [](httplib::Response& res) {
res.set_header("Access-Control-Allow-Origin", "*");
};
server_.Get("/", [this, &setCorsHeader](const httplib::Request& req, httplib::Response& res) {
res.set_content("", "text/json");
setCorsHeader(res);
});
server_.Get("/launched-pids", [this, &setCorsHeader](const httplib::Request& req, httplib::Response& res) {
const nlohmann::json j = app_launcher_.launchedPids();
res.set_content(j.dump(), "text/json");

@ -51,8 +51,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,1,2,0031000204300
PRODUCTVERSION 0,1,2,0031000204300
FILEVERSION 0,1,2,0041007165813
PRODUCTVERSION 0,1,2,0041007165813
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -69,12 +69,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "Peter Repukat - FlatspotSoftware"
VALUE "FileDescription", "GlosSI - SteamTarget"
VALUE "FileVersion", "0.1.2.0-31-gd2b43ff"
VALUE "FileVersion", "0.1.2.0-41-g7165813"
VALUE "InternalName", "GlosSITarget"
VALUE "LegalCopyright", "Copyright (C) 2021-2022 Peter Repukat - FlatspotSoftware"
VALUE "OriginalFilename", "GlosSITarget.exe"
VALUE "ProductName", "GlosSI"
VALUE "ProductVersion", "0.1.2.0-31-gd2b43ff"
VALUE "ProductVersion", "0.1.2.0-41-g7165813"
END
END
BLOCK "VarFileInfo"

@ -58,6 +58,10 @@ int SteamTarget::run()
if (Settings::common.standaloneModeGameId == L"") {
spdlog::error("No game id set for standalone mode. Controller will use desktop-config!");
}
auto steam_tweaks = CEFInject::SteamTweaks();
steam_tweaks.setAutoInject(true);
if (!overlay_.expired())
overlay_.lock()->setEnabled(false);
std::vector<std::function<void()>> end_frame_callbacks;
@ -116,6 +120,8 @@ int SteamTarget::run()
server_.run();
bool delayed_full_init_1_frame = false;
sf::Clock frame_time_clock;
while (run_) {
if (!fully_initialized_ && can_fully_initialize_ && delayed_full_init_1_frame) {
init_FuckingRenameMe();
@ -130,6 +136,9 @@ int SteamTarget::run()
overlayHotkeyWorkaround();
window_.update();
steam_tweaks.update(frame_time_clock.getElapsedTime().asSeconds());
// Wait on shutdown; User might get confused if window closes to fast if anything with launchApp get's borked.
if (delayed_shutdown_) {
if (delay_shutdown_clock_.getElapsedTime().asSeconds() >= 3) {
@ -145,7 +154,9 @@ int SteamTarget::run()
efc();
}
end_frame_callbacks.clear();
frame_time_clock.restart();
}
steam_tweaks.uninstallTweaks();
tray->exit();
server_.stop();
@ -156,6 +167,7 @@ int SteamTarget::run()
#endif
launcher_.close();
}
return 0;
}

@ -71,10 +71,12 @@
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<IncludePath>..\deps\spdlog\include;..\deps\json\include;..\deps\cpp-httplib;$(IncludePath)</IncludePath>
<IncludePath>..\deps\spdlog\include;..\deps\json\include;..\deps\cpp-httplib;..\CEFInjectLib;$(IncludePath)</IncludePath>
<LibraryPath>..\x64\Debug;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<IncludePath>..\deps\spdlog\include;..\deps\json\include;..\deps\cpp-httplib;$(IncludePath)</IncludePath>
<IncludePath>..\deps\spdlog\include;..\deps\json\include;..\deps\cpp-httplib;..\CEFInjectLib;$(IncludePath)</IncludePath>
<LibraryPath>..\x64\Release;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
@ -119,7 +121,7 @@
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>hid.lib;Cfgmgr32.lib;setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>hid.lib;Cfgmgr32.lib;setupapi.lib;CefInjectLib.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<CustomBuildStep>
<Command>powershell.exe $(SolutionDir)version_help.ps1</Command>
@ -144,7 +146,7 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>hid.lib;Cfgmgr32.lib;setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>hid.lib;Cfgmgr32.lib;setupapi.lib;CefInjectLib.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<CustomBuildStep>
<Outputs>Upading version based on git;%(Outputs)</Outputs>

@ -27,10 +27,13 @@ limitations under the License.
#include <nlohmann/json.hpp>
#include "../version.hpp"
#include "../common/Settings.h"
#include "../common/HidHide.h"
#include <CEFInject.h>
bool IsProcessRunning(DWORD pid)
{
const HANDLE process = OpenProcess(SYNCHRONIZE, FALSE, pid);
@ -116,6 +119,10 @@ DWORD WINAPI watchdog(HMODULE hModule)
HidHide hidhide;
hidhide.disableHidHide();
spdlog::info("Uninstalling GlosSITweaks");
auto steam_tweaks = CEFInject::SteamTweaks();
steam_tweaks.uninstallTweaks(true);
if (Settings::launch.closeOnExit)
{
spdlog::info("Closing launched processes");

@ -3,7 +3,7 @@
!define APP_NAME "GlosSI"
!define COMP_NAME "Peter Repukat - Flatspotsoftware"
!define WEB_SITE "https://glossi.flatspot.pictures/"
!define VERSION "0.1.2.0-31-gd2b43ff"
!define VERSION "0.1.2.0-41-g7165813"
!define COPYRIGHT "Peter Repukat - FlatspotSoftware © 2017-2022"
!define DESCRIPTION "SteamInput compatibility tool"
!define INSTALLER_NAME "GlosSI-Installer.exe"

@ -27,6 +27,7 @@ export default [
dir: 'dist',
sourcemap: "inline",
format: 'iife',
// name: 'GlosSITweaks' // don't use name; don't pollute global namespace
},
plugins: [tsPluginConf],
},
@ -37,6 +38,7 @@ export default [
file: file.replace('src', 'dist').replace(/\.ts$/, '.js'),
sourcemap: "inline",
format: 'iife',
// name: path.basename(file).replace(/\.ts$/, '') // don't use name; don't pollute global namespace
},
plugins: [tsPluginConf],
}

@ -1,4 +1,8 @@
import type { SteamConfig } from './common/util/types';
import { fetchWithTimeout } from './common/util/util';
class SteamTargetApi {
public getSteamSettings(): Promise<SteamConfig> {
return fetch('http://localhost:8756/steam_settings')
@ -8,8 +12,16 @@ class SteamTargetApi {
)
);
}
public getGlosSIActive() {
return fetchWithTimeout('http://localhost:8756/', { timeout: 10000 })
.then(
() => true
).catch((e) => false);
}
}
class GlosSIApiCtor {
public readonly SteamTarget: SteamTargetApi = new SteamTargetApi();
}
@ -51,8 +63,23 @@ const installGlosSIApi = () => {
}
};
window.GlosSITweaks.GlosSI.install();
const glossiCheckInterval = setInterval(() => {
if (window.GlosSIApi) {
window.GlosSIApi.SteamTarget.getGlosSIActive().then((active) => {
if (!active) {
window?.GlosSITweaks?.GlosSI?.uninstall?.();
}
});
return;
}
clearTimeout(glossiCheckInterval)
}, 5000)
};
if (!window.GlosSITweaks || !window.GlosSIApi) {
installGlosSIApi();
}
export default !!window.GlosSITweaks && !!window.GlosSIApi;

@ -4,7 +4,7 @@ import { initTweak } from "../../../common/tweakApi";
const backup: { originalFpsCorner?: number } = {};
initTweak('AnotherTweak', {
initTweak('HideFPSCounter', {
install: async () => {
backup.originalFpsCorner = Number(
((await GlosSIApi.SteamTarget.getSteamSettings()).system as SteamConfig)
@ -13,6 +13,11 @@ initTweak('AnotherTweak', {
SteamClient.Settings.SetInGameOverlayShowFPSCorner(0);
},
uninstall: () => {
console.log('uninstalling HideFPSCounter Tweak. Restoring FPS Counter corner: ', backup.originalFpsCorner);
SteamClient.Settings.SetInGameOverlayShowFPSCorner((backup.originalFpsCorner ?? 0) as 0 | 1 | 2 | 3 | 4);
setTimeout(() => {
// steam might not actually register the setting?! Try again like 10 seconds later... ¯\_(ツ)_/¯
SteamClient.Settings.SetInGameOverlayShowFPSCorner((backup.originalFpsCorner ?? 0) as 0 | 1 | 2 | 3 | 4);
}, 10 * 1000);
}
});

@ -0,0 +1,12 @@
export const fetchWithTimeout = async (input: RequestInfo | URL, init?: RequestInit & { timeout: number }) => {
const { timeout = 8000 } = init || {};
const controller = new AbortController();
const id = setTimeout(() => controller.abort(), timeout);
const response = await fetch(input, {
...(init ||{}),
signal: controller.signal
});
clearTimeout(id);
return response;
}
Loading…
Cancel
Save