mirror of https://github.com/Alia5/GlosSI
commit
2b41208e6f
@ -0,0 +1,41 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "shell",
|
||||
"label": "Build Solution (Debug)",
|
||||
"command": "msbuild.exe",
|
||||
"args": [
|
||||
"GlosSI.sln",
|
||||
"/target:Build",
|
||||
"/p:Configuration=Debug",
|
||||
"/p:Platform=x64"
|
||||
],
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}",
|
||||
},
|
||||
"problemMatcher": ["$msCompile"],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
},
|
||||
},
|
||||
{
|
||||
"type": "shell",
|
||||
"label": "Re-Build Solution (Debug)",
|
||||
"command": "msbuild.exe",
|
||||
"args": [
|
||||
"GlosSI.sln",
|
||||
"/target:Rebuild",
|
||||
"/p:Configuration=Debug",
|
||||
"/p:Platform=x64"
|
||||
],
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}",
|
||||
},
|
||||
"problemMatcher": ["$msCompile"],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Win32",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/**",
|
||||
"${workspaceFolder}/../deps/json/include",
|
||||
"${workspaceFolder}/../deps/cpp-httplib",
|
||||
"${workspaceFolder}/../deps/easywsclient"
|
||||
],
|
||||
"defines": [
|
||||
"_DEBUG",
|
||||
"UNICODE",
|
||||
"_UNICODE",
|
||||
"_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING"
|
||||
],
|
||||
"windowsSdkVersion": "10.0.18362.0",
|
||||
"compilerPath": "C:/Program Files (x86)/Microsoft Visual Studio/2019/BuildTools/VC/Tools/MSVC/14.24.28314/bin/Hostx64/x64/cl.exe",
|
||||
"cStandard": "c11",
|
||||
"cppStandard": "c++20",
|
||||
"intelliSenseMode": "msvc-x64"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "shell",
|
||||
"label": "Build CEFInjectLib (Debug)",
|
||||
"command": "msbuild.exe",
|
||||
"args": [
|
||||
"GlosSI.sln",
|
||||
"/target:CEFInjectLib",
|
||||
"/p:Configuration=Debug",
|
||||
"/p:Platform=x64"
|
||||
],
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/..",
|
||||
|
||||
},
|
||||
"problemMatcher": ["$msCompile"],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
},
|
||||
},
|
||||
{
|
||||
"type": "shell",
|
||||
"label": "Re-Build CEFInjectLib (Debug)",
|
||||
"command": "msbuild.exe",
|
||||
"args": [
|
||||
"GlosSI.sln",
|
||||
"/target:CEFInjectLib:Rebuild",
|
||||
"/p:Configuration=Debug",
|
||||
"/p:Platform=x64"
|
||||
],
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/..",
|
||||
|
||||
},
|
||||
"problemMatcher": ["$msCompile"],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,104 @@
|
||||
/*
|
||||
Copyright 2021-2023 Peter Repukat - FlatspotSoftware
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <future>
|
||||
#include <httplib.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
|
||||
namespace CEFInject
|
||||
{
|
||||
namespace internal {
|
||||
httplib::Client GetHttpClient(uint16_t port);
|
||||
static inline uint16_t port_ = 8080;
|
||||
}
|
||||
inline void setPort(uint16_t port)
|
||||
{
|
||||
internal::port_ = port;
|
||||
}
|
||||
bool CEFDebugAvailable(uint16_t port = internal::port_);
|
||||
std::vector<std::wstring> AvailableTabNames(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 WSAStartupWrap
|
||||
{
|
||||
public:
|
||||
explicit WSAStartupWrap();
|
||||
~WSAStartupWrap();
|
||||
private:
|
||||
bool wsa_startup_succeeded_ = false;
|
||||
};
|
||||
|
||||
class SteamTweaks
|
||||
{
|
||||
public:
|
||||
SteamTweaks() = default;
|
||||
|
||||
struct Tab_Info
|
||||
{
|
||||
std::string name;
|
||||
std::string id;
|
||||
std::string webSocketDebuggerUrl;
|
||||
};
|
||||
bool injectGlosSITweaks(std::string_view tab_name, uint16_t port = internal::port_);
|
||||
bool injectGlosSITweaks(const Tab_Info& info, uint16_t port = internal::port_);
|
||||
bool uninstallTweaks(bool force = false);
|
||||
|
||||
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
|
||||
{L"GamepadUI", "Steam Big Picture Mode"},
|
||||
};
|
||||
|
||||
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"(
|
||||
(() => {
|
||||
return window.GlosSITweaks?.GlosSI?.uninstall();
|
||||
})();
|
||||
)";
|
||||
};
|
||||
|
||||
namespace internal {
|
||||
static WSAStartupWrap wsa_startup_wrap{};
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,165 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="CEFInject.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="CEFInject.cpp" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{74fba967-ab7e-43ea-b561-3f4821954b3b}</ProjectGuid>
|
||||
<RootNamespace>CEFInjectLib</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<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;..\deps\spdlog\include;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>
|
||||
</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>
|
||||
</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<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>
|
||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
|
||||
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>
|
||||
</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<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>
|
||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>
|
||||
</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="CEFInject.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="CEFInject.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -0,0 +1,43 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "shell",
|
||||
"label": "Build GlosSIConfig (Debug)",
|
||||
"command": "msbuild.exe",
|
||||
"args": [
|
||||
"GlosSI.sln",
|
||||
"/target:GlosSIConfig",
|
||||
"/p:Configuration=Debug",
|
||||
"/p:Platform=x64"
|
||||
],
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/..",
|
||||
|
||||
},
|
||||
"problemMatcher": ["$msCompile"],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
},
|
||||
},
|
||||
{
|
||||
"type": "shell",
|
||||
"label": "Re-Build GlosSIConfig (Debug)",
|
||||
"command": "msbuild.exe",
|
||||
"args": [
|
||||
"GlosSI.sln",
|
||||
"/target:GlosSIConfig:Rebuild",
|
||||
"/p:Configuration=Debug",
|
||||
"/p:Platform=x64"
|
||||
],
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/..",
|
||||
|
||||
},
|
||||
"problemMatcher": ["$msCompile"],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,37 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Win32",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/**",
|
||||
"${workspaceFolder}/../deps/SFML/include",
|
||||
"${workspaceFolder}/../deps/WinReg",
|
||||
"${workspaceFolder}/../deps/spdlog/include",
|
||||
"${workspaceFolder}/../deps/ValveFileVDF",
|
||||
"${workspaceFolder}/../deps/subhook",
|
||||
"${workspaceFolder}/../deps/ViGEmClient/include",
|
||||
"${workspaceFolder}/../deps/imgui",
|
||||
"${workspaceFolder}/../deps/imgui-sfml",
|
||||
"${workspaceFolder}/../deps/json/include",
|
||||
"${workspaceFolder}/../deps/traypp/tray/include",
|
||||
"${workspaceFolder}/../deps/cpp-httplib",
|
||||
"${workspaceFolder}/../CEFInjectLib"
|
||||
],
|
||||
"defines": [
|
||||
"_DEBUG",
|
||||
"UNICODE",
|
||||
"_UNICODE",
|
||||
"SPDLOG_WCHAR_TO_UTF8_SUPPORT",
|
||||
"SPDLOG_WCHAR_FILENAMES",
|
||||
"_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING",
|
||||
"SUBHOOK_STATIC"
|
||||
],
|
||||
"windowsSdkVersion": "10.0.18362.0",
|
||||
"compilerPath": "C:/Program Files (x86)/Microsoft Visual Studio/2019/BuildTools/VC/Tools/MSVC/14.24.28314/bin/Hostx64/x64/cl.exe",
|
||||
"cStandard": "c11",
|
||||
"cppStandard": "c++20",
|
||||
"intelliSenseMode": "msvc-x64"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
{
|
||||
"C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools"
|
||||
}
|
@ -1,15 +1,43 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "cmake",
|
||||
"command": "build",
|
||||
"label": "Build",
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"problemMatcher": []
|
||||
}
|
||||
]
|
||||
}
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "shell",
|
||||
"label": "Build GlosSITarget (Debug)",
|
||||
"command": "msbuild.exe",
|
||||
"args": [
|
||||
"GlosSI.sln",
|
||||
"/target:GlosSITarget",
|
||||
"/p:Configuration=Debug",
|
||||
"/p:Platform=x64"
|
||||
],
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/..",
|
||||
|
||||
},
|
||||
"problemMatcher": ["$msCompile"],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
},
|
||||
},
|
||||
{
|
||||
"type": "shell",
|
||||
"label": "Re-Build GlosSITarget (Debug)",
|
||||
"command": "msbuild.exe",
|
||||
"args": [
|
||||
"GlosSI.sln",
|
||||
"/target:GlosSITarget:Rebuild",
|
||||
"/p:Configuration=Debug",
|
||||
"/p:Platform=x64"
|
||||
],
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/..",
|
||||
|
||||
},
|
||||
"problemMatcher": ["$msCompile"],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
#pragma once
|
||||
#include "HttpServer.h"
|
||||
#include "../common/Settings.h"
|
||||
#include "../common/steam_util.h"
|
||||
|
||||
namespace CHTE {
|
||||
|
||||
inline void addEndpoints()
|
||||
{
|
||||
|
||||
HttpServer::AddEndpoint(
|
||||
{"/running",
|
||||
HttpServer::Method::GET,
|
||||
[](const httplib::Request& req, httplib::Response& res) {
|
||||
// TODO: extend this when "passive" running of global mods is implemented
|
||||
res.set_content(nlohmann::json{{"state", nlohmann::json{{"running", true}}}}.dump(), "text/json");
|
||||
}});
|
||||
|
||||
HttpServer::AddEndpoint(
|
||||
{"/settings",
|
||||
HttpServer::Method::GET,
|
||||
[](const httplib::Request& req, httplib::Response& res) {
|
||||
res.set_content(Settings::toJson().dump(), "text/json");
|
||||
},
|
||||
"json"});
|
||||
|
||||
HttpServer::AddEndpoint(
|
||||
{"/steam_settings",
|
||||
HttpServer::Method::GET,
|
||||
[](const httplib::Request& req, httplib::Response& res) {
|
||||
res.set_content(util::steam::getSteamConfig().dump(4), "text/json");
|
||||
},
|
||||
"json"});
|
||||
|
||||
HttpServer::AddEndpoint({
|
||||
"/log",
|
||||
HttpServer::Method::POST,
|
||||
[](const httplib::Request& req, httplib::Response& res) {
|
||||
struct LogEntry {
|
||||
std::string level;
|
||||
std::string message;
|
||||
};
|
||||
auto entry = LogEntry{};
|
||||
try {
|
||||
const nlohmann::json postbody = nlohmann::json::parse(req.body);
|
||||
entry.level = postbody.at("level");
|
||||
entry.message = postbody.at("message");
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
res.status = 401;
|
||||
res.set_content(nlohmann::json{
|
||||
{"code", 401},
|
||||
{"name", "Bad Request"},
|
||||
{"message", e.what()},
|
||||
}
|
||||
.dump(),
|
||||
"text/json");
|
||||
}
|
||||
if (entry.level == "info") {
|
||||
spdlog::info("GlosSITweaks: {}", entry.message);
|
||||
}
|
||||
else if (entry.level == "warn") {
|
||||
spdlog::warn("GlosSITweaks: {}", entry.message);
|
||||
}
|
||||
else if (entry.level == "error") {
|
||||
spdlog::error("GlosSITweaks: {}", entry.message);
|
||||
}
|
||||
else if (entry.level == "debug") {
|
||||
spdlog::debug("GlosSITweaks: {}", entry.message);
|
||||
}
|
||||
else {
|
||||
spdlog::trace("GlosSITweaks: {}", entry.message);
|
||||
}
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
} // namespace CHTE
|
@ -1,331 +0,0 @@
|
||||
/*
|
||||
Copyright 2021-2023 Peter Repukat - FlatspotSoftware
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <fstream>
|
||||
#include <regex>
|
||||
#include <string>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <locale>
|
||||
#include <codecvt>
|
||||
|
||||
#ifdef WIN32
|
||||
#define NOMINMAX
|
||||
#include <Windows.h>
|
||||
#include <ShlObj.h>
|
||||
#include <KnownFolders.h>
|
||||
#endif
|
||||
|
||||
namespace Settings {
|
||||
|
||||
inline struct Launch {
|
||||
bool launch = false;
|
||||
std::wstring launchPath;
|
||||
std::wstring launchAppArgs;
|
||||
bool closeOnExit = true;
|
||||
bool waitForChildProcs = true;
|
||||
bool isUWP = false;
|
||||
bool ignoreLauncher = true;
|
||||
bool killLauncher = false;
|
||||
std::vector<std::wstring> launcherProcesses{};
|
||||
} launch;
|
||||
|
||||
inline struct Devices {
|
||||
bool hideDevices = true;
|
||||
bool realDeviceIds = false;
|
||||
} devices;
|
||||
|
||||
inline struct Window {
|
||||
bool windowMode = false;
|
||||
int maxFps = 0;
|
||||
float scale = 0.f;
|
||||
bool disableOverlay = false;
|
||||
bool hideAltTab = false;
|
||||
bool disableGlosSIOverlay = false;
|
||||
} window;
|
||||
|
||||
inline struct Controller {
|
||||
int maxControllers = 1;
|
||||
bool allowDesktopConfig = false;
|
||||
bool emulateDS4 = false;
|
||||
} controller;
|
||||
|
||||
inline struct Common {
|
||||
bool no_uwp_overlay = false;
|
||||
bool disable_watchdog = false;
|
||||
bool extendedLogging = false;
|
||||
std::wstring name;
|
||||
std::wstring icon;
|
||||
int version;
|
||||
std::wstring steamPath;
|
||||
std::wstring steamUserId;
|
||||
} common;
|
||||
|
||||
inline std::filesystem::path settings_path_ = "";
|
||||
|
||||
inline bool checkIsUwp(const std::wstring& launch_path)
|
||||
{
|
||||
if (launch_path.find(L"://") != std::wstring::npos) {
|
||||
return false;
|
||||
}
|
||||
std::wsmatch m;
|
||||
if (!std::regex_search(launch_path, m, std::wregex(L"^.{1,5}:"))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
inline bool isWin10 = false;
|
||||
|
||||
typedef LONG NTSTATUS, *PNTSTATUS;
|
||||
#define STATUS_SUCCESS (0x00000000)
|
||||
|
||||
typedef NTSTATUS(WINAPI* RtlGetVersionPtr)(PRTL_OSVERSIONINFOW);
|
||||
|
||||
inline RTL_OSVERSIONINFOW GetRealOSVersion()
|
||||
{
|
||||
HMODULE hMod = ::GetModuleHandleW(L"ntdll.dll");
|
||||
if (hMod) {
|
||||
RtlGetVersionPtr fxPtr = (RtlGetVersionPtr)::GetProcAddress(hMod, "RtlGetVersion");
|
||||
if (fxPtr != nullptr) {
|
||||
RTL_OSVERSIONINFOW rovi = {0};
|
||||
rovi.dwOSVersionInfoSize = sizeof(rovi);
|
||||
if (STATUS_SUCCESS == fxPtr(&rovi)) {
|
||||
return rovi;
|
||||
}
|
||||
}
|
||||
}
|
||||
RTL_OSVERSIONINFOW rovi = {0};
|
||||
return rovi;
|
||||
}
|
||||
|
||||
inline void checkWinVer()
|
||||
{
|
||||
auto VN = GetRealOSVersion();
|
||||
isWin10 = VN.dwBuildNumber < 22000;
|
||||
|
||||
if (isWin10) {
|
||||
spdlog::info("Running on Windows 10; Winver: {}.{}.{}", VN.dwMajorVersion, VN.dwMinorVersion, VN.dwBuildNumber);
|
||||
}
|
||||
else {
|
||||
spdlog::info("Running on Windows 11; Winver: {}.{}.{}", VN.dwMajorVersion, VN.dwMinorVersion, VN.dwBuildNumber);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
inline void Parse(const nlohmann::basic_json<>& json)
|
||||
{
|
||||
auto safeParseValue = [](const auto& object, const auto& key, auto& value) {
|
||||
try {
|
||||
if (object.is_null() || object.empty() || object.at(key).empty() || object.at(key).is_null()) {
|
||||
return;
|
||||
}
|
||||
value = object[key];
|
||||
}
|
||||
catch (const nlohmann::json::exception& e) {
|
||||
e.id == 403
|
||||
? spdlog::trace("Err parsing \"{}\"; {}", key, e.what())
|
||||
: spdlog::warn("Err parsing \"{}\"; {}", key, e.what());
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
spdlog::warn("Err parsing \"{}\"; {}", key, e.what());
|
||||
}
|
||||
};
|
||||
|
||||
auto safeWStringParse = [&safeParseValue](const auto& object, const auto& key, std::wstring& value) {
|
||||
std::string meh;
|
||||
safeParseValue(object, key, meh);
|
||||
if (!meh.empty()) {
|
||||
// This assumes that char is utf8 and wchar_t is utf16, which is guaranteed on Windows.
|
||||
value = std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>>().from_bytes(meh);
|
||||
}
|
||||
};
|
||||
|
||||
int version;
|
||||
safeParseValue(json, "version", version);
|
||||
if (version != 1) { // TODO: versioning stuff
|
||||
spdlog::warn("Config version doesn't match application version.");
|
||||
}
|
||||
|
||||
// TODO: make this as much generic as fits in about the same amount of code if one would parse every value separately.
|
||||
try {
|
||||
if (auto launchconf = json["launch"]; !launchconf.is_null() && !launchconf.empty() && launchconf.is_object()) {
|
||||
safeParseValue(launchconf, "launch", launch.launch);
|
||||
safeWStringParse(launchconf, "launchPath", launch.launchPath);
|
||||
safeWStringParse(launchconf, "launchAppArgs", launch.launchAppArgs);
|
||||
safeParseValue(launchconf, "closeOnExit", launch.closeOnExit);
|
||||
safeParseValue(launchconf, "waitForChildProcs", launch.waitForChildProcs);
|
||||
safeParseValue(launchconf, "killLauncher", launch.killLauncher);
|
||||
safeParseValue(launchconf, "ignoreLauncher", launch.ignoreLauncher);
|
||||
|
||||
if (auto launcherProcs = launchconf["launcherProcesses"];
|
||||
!launcherProcs.is_null() && !launcherProcs.empty() && launcherProcs.is_array()) {
|
||||
launch.launcherProcesses.clear();
|
||||
launch.launcherProcesses.reserve(launcherProcs.size());
|
||||
for (auto& proc : launcherProcs) {
|
||||
launch.launcherProcesses.push_back(std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>>().from_bytes(proc));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (auto devconf = json["devices"]; !devconf.is_null() && !devconf.empty() && devconf.is_object()) {
|
||||
safeParseValue(devconf, "hideDevices", devices.hideDevices);
|
||||
safeParseValue(devconf, "realDeviceIds", devices.realDeviceIds);
|
||||
}
|
||||
|
||||
if (auto winconf = json["window"]; !winconf.is_null() && !winconf.empty() && winconf.is_object()) {
|
||||
safeParseValue(winconf, "windowMode", window.windowMode);
|
||||
safeParseValue(winconf, "maxFps", window.maxFps);
|
||||
safeParseValue(winconf, "scale", window.scale);
|
||||
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()) {
|
||||
safeParseValue(controllerConf, "maxControllers", controller.maxControllers);
|
||||
safeParseValue(controllerConf, "allowDesktopConfig", controller.allowDesktopConfig);
|
||||
safeParseValue(controllerConf, "emulateDS4", controller.emulateDS4);
|
||||
}
|
||||
safeParseValue(json, "extendedLogging", common.extendedLogging);
|
||||
safeWStringParse(json, "name", common.name);
|
||||
safeWStringParse(json, "icon", common.icon);
|
||||
safeParseValue(json, "version", common.version);
|
||||
|
||||
safeWStringParse(json, "steamPath", common.steamPath);
|
||||
safeWStringParse(json, "steamUserId", common.steamUserId);
|
||||
}
|
||||
catch (const nlohmann::json::exception& e) {
|
||||
spdlog::warn("Err parsing config: {}", e.what());
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
spdlog::warn("Err parsing config: {}", e.what());
|
||||
}
|
||||
if (launch.launch) {
|
||||
launch.isUWP = checkIsUwp(launch.launchPath);
|
||||
}
|
||||
}
|
||||
|
||||
inline void Parse(const std::vector<std::wstring>& args)
|
||||
{
|
||||
std::wstring configName;
|
||||
for (const auto& arg : args) {
|
||||
if (arg.empty()) {
|
||||
continue;
|
||||
}
|
||||
if (arg == L"-disableuwpoverlay") {
|
||||
common.no_uwp_overlay = true;
|
||||
}
|
||||
else if (arg == L"-disablewatchdog") {
|
||||
common.disable_watchdog = true;
|
||||
}
|
||||
else if (arg == L"-ignorelauncher") {
|
||||
launch.ignoreLauncher = true;
|
||||
}
|
||||
else if (arg == L"-window") {
|
||||
window.windowMode = true;
|
||||
}
|
||||
else {
|
||||
configName += L" " + std::wstring(arg.begin(), arg.end());
|
||||
}
|
||||
}
|
||||
if (!configName.empty()) {
|
||||
if (configName[0] == L' ') {
|
||||
configName.erase(configName.begin());
|
||||
}
|
||||
if (!configName.ends_with(L".json")) {
|
||||
configName += L".json";
|
||||
}
|
||||
}
|
||||
wchar_t* localAppDataFolder;
|
||||
std::filesystem::path path;
|
||||
if (SHGetKnownFolderPath(FOLDERID_LocalAppData, KF_FLAG_CREATE, NULL, &localAppDataFolder) != S_OK) {
|
||||
path = std::filesystem::temp_directory_path().parent_path().parent_path().parent_path();
|
||||
}
|
||||
else {
|
||||
path = std::filesystem::path(localAppDataFolder).parent_path();
|
||||
}
|
||||
|
||||
path /= "Roaming";
|
||||
path /= "GlosSI";
|
||||
if (!configName.empty()) {
|
||||
path /= "Targets";
|
||||
path /= configName;
|
||||
}
|
||||
else {
|
||||
spdlog::info("No config file specified, using default");
|
||||
path /= "default.json";
|
||||
}
|
||||
|
||||
std::ifstream json_file;
|
||||
json_file.open(path);
|
||||
if (!json_file.is_open()) {
|
||||
spdlog::error(L"Couldn't open settings file {}", path.wstring());
|
||||
spdlog::debug(L"Using sane defaults...");
|
||||
return;
|
||||
}
|
||||
settings_path_ = path;
|
||||
const auto& json = nlohmann::json::parse(json_file);
|
||||
Parse(json);
|
||||
|
||||
spdlog::debug("Read config file \"{}\"; config: {}", path.string(), json.dump());
|
||||
json_file.close();
|
||||
}
|
||||
|
||||
inline nlohmann::json toJson()
|
||||
{
|
||||
nlohmann::json json;
|
||||
json["version"] = 1;
|
||||
json["launch"]["launch"] = launch.launch;
|
||||
json["launch"]["launchPath"] = std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>>().to_bytes(launch.launchPath);
|
||||
json["launch"]["launchAppArgs"] = std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>>().to_bytes(launch.launchAppArgs);
|
||||
json["launch"]["closeOnExit"] = launch.closeOnExit;
|
||||
json["launch"]["waitForChildProcs"] = launch.waitForChildProcs;
|
||||
json["devices"]["hideDevices"] = devices.hideDevices;
|
||||
json["devices"]["realDeviceIds"] = devices.realDeviceIds;
|
||||
json["window"]["windowMode"] = window.windowMode;
|
||||
json["window"]["maxFps"] = window.maxFps;
|
||||
json["window"]["scale"] = window.scale;
|
||||
json["window"]["disableOverlay"] = window.disableOverlay;
|
||||
json["window"]["hideAltTab"] = window.hideAltTab;
|
||||
json["controller"]["maxControllers"] = controller.maxControllers;
|
||||
json["controller"]["allowDesktopConfig"] = controller.allowDesktopConfig;
|
||||
json["controller"]["emulateDS4"] = controller.emulateDS4;
|
||||
|
||||
json["extendedLogging"] = common.extendedLogging;
|
||||
json["name"] = std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>>().to_bytes(common.name);
|
||||
json["icon"] = std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>>().to_bytes(common.icon);
|
||||
json["version"] = common.version;
|
||||
return json;
|
||||
}
|
||||
|
||||
inline void StoreSettings()
|
||||
{
|
||||
const auto& json = toJson();
|
||||
|
||||
std::ofstream json_file;
|
||||
json_file.open(settings_path_);
|
||||
if (!json_file.is_open()) {
|
||||
spdlog::error(L"Couldn't open settings file {}", settings_path_.wstring());
|
||||
return;
|
||||
}
|
||||
json_file << json.dump(4);
|
||||
json_file.close();
|
||||
}
|
||||
|
||||
} // namespace Settings
|
@ -1,66 +0,0 @@
|
||||
/*
|
||||
Copyright 2021-2023 Peter Repukat - FlatspotSoftware
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#define NOMINMAX
|
||||
#include <map>
|
||||
#include <Windows.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace UnhookUtil {
|
||||
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 = {
|
||||
0xE9,
|
||||
0xE8,
|
||||
0xEB,
|
||||
0xEA,
|
||||
0xFF};
|
||||
|
||||
// Valve Hooks various functions and hides Gaming devices like this.
|
||||
// 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
|
||||
static inline const std::map<std::string, std::string> UNHOOK_BYTES_ORIGINAL_22000 = {
|
||||
{"SetupDiEnumDeviceInfo", "\x48\x89\x5C\x24\x08"},
|
||||
{"SetupDiGetClassDevsW", "\x48\x89\x5C\x24\x08"},
|
||||
{"HidD_GetPreparsedData", "\x48\x89\x5C\x24\x18"},
|
||||
{"HidP_GetCaps", "\x4C\x8B\xD1\x48\x85\xC9"},
|
||||
{"HidD_GetAttributes", "\x40\x53\x48\x83\xEC"},
|
||||
{"HidD_GetProductString", "\x48\x83\xEC\x48\x48"},
|
||||
{"HidP_GetUsages", "\x4C\x89\x4C\x24\x20"},
|
||||
{"HidP_GetData", "\x4C\x89\x44\x24\x18"},
|
||||
{"HidP_GetValueCaps", "\x48\x83\xEC\x48\x49"},
|
||||
{"HidP_GetUsageValue", "\x40\x53\x55\x56\x48"},
|
||||
{"HidP_GetButtonCaps", "\x48\x83\xEC\x48\x49"},
|
||||
// Valve hooks "CreateProcess" to detect child-processes
|
||||
{"CreateProcessW", "\x4C\x8B\xDC\x48\x83"},
|
||||
};
|
||||
|
||||
// SetupApi.dll is different on Win10 than on Win11
|
||||
static inline const std::map<std::string, std::string> UNHOOK_BYTES_ORIGINAL_WIN10 = {
|
||||
{"SetupDiEnumDeviceInfo", "\x40\x53\x56\x57\x41\x54\x41\x55"},
|
||||
{"SetupDiGetClassDevsW", "\x48\x8B\xC4\x48\x89\x58\x08"},
|
||||
};
|
||||
|
||||
|
||||
} // namespace UnhookUtil
|
@ -1,76 +0,0 @@
|
||||
/*
|
||||
Copyright 2021-2023 Peter Repukat - FlatspotSoftware
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
#pragma once
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define NOMINMAX
|
||||
#include <Windows.h>
|
||||
#include <tlhelp32.h>
|
||||
|
||||
namespace glossi_util {
|
||||
|
||||
inline DWORD PidByName(const std::wstring& name)
|
||||
{
|
||||
PROCESSENTRY32 entry;
|
||||
entry.dwSize = sizeof(PROCESSENTRY32);
|
||||
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
|
||||
if (Process32First(snapshot, &entry) == TRUE) {
|
||||
while (Process32Next(snapshot, &entry) == TRUE) {
|
||||
if (std::wstring(entry.szExeFile).find(name) != std::string::npos) {
|
||||
return entry.th32ProcessID;
|
||||
}
|
||||
}
|
||||
}
|
||||
CloseHandle(snapshot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline std::wstring GetProcName(DWORD pid)
|
||||
{
|
||||
PROCESSENTRY32 processInfo;
|
||||
processInfo.dwSize = sizeof(processInfo);
|
||||
const HANDLE processesSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
|
||||
if (processesSnapshot == INVALID_HANDLE_VALUE) {
|
||||
spdlog::trace("util::GetProcName: can't get a process snapshot");
|
||||
return L"";
|
||||
}
|
||||
|
||||
for (BOOL bok = Process32First(processesSnapshot, &processInfo);
|
||||
bok;
|
||||
bok = Process32Next(processesSnapshot, &processInfo)) {
|
||||
if (pid == processInfo.th32ProcessID) {
|
||||
CloseHandle(processesSnapshot);
|
||||
return processInfo.szExeFile;
|
||||
}
|
||||
}
|
||||
CloseHandle(processesSnapshot);
|
||||
return L"";
|
||||
}
|
||||
|
||||
inline bool KillProcess(DWORD pid)
|
||||
{
|
||||
auto res = true;
|
||||
if (const auto proc = OpenProcess(PROCESS_TERMINATE, FALSE, pid)) {
|
||||
spdlog::debug("Terminating process: {}", pid);
|
||||
res = TerminateProcess(proc, 0);
|
||||
if (!res) {
|
||||
spdlog::error("Failed to terminate process: {}", pid);
|
||||
}
|
||||
CloseHandle(proc);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
} // namespace glossi_util
|
@ -0,0 +1,41 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "shell",
|
||||
"label": "Build GlosSIWatchdog (Debug)",
|
||||
"command": "msbuild.exe",
|
||||
"args": [
|
||||
"GlosSI.sln",
|
||||
"/target:GlosSIWatchdog",
|
||||
"/p:Configuration=Debug",
|
||||
"/p:Platform=x64"
|
||||
],
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/..",
|
||||
},
|
||||
"problemMatcher": ["$msCompile"],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
},
|
||||
},
|
||||
{
|
||||
"type": "shell",
|
||||
"label": "Re-Build GlosSIWatchdog (Debug)",
|
||||
"command": "msbuild.exe",
|
||||
"args": [
|
||||
"GlosSI.sln",
|
||||
"/target:GlosSIWatchdog:Rebuild",
|
||||
"/p:Configuration=Debug",
|
||||
"/p:Platform=x64"
|
||||
],
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/..",
|
||||
},
|
||||
"problemMatcher": ["$msCompile"],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,187 @@
|
||||
module.exports = {
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:@typescript-eslint/eslint-recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'plugin:@typescript-eslint/recommended-requiring-type-checking',
|
||||
],
|
||||
env: {
|
||||
browser: true,
|
||||
node: false
|
||||
},
|
||||
plugins: [
|
||||
'@typescript-eslint',
|
||||
'no-null',
|
||||
'prefer-arrow',
|
||||
'import',
|
||||
],
|
||||
parser: '@typescript-eslint/parser', // Specifies the ESLint parser
|
||||
parserOptions: {
|
||||
ecmaVersion: 2022, // Allows for the parsing of modern ECMAScript features
|
||||
sourceType: 'module',
|
||||
ecmaFeatures: {
|
||||
jsx: false,
|
||||
},
|
||||
project: ['./tsconfig.json'],
|
||||
tsconfigRootDir: __dirname
|
||||
},
|
||||
rules: {
|
||||
'@typescript-eslint/no-namespace': 'off',
|
||||
'@typescript-eslint/ban-types': 'error',
|
||||
'@typescript-eslint/adjacent-overload-signatures': 'error',
|
||||
'@typescript-eslint/array-type': 'error',
|
||||
'@typescript-eslint/consistent-type-definitions': ['error', 'interface'],
|
||||
'@typescript-eslint/no-inferrable-types': 'error',
|
||||
'@typescript-eslint/no-misused-new': 'error',
|
||||
'@typescript-eslint/no-this-alias': 'error',
|
||||
'@typescript-eslint/prefer-for-of': 'error',
|
||||
'@typescript-eslint/prefer-function-type': 'error',
|
||||
'@typescript-eslint/prefer-namespace-keyword': 'error',
|
||||
'no-inner-declarations': 'off', // we have es6blocked scoped functions.
|
||||
'@typescript-eslint/triple-slash-reference': 'error',
|
||||
'@typescript-eslint/type-annotation-spacing': 'error',
|
||||
'@typescript-eslint/unified-signatures': 'error',
|
||||
'@typescript-eslint/no-explicit-any': 'error',
|
||||
'@typescript-eslint/no-unused-vars': 'error',
|
||||
'@typescript-eslint/unbound-method': 'warn',
|
||||
'@typescript-eslint/semi': [
|
||||
'error',
|
||||
'always'
|
||||
],
|
||||
'@typescript-eslint/quotes': [
|
||||
'warn',
|
||||
'single'
|
||||
],
|
||||
'@typescript-eslint/member-delimiter-style': [
|
||||
'error',
|
||||
{
|
||||
'multiline': {
|
||||
'delimiter': 'semi',
|
||||
'requireLast': true
|
||||
},
|
||||
'singleline': {
|
||||
'delimiter': 'semi',
|
||||
'requireLast': false
|
||||
}
|
||||
}
|
||||
],
|
||||
'@typescript-eslint/indent': [
|
||||
'warn',
|
||||
4,
|
||||
{
|
||||
'FunctionDeclaration': {
|
||||
'parameters': 'first'
|
||||
},
|
||||
'FunctionExpression': {
|
||||
'parameters': 'first'
|
||||
},
|
||||
'SwitchCase': 1
|
||||
}
|
||||
],
|
||||
|
||||
'@typescript-eslint/explicit-member-accessibility': [
|
||||
'error',
|
||||
{
|
||||
'accessibility': 'explicit'
|
||||
}
|
||||
],
|
||||
'@typescript-eslint/no-use-before-define': ['error', { 'functions': false }],
|
||||
// "@typescript-eslint/naming-convention": [
|
||||
// "error",
|
||||
// {
|
||||
// "selector": "default",
|
||||
// "format": ["camelCase", "PascalCase"]
|
||||
// },
|
||||
// {
|
||||
// "selector": "variable",
|
||||
// "format": ["camelCase", "UPPER_CASE"]
|
||||
// },
|
||||
// {
|
||||
// "selector": "parameter",
|
||||
// "format": ["camelCase"],
|
||||
// "leadingUnderscore": "allow"
|
||||
// },
|
||||
// {
|
||||
// "selector": "memberLike",
|
||||
// "modifiers": ["private"],
|
||||
// "format": ["camelCase"],
|
||||
// "leadingUnderscore": "require"
|
||||
// },
|
||||
// {
|
||||
// "selector": "typeLike",
|
||||
// "format": ["PascalCase"]
|
||||
// }
|
||||
// ],
|
||||
'no-console': 'off',
|
||||
'no-return-await': 'error',
|
||||
'arrow-body-style': 'error',
|
||||
'arrow-parens': [
|
||||
'error',
|
||||
'always'
|
||||
],
|
||||
'camelcase': ['warn', { "ignoreImports": true }],
|
||||
'comma-dangle': [
|
||||
'error',
|
||||
{
|
||||
'objects': 'never',
|
||||
'arrays': 'never',
|
||||
'functions': 'never'
|
||||
}
|
||||
],
|
||||
'prefer-arrow/prefer-arrow-functions': 'error',
|
||||
'prefer-arrow-callback': 'error',
|
||||
'prefer-const': 'error',
|
||||
'quote-props': [
|
||||
'error',
|
||||
'consistent-as-needed'
|
||||
],
|
||||
'no-var': 'error',
|
||||
'new-parens': 'error',
|
||||
'no-caller': 'error',
|
||||
'no-cond-assign': 'error',
|
||||
'no-debugger': 'error',
|
||||
'no-empty': 'error',
|
||||
'no-eval': 'error',
|
||||
'no-multiple-empty-lines': 'warn',
|
||||
'no-new-wrappers': 'error',
|
||||
'no-redeclare': 'error',
|
||||
'no-shadow': [
|
||||
'error',
|
||||
{
|
||||
'hoist': 'all'
|
||||
}
|
||||
],
|
||||
'no-null/no-null': 'error',
|
||||
'no-throw-literal': 'error',
|
||||
'no-trailing-spaces': 'error',
|
||||
'no-undef-init': 'error',
|
||||
'no-underscore-dangle': 'error',
|
||||
'no-unsafe-finally': 'error',
|
||||
'no-unused-labels': 'error',
|
||||
'spaced-comment': 'error',
|
||||
'use-isnan': 'error',
|
||||
'max-lines': [
|
||||
'error',
|
||||
{
|
||||
'max': 300,
|
||||
'skipBlankLines': true,
|
||||
'skipComments': true
|
||||
}
|
||||
],
|
||||
'max-len': [
|
||||
'warn',
|
||||
{
|
||||
'code': 140
|
||||
}
|
||||
],
|
||||
'dot-notation': 'error',
|
||||
'eqeqeq': 'error',
|
||||
'eol-last': 'error',
|
||||
'linebreak-style': ['error', 'windows'],
|
||||
'block-spacing': ['error', 'always'],
|
||||
'object-curly-spacing': ["error", "always"],
|
||||
'import/no-deprecated': 'warn', // eslint deprecation rule sucks. just wrns on deprecated IMPORTs
|
||||
},
|
||||
settings: {
|
||||
},
|
||||
};
|
@ -0,0 +1,4 @@
|
||||
node_modules/
|
||||
dist/
|
||||
tsconfig.tsbuildinfo
|
||||
.rollup.tscache/
|
@ -0,0 +1 @@
|
||||
19
|
@ -0,0 +1,10 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Attach to Steam CEF",
|
||||
"port": 8080,
|
||||
"request": "attach",
|
||||
"type": "chrome",
|
||||
}
|
||||
]
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "glossi_steamtweaks",
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"clean": "npx rimraf dist .rollup.tscache tsconfig.tsbuildinfo ",
|
||||
"build": "npx rollup -c rollup.config.js",
|
||||
"build:clean": "npm run clean && npm run build",
|
||||
"build:copy": "npx rimraf ../x64/Debug/SteamTweaks && npm run build && cd dist && npx copyfiles -a -V ./**/* ../../x64/Debug/SteamTweaks"
|
||||
},
|
||||
"author": "Peter Repukat - FlatspotSoftware",
|
||||
"license": "Apache-2.0",
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-typescript": "^11.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.49.0",
|
||||
"@typescript-eslint/parser": "^5.49.0",
|
||||
"copyfiles": "^2.4.1",
|
||||
"eslint": "^8.33.0",
|
||||
"eslint-plugin-import": "^2.27.5",
|
||||
"eslint-plugin-no-null": "^1.0.2",
|
||||
"eslint-plugin-prefer-arrow": "^1.2.3",
|
||||
"rollup": "^3.12.0",
|
||||
"typescript": "^4.9.4",
|
||||
"rimraf": "^4.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
import typescript from '@rollup/plugin-typescript';
|
||||
import { readdirSync, lstatSync } from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
const getFileListForDir = (dir) => {
|
||||
return readdirSync(dir).map((file) => {
|
||||
const absolute = path.resolve(dir, file);
|
||||
if (file.endsWith('.ts')) {
|
||||
return absolute;
|
||||
}
|
||||
if (lstatSync(absolute).isDirectory()) {
|
||||
return getFileListForDir(absolute)
|
||||
}
|
||||
}).flat(999);
|
||||
|
||||
}
|
||||
|
||||
|
||||
const tsPluginConf = typescript({
|
||||
cacheDir: '.rollup.tscache'
|
||||
});
|
||||
|
||||
export default [
|
||||
{
|
||||
input: 'src/GlosSITweaks.ts',
|
||||
output: {
|
||||
dir: 'dist',
|
||||
sourcemap: "inline",
|
||||
format: 'iife',
|
||||
// name: 'GlosSITweaks' // don't use name; don't pollute global namespace
|
||||
},
|
||||
plugins: [tsPluginConf],
|
||||
},
|
||||
...getFileListForDir('src/Tweaks').map((file) => {
|
||||
return {
|
||||
input: file,
|
||||
output: {
|
||||
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],
|
||||
}
|
||||
})
|
||||
];
|
@ -0,0 +1,44 @@
|
||||
export interface GlosSISettings {
|
||||
controller: {
|
||||
allowDesktopConfig: boolean;
|
||||
emulateDS4: boolean;
|
||||
maxControllers: number;
|
||||
};
|
||||
devices: {
|
||||
hideDevices: boolean;
|
||||
realDeviceIds: boolean;
|
||||
};
|
||||
extendedLogging: boolean;
|
||||
globalModeGameId: string;
|
||||
globalModeUseGamepadUI: boolean;
|
||||
icon?: string;
|
||||
ignoreEGS: boolean;
|
||||
killEGS: boolean;
|
||||
launch: {
|
||||
closeOnExit: boolean;
|
||||
ignoreLauncher: boolean;
|
||||
killLauncher: boolean;
|
||||
launch: boolean;
|
||||
launchAppArgs?: string;
|
||||
launchPath?: string;
|
||||
launcherProcesses: string[];
|
||||
waitForChildProcs: boolean;
|
||||
};
|
||||
name?: string;
|
||||
snapshotNotify: boolean;
|
||||
standaloneModeGameId: string;
|
||||
standaloneUseGamepadUI: boolean;
|
||||
minimizeSteamGamepadUI: boolean;
|
||||
steamPath: string;
|
||||
steamUserId: string;
|
||||
steamgridApiKey: string;
|
||||
version: number;
|
||||
window: {
|
||||
disableGlosSIOverlay: boolean;
|
||||
disableOverlay: boolean;
|
||||
hideAltTab: boolean;
|
||||
maxFps?: number;
|
||||
scale?: number;
|
||||
windowMode: boolean;
|
||||
};
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
export interface SteamClient {
|
||||
Settings: {
|
||||
// Current stable (As time of commit); Beta does not have this anymore...
|
||||
SetInGameOverlayShowFPSCorner?: (value: 0|1|2|3|4) => void;
|
||||
SetInGameOverlayShowFPSContrast?: (value: boolean) => void;
|
||||
// TODO: find a way to change setting on beta (and soon stable...)
|
||||
};
|
||||
UI: {
|
||||
GetUiMode: () => Promise<SteamUiMode>;
|
||||
SetUiMode: (mode: SteamUiMode) => void;
|
||||
};
|
||||
Window: {
|
||||
Minimize();
|
||||
HideWindow();
|
||||
};
|
||||
}
|
||||
|
||||
export type FullSteamClient = Required<SteamClient>;
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
SteamClient: SteamClient;
|
||||
}
|
||||
// eslint-disable-next-line
|
||||
declare const SteamClient: SteamClient;
|
||||
}
|
@ -0,0 +1,157 @@
|
||||
import type { SteamConfig } from './common/util/types';
|
||||
import { fetchWithTimeout } from './common/util/util';
|
||||
import type { GlosSISettings } from './@types/GlosSISettings';
|
||||
|
||||
|
||||
class SteamTargetApi {
|
||||
|
||||
public static GlosSIActive = true;
|
||||
|
||||
public static readonly ACTIVE_FAIL_THRESHOLD = 2;
|
||||
private activeFailCounter = 0;
|
||||
private static ActiveCheckTimer = 0;
|
||||
|
||||
public constructor() {
|
||||
if (SteamTargetApi.ActiveCheckTimer !== 0) {
|
||||
clearInterval(SteamTargetApi.ActiveCheckTimer);
|
||||
}
|
||||
SteamTargetApi.ActiveCheckTimer = setInterval(() => {
|
||||
void this.getGlosSIActive().then((active) => {
|
||||
if (!active) {
|
||||
this.activeFailCounter++;
|
||||
if (this.activeFailCounter >= SteamTargetApi.ACTIVE_FAIL_THRESHOLD) {
|
||||
window?.GlosSITweaks?.GlosSI?.uninstall?.();
|
||||
}
|
||||
}
|
||||
});
|
||||
}, 666);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
public log(level: string, ...args: any[]) {
|
||||
void fetch('http://localhost:8756/log', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
level,
|
||||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
||||
message: `${args}`
|
||||
})
|
||||
});
|
||||
switch (level) {
|
||||
case 'error':
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
||||
console.error(...args);
|
||||
break;
|
||||
case 'warn':
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
||||
console.warn(...args);
|
||||
break;
|
||||
case 'info':
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
||||
console.info(...args);
|
||||
break;
|
||||
case 'debug':
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
||||
console.debug(...args);
|
||||
break;
|
||||
default:
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
||||
console.log(...args);
|
||||
}
|
||||
}
|
||||
|
||||
public async getGlosSIActive() {
|
||||
return fetchWithTimeout('http://localhost:8756/running', { timeout: 500 })
|
||||
.then(
|
||||
() => {
|
||||
SteamTargetApi.GlosSIActive = true;
|
||||
return true;
|
||||
}
|
||||
).catch(() => {
|
||||
SteamTargetApi.GlosSIActive = false;
|
||||
return false;
|
||||
});
|
||||
}
|
||||
public getSteamSettings(): Promise<SteamConfig> {
|
||||
return fetch('http://localhost:8756/steam_settings')
|
||||
.then(
|
||||
(res) => res.json().then(
|
||||
(json) => (json as SteamConfig).UserLocalConfigStore as SteamConfig
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public getGlosSISettings() {
|
||||
return fetch('http://localhost:8756/settings')
|
||||
.then(
|
||||
(res) => res.json().then(
|
||||
(json) => json as GlosSISettings
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class GlosSIApiCtor {
|
||||
public readonly SteamTarget: SteamTargetApi = new SteamTargetApi();
|
||||
|
||||
}
|
||||
|
||||
interface GlosSITweaks {
|
||||
[tweakName: string]: { readonly install: () => unknown; readonly uninstall?: () => void };
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
GlosSITweaks: GlosSITweaks;
|
||||
GlosSIApi: InstanceType<typeof GlosSIApiCtor>;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line
|
||||
const GlosSIApi: InstanceType<typeof GlosSIApiCtor>;
|
||||
// eslint-disable-next-line
|
||||
const GlosSITweaks: GlosSITweaks;
|
||||
}
|
||||
|
||||
const installGlosSIApi = () => {
|
||||
window.GlosSITweaks = {
|
||||
GlosSI: {
|
||||
install: () => {
|
||||
const api = new GlosSIApiCtor();
|
||||
Object.assign(window, { GlosSIApi: api });
|
||||
},
|
||||
uninstall: () => {
|
||||
Object.entries(window.GlosSITweaks)
|
||||
.filter(([tweakName]) => (tweakName !== 'GlosSI'))
|
||||
.forEach(([, obj]) => obj.uninstall?.());
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
delete window.GlosSIApi;
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
delete window.GlosSITweaks;
|
||||
}
|
||||
}
|
||||
};
|
||||
window.GlosSITweaks.GlosSI.install();
|
||||
|
||||
const glossiCheckInterval = setInterval(() => {
|
||||
if (window.GlosSIApi) {
|
||||
void 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;
|
@ -0,0 +1,21 @@
|
||||
import { initTweak } from '../../common/tweakApi';
|
||||
|
||||
|
||||
initTweak('MinimizeSteamGamepadUI', async () => {
|
||||
|
||||
const [isGamepadUI, minimizeGPUI] = await Promise.all([
|
||||
// (async () => (await SteamClient.UI.GetUiMode()) === SteamUiMode.GamepadUI)(),
|
||||
true, // Steam is always GamepadUI if injected into GamepadUI, duh!
|
||||
(async () => (await GlosSIApi.SteamTarget.getGlosSISettings()).minimizeSteamGamepadUI)()
|
||||
]);
|
||||
if (isGamepadUI && minimizeGPUI) {
|
||||
SteamClient.Window.Minimize();
|
||||
return true;
|
||||
}
|
||||
if (!isGamepadUI && minimizeGPUI) {
|
||||
GlosSIApi.SteamTarget.log('warn', 'MinimizeSteamGamepadUI is enabled but Steam is not in GamepadUI mode');
|
||||
}
|
||||
return false;
|
||||
}).then((minimized: boolean) => {
|
||||
GlosSIApi.SteamTarget.log('debug', 'MinimizeSteamGamepadUI installed; Minimized GamepadUI:', minimized);
|
||||
}).catch((e) =>GlosSIApi.SteamTarget.log('error', 'MinimizeSteamGamepadUI failed to install', e));
|
@ -0,0 +1,33 @@
|
||||
import type { SteamConfig } from '../../../common/util/types';
|
||||
import { initTweak } from '../../../common/tweakApi';
|
||||
|
||||
|
||||
const backup: { originalFpsCorner?: number } = {};
|
||||
initTweak('HideFPSCounter', {
|
||||
install: async () => {
|
||||
backup.originalFpsCorner = Number(
|
||||
((await GlosSIApi.SteamTarget.getSteamSettings()).system as SteamConfig)
|
||||
.InGameOverlayShowFPSCorner
|
||||
) as 0 | 1 | 2 | 3 | 4;
|
||||
if (!SteamClient.Settings.SetInGameOverlayShowFPSCorner) {
|
||||
GlosSIApi.SteamTarget.log('warn',
|
||||
'HideFPSCounter: SteamClient.Settings.SetInGameOverlayShowFPSCorner is not available.'
|
||||
+'Can\'t hide FPS Counter corner.'
|
||||
);
|
||||
}
|
||||
SteamClient.Settings.SetInGameOverlayShowFPSCorner?.(0);
|
||||
},
|
||||
uninstall: () => {
|
||||
if (!SteamClient.Settings.SetInGameOverlayShowFPSCorner) {
|
||||
return;
|
||||
}
|
||||
GlosSIApi.SteamTarget.log('debug','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);
|
||||
}
|
||||
}).then(() => {
|
||||
GlosSIApi.SteamTarget.log('debug', 'HideFPSCounter installed');
|
||||
}).catch((e) => GlosSIApi.SteamTarget.log('error', 'HideFPSCounter failed to install', e));
|
@ -0,0 +1,8 @@
|
||||
// eslint-disable-next-line no-shadow
|
||||
export enum SteamUiMode {
|
||||
Desktop = 0,
|
||||
Unknown1 = 1,
|
||||
Unknown2 = 2,
|
||||
Unknown3 = 3,
|
||||
GamepadUI = 4,
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
|
||||
export const initTweak = <T>(name: string, tweakMain: (() => T)|{
|
||||
install: () => T;
|
||||
uninstall: () => void;
|
||||
}, force = false): T => {
|
||||
if (!force && window.GlosSITweaks[name]) {
|
||||
throw new Error(`Tweak ${name} is already installed!`);
|
||||
}
|
||||
|
||||
if (typeof tweakMain === 'object') {
|
||||
window.GlosSITweaks[name] = { install: tweakMain.install, uninstall: () => {
|
||||
try {
|
||||
tweakMain.uninstall();
|
||||
} catch (e) {
|
||||
GlosSIApi.SteamTarget.log('error', e);
|
||||
}
|
||||
delete window.GlosSITweaks[name];
|
||||
} };
|
||||
} else {
|
||||
window.GlosSITweaks[name] = { install: tweakMain };
|
||||
}
|
||||
try {
|
||||
return window.GlosSITweaks[name].install() as T;
|
||||
} catch (e) {
|
||||
GlosSIApi.SteamTarget.log('error', e);
|
||||
throw e;
|
||||
}
|
||||
|
||||
};
|
@ -0,0 +1,3 @@
|
||||
export interface SteamConfig {
|
||||
[key: string]: string|SteamConfig;
|
||||
}
|
@ -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;
|
||||
};
|
@ -0,0 +1,26 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"module": "ES2022",
|
||||
"noImplicitAny": true,
|
||||
"rootDir": "./src",
|
||||
"outDir": "./dist",
|
||||
"inlineSourceMap": true,
|
||||
"esModuleInterop": true,
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"useDefineForClassFields": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"incremental": true,
|
||||
"lib": [
|
||||
"esnext",
|
||||
"DOM"
|
||||
],
|
||||
},
|
||||
"include": [
|
||||
"src/**/*"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
]
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "shell",
|
||||
"label": "Build UWPOverlayEnablerDLL (Debug)",
|
||||
"command": "msbuild.exe",
|
||||
"args": [
|
||||
"GlosSI.sln",
|
||||
"/target:UWPOverlayEnablerDLL",
|
||||
"/p:Configuration=Debug",
|
||||
"/p:Platform=x64"
|
||||
],
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/..",
|
||||
},
|
||||
"problemMatcher": ["$msCompile"],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
},
|
||||
},
|
||||
{
|
||||
"type": "shell",
|
||||
"label": "Re-Build UWPOverlayEnablerDLL (Debug)",
|
||||
"command": "msbuild.exe",
|
||||
"args": [
|
||||
"GlosSI.sln",
|
||||
"/target:UWPOverlayEnablerDLL:Rebuild",
|
||||
"/p:Configuration=Debug",
|
||||
"/p:Platform=x64"
|
||||
],
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/..",
|
||||
},
|
||||
"problemMatcher": ["$msCompile"],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Win32",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/**",
|
||||
"${workspaceFolder}/../deps/SFML/include",
|
||||
"${workspaceFolder}/../deps/WinReg",
|
||||
"${workspaceFolder}/../deps/spdlog/include",
|
||||
"${workspaceFolder}/../deps/ValveFileVDF",
|
||||
"${workspaceFolder}/../deps/subhook",
|
||||
"${workspaceFolder}/../deps/ViGEmClient/include",
|
||||
"${workspaceFolder}/../deps/imgui",
|
||||
"${workspaceFolder}/../deps/imgui-sfml",
|
||||
"${workspaceFolder}/../deps/json/include",
|
||||
"${workspaceFolder}/../deps/traypp/tray/include",
|
||||
"${workspaceFolder}/../deps/cpp-httplib",
|
||||
"${workspaceFolder}/../CEFInjectLib"
|
||||
],
|
||||
"defines": [
|
||||
"_DEBUG",
|
||||
"UNICODE",
|
||||
"_UNICODE"
|
||||
],
|
||||
"windowsSdkVersion": "10.0.18362.0",
|
||||
"compilerPath": "C:/Program Files (x86)/Microsoft Visual Studio/2019/BuildTools/VC/Tools/MSVC/14.24.28314/bin/Hostx64/x64/cl.exe",
|
||||
"cStandard": "c11",
|
||||
"cppStandard": "c++20",
|
||||
"intelliSenseMode": "msvc-x64"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
@ -0,0 +1,379 @@
|
||||
/*
|
||||
Copyright 2021-2023 Peter Repukat - FlatspotSoftware
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#define SPDLOG_WCHAR_TO_UTF8_SUPPORT
|
||||
#define SPDLOG_WCHAR_FILENAMES
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <fstream>
|
||||
#include <regex>
|
||||
#include <string>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#ifdef WIN32
|
||||
#define NOMINMAX
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
#include "../common/nlohmann_json_wstring.h"
|
||||
#include "../common/util.h"
|
||||
|
||||
namespace Settings
|
||||
{
|
||||
|
||||
inline struct Launch
|
||||
{
|
||||
bool launch = false;
|
||||
std::wstring launchPath;
|
||||
std::wstring launchAppArgs;
|
||||
bool closeOnExit = true;
|
||||
bool waitForChildProcs = true;
|
||||
bool isUWP = false;
|
||||
bool ignoreLauncher = true;
|
||||
bool killLauncher = false;
|
||||
std::vector<std::wstring> launcherProcesses{};
|
||||
} launch;
|
||||
|
||||
inline struct Devices
|
||||
{
|
||||
bool hideDevices = true;
|
||||
bool realDeviceIds = false;
|
||||
} devices;
|
||||
|
||||
inline struct Window
|
||||
{
|
||||
bool windowMode = false;
|
||||
int maxFps = 0;
|
||||
float scale = 0.f;
|
||||
bool disableOverlay = false;
|
||||
bool hideAltTab = true;
|
||||
bool disableGlosSIOverlay = false;
|
||||
bool opaqueSteamOverlay = false;
|
||||
} window;
|
||||
|
||||
inline struct Controller
|
||||
{
|
||||
int maxControllers = -1;
|
||||
bool allowDesktopConfig = false;
|
||||
bool emulateDS4 = false;
|
||||
unsigned int updateRate = 144;
|
||||
} controller;
|
||||
|
||||
inline struct Common
|
||||
{
|
||||
bool no_uwp_overlay = false;
|
||||
bool disable_watchdog = false;
|
||||
bool extendedLogging = false;
|
||||
std::wstring name;
|
||||
std::wstring icon;
|
||||
int version;
|
||||
std::wstring steamPath;
|
||||
std::wstring steamUserId;
|
||||
std::wstring globalModeGameId; /* = L"12605636929694728192"; */
|
||||
bool globalModeUseGamepadUI = false;
|
||||
bool allowGlobalMode = true;
|
||||
bool minimizeSteamGamepadUI = true;
|
||||
} common;
|
||||
|
||||
inline const std::map<std::wstring, std::function<void()>> cmd_args = {
|
||||
{L"-disableuwpoverlay", [&]()
|
||||
{ common.no_uwp_overlay = true; }},
|
||||
{L"-disablewatchdog", [&]()
|
||||
{ common.disable_watchdog = true; }},
|
||||
{L"-ignorelauncher", [&]()
|
||||
{ launch.ignoreLauncher = true; }},
|
||||
{L"-window", [&]()
|
||||
{ window.windowMode = true; }},
|
||||
{L"-extendedLogging", [&]()
|
||||
{ common.extendedLogging = true; }},
|
||||
{L"-globalModeUseGamepadUI", [&]()
|
||||
{ common.globalModeUseGamepadUI = true; }},
|
||||
{L"-disallowGlobalMode", [&]()
|
||||
{ common.allowGlobalMode = false; }},
|
||||
};
|
||||
|
||||
inline std::filesystem::path settings_path_ = "";
|
||||
|
||||
inline bool checkIsUwp(const std::wstring &launch_path)
|
||||
{
|
||||
if (launch_path.find(L"://") != std::wstring::npos)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
std::wsmatch m;
|
||||
if (!std::regex_search(launch_path, m, std::wregex(L"^.{1,5}:")))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
inline bool isWin10 = false;
|
||||
|
||||
inline void checkWinVer()
|
||||
{
|
||||
auto VN = util::win::GetRealOSVersion();
|
||||
isWin10 = VN.dwBuildNumber < 22000;
|
||||
|
||||
if (isWin10)
|
||||
{
|
||||
spdlog::info("Running on Windows 10; Winver: {}.{}.{}", VN.dwMajorVersion, VN.dwMinorVersion, VN.dwBuildNumber);
|
||||
}
|
||||
else
|
||||
{
|
||||
spdlog::info("Running on Windows 11; Winver: {}.{}.{}", VN.dwMajorVersion, VN.dwMinorVersion, VN.dwBuildNumber);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
inline void Parse(const nlohmann::basic_json<> &json)
|
||||
{
|
||||
constexpr auto safeParseValue = []<typename T>(const auto &object, const auto &key, T &value)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (object.is_null() || object.empty() || object.at(key).empty() || object.at(key).is_null())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if constexpr (std::is_same_v<T, std::wstring>)
|
||||
{
|
||||
value = util::string::to_wstring(object[key].get<std::string>());
|
||||
}
|
||||
else
|
||||
{
|
||||
value = object[key];
|
||||
}
|
||||
}
|
||||
catch (const nlohmann::json::exception &e)
|
||||
{
|
||||
e.id == 403
|
||||
? spdlog::trace("Err parsing \"{}\"; {}", key, e.what())
|
||||
: spdlog::warn("Err parsing \"{}\"; {}", key, e.what());
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
spdlog::warn("Err parsing \"{}\"; {}", key, e.what());
|
||||
}
|
||||
};
|
||||
|
||||
int version;
|
||||
safeParseValue(json, "version", version);
|
||||
if (version != 1)
|
||||
{ // TODO: versioning stuff
|
||||
spdlog::warn("Config version doesn't match application version.");
|
||||
}
|
||||
|
||||
// TODO: make this as much generic as fits in about the same amount of code if one would parse every value separately.
|
||||
try
|
||||
{
|
||||
if (const auto launchconf = json["launch"]; !launchconf.is_null() && !launchconf.empty() && launchconf.is_object())
|
||||
{
|
||||
safeParseValue(launchconf, "launch", launch.launch);
|
||||
safeParseValue(launchconf, "launchPath", launch.launchPath);
|
||||
safeParseValue(launchconf, "launchAppArgs", launch.launchAppArgs);
|
||||
safeParseValue(launchconf, "closeOnExit", launch.closeOnExit);
|
||||
safeParseValue(launchconf, "waitForChildProcs", launch.waitForChildProcs);
|
||||
safeParseValue(launchconf, "killLauncher", launch.killLauncher);
|
||||
safeParseValue(launchconf, "ignoreLauncher", launch.ignoreLauncher);
|
||||
|
||||
if (launchconf.contains("launcherProcesses") && launchconf["launcherProcesses"].is_array())
|
||||
{
|
||||
if (const auto launcherProcs = launchconf["launcherProcesses"];
|
||||
!launcherProcs.is_null() && !launcherProcs.empty() && launcherProcs.is_array())
|
||||
{
|
||||
launch.launcherProcesses.clear();
|
||||
launch.launcherProcesses.reserve(launcherProcs.size());
|
||||
for (auto &proc : launcherProcs)
|
||||
{
|
||||
launch.launcherProcesses.push_back(util::string::to_wstring(proc));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (const auto devconf = json["devices"]; !devconf.is_null() && !devconf.empty() && devconf.is_object())
|
||||
{
|
||||
safeParseValue(devconf, "hideDevices", devices.hideDevices);
|
||||
safeParseValue(devconf, "realDeviceIds", devices.realDeviceIds);
|
||||
}
|
||||
|
||||
if (const auto winconf = json["window"]; !winconf.is_null() && !winconf.empty() && winconf.is_object())
|
||||
{
|
||||
safeParseValue(winconf, "windowMode", window.windowMode);
|
||||
safeParseValue(winconf, "maxFps", window.maxFps);
|
||||
safeParseValue(winconf, "scale", window.scale);
|
||||
safeParseValue(winconf, "disableOverlay", window.disableOverlay);
|
||||
safeParseValue(winconf, "hideAltTab", window.hideAltTab);
|
||||
safeParseValue(winconf, "disableGlosSIOverlay", window.disableGlosSIOverlay);
|
||||
safeParseValue(winconf, "opaqueSteamOverlay", window.opaqueSteamOverlay);
|
||||
}
|
||||
|
||||
if (const auto controllerConf = json["controller"]; !controllerConf.is_null() && !controllerConf.empty() && controllerConf.is_object())
|
||||
{
|
||||
safeParseValue(controllerConf, "maxControllers", controller.maxControllers);
|
||||
safeParseValue(controllerConf, "allowDesktopConfig", controller.allowDesktopConfig);
|
||||
safeParseValue(controllerConf, "emulateDS4", controller.emulateDS4);
|
||||
safeParseValue(controllerConf, "updateRate", controller.updateRate);
|
||||
}
|
||||
safeParseValue(json, "extendedLogging", common.extendedLogging);
|
||||
safeParseValue(json, "name", common.name);
|
||||
safeParseValue(json, "icon", common.icon);
|
||||
safeParseValue(json, "version", common.version);
|
||||
|
||||
safeParseValue(json, "steamPath", common.steamPath);
|
||||
safeParseValue(json, "steamUserId", common.steamUserId);
|
||||
|
||||
safeParseValue(json, "globalModeGameId", common.globalModeGameId);
|
||||
safeParseValue(json, "globalModeUseGamepadUI", common.globalModeUseGamepadUI);
|
||||
safeParseValue(json, "minimizeSteamGamepadUI", common.minimizeSteamGamepadUI);
|
||||
}
|
||||
catch (const nlohmann::json::exception &e)
|
||||
{
|
||||
spdlog::warn("Err parsing config: {}", e.what());
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
spdlog::warn("Err parsing config: {}", e.what());
|
||||
}
|
||||
if (launch.launch)
|
||||
{
|
||||
launch.isUWP = checkIsUwp(launch.launchPath);
|
||||
}
|
||||
}
|
||||
|
||||
inline void Parse(const std::vector<std::wstring> &args)
|
||||
{
|
||||
std::wstring configName;
|
||||
std::vector<std::function<void()>> cli_overrides;
|
||||
for (const auto &arg : args)
|
||||
{
|
||||
if (arg.empty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (cmd_args.contains(arg))
|
||||
{
|
||||
cli_overrides.push_back(cmd_args.at(arg));
|
||||
}
|
||||
else
|
||||
{
|
||||
configName += L" " + std::wstring(arg.begin(), arg.end());
|
||||
}
|
||||
}
|
||||
if (!configName.empty())
|
||||
{
|
||||
if (configName[0] == L' ')
|
||||
{
|
||||
configName.erase(configName.begin());
|
||||
}
|
||||
if (!configName.ends_with(L".json"))
|
||||
{
|
||||
configName += L".json";
|
||||
}
|
||||
}
|
||||
auto path = util::path::getDataDirPath();
|
||||
if (!configName.empty())
|
||||
{
|
||||
path /= "Targets";
|
||||
path /= configName;
|
||||
}
|
||||
else
|
||||
{
|
||||
spdlog::info("No config file specified, using default");
|
||||
path /= "default.json";
|
||||
}
|
||||
|
||||
std::ifstream json_file;
|
||||
json_file.open(path);
|
||||
if (!json_file.is_open())
|
||||
{
|
||||
spdlog::error(L"Couldn't open settings file {}", path.wstring());
|
||||
spdlog::debug(L"Using sane defaults...");
|
||||
for (const auto &ovr : cli_overrides)
|
||||
{
|
||||
ovr();
|
||||
}
|
||||
return;
|
||||
}
|
||||
settings_path_ = path;
|
||||
const auto &json = nlohmann::json::parse(json_file);
|
||||
Parse(json);
|
||||
|
||||
for (const auto &ovr : cli_overrides)
|
||||
{
|
||||
ovr();
|
||||
}
|
||||
spdlog::debug("Read config file \"{}\"; config: {}", path.string(), json.dump());
|
||||
json_file.close();
|
||||
}
|
||||
|
||||
inline nlohmann::json toJson()
|
||||
{
|
||||
nlohmann::json json;
|
||||
json["version"] = 1;
|
||||
json["launch"]["launch"] = launch.launch;
|
||||
json["launch"]["launchPath"] = launch.launchPath;
|
||||
json["launch"]["launchAppArgs"] = launch.launchAppArgs;
|
||||
json["launch"]["closeOnExit"] = launch.closeOnExit;
|
||||
json["launch"]["waitForChildProcs"] = launch.waitForChildProcs;
|
||||
json["devices"]["hideDevices"] = devices.hideDevices;
|
||||
json["devices"]["realDeviceIds"] = devices.realDeviceIds;
|
||||
json["window"]["windowMode"] = window.windowMode;
|
||||
json["window"]["maxFps"] = window.maxFps;
|
||||
json["window"]["scale"] = window.scale;
|
||||
json["window"]["disableOverlay"] = window.disableOverlay;
|
||||
json["window"]["hideAltTab"] = window.hideAltTab;
|
||||
json["window"]["opaqueSteamOverlay"] = window.opaqueSteamOverlay;
|
||||
json["controller"]["maxControllers"] = controller.maxControllers;
|
||||
json["controller"]["allowDesktopConfig"] = controller.allowDesktopConfig;
|
||||
json["controller"]["emulateDS4"] = controller.emulateDS4;
|
||||
json["controller"]["updateRate"] = controller.updateRate;
|
||||
|
||||
|
||||
json["globalModeGameId"] = common.globalModeGameId;;
|
||||
json["globalModeUseGamepadUI"] = common.globalModeUseGamepadUI;
|
||||
json["minimizeSteamGamepadUI"] = common.minimizeSteamGamepadUI;
|
||||
|
||||
// json["steamgridApiKey"] = common.steamgridApiKey;
|
||||
|
||||
json["steamPath"] = common.steamPath;
|
||||
json["steamUserId"] = common.steamUserId;
|
||||
|
||||
json["extendedLogging"] = common.extendedLogging;
|
||||
json["name"] = common.name;
|
||||
json["icon"] = common.icon;
|
||||
json["version"] = common.version;
|
||||
return json;
|
||||
}
|
||||
|
||||
inline void StoreSettings()
|
||||
{
|
||||
const auto &json = toJson();
|
||||
|
||||
std::ofstream json_file;
|
||||
json_file.open(settings_path_);
|
||||
if (!json_file.is_open())
|
||||
{
|
||||
spdlog::error(L"Couldn't open settings file {}", settings_path_.wstring());
|
||||
return;
|
||||
}
|
||||
json_file << json.dump(4);
|
||||
json_file.close();
|
||||
}
|
||||
|
||||
} // namespace Settings
|
@ -0,0 +1,66 @@
|
||||
/*
|
||||
Copyright 2021-2023 Peter Repukat - FlatspotSoftware
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#define NOMINMAX
|
||||
#include <map>
|
||||
#include <Windows.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace UnhookUtil {
|
||||
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 = {
|
||||
0xE9,
|
||||
0xE8,
|
||||
0xEB,
|
||||
0xEA,
|
||||
0xFF };
|
||||
|
||||
// Valve Hooks various functions and hides Gaming devices like this.
|
||||
// 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
|
||||
static inline const std::map<std::string, std::string> UNHOOK_BYTES_ORIGINAL_22000 = {
|
||||
{"SetupDiEnumDeviceInfo", "\x48\x89\x5C\x24\x08"},
|
||||
{"SetupDiGetClassDevsW", "\x48\x89\x5C\x24\x08"},
|
||||
{"HidD_GetPreparsedData", "\x48\x89\x5C\x24\x18"},
|
||||
{"HidP_GetCaps", "\x4C\x8B\xD1\x48\x85\xC9"},
|
||||
{"HidD_GetAttributes", "\x40\x53\x48\x83\xEC"},
|
||||
{"HidD_GetProductString", "\x48\x83\xEC\x48\x48"},
|
||||
{"HidP_GetUsages", "\x4C\x89\x4C\x24\x20"},
|
||||
{"HidP_GetData", "\x4C\x89\x44\x24\x18"},
|
||||
{"HidP_GetValueCaps", "\x48\x83\xEC\x48\x49"},
|
||||
{"HidP_GetUsageValue", "\x40\x53\x55\x56\x48"},
|
||||
{"HidP_GetButtonCaps", "\x48\x83\xEC\x48\x49"},
|
||||
// Valve hooks "CreateProcess" to detect child-processes
|
||||
{"CreateProcessW", "\x4C\x8B\xDC\x48\x83"},
|
||||
};
|
||||
|
||||
// SetupApi.dll is different on Win10 than on Win11
|
||||
static inline const std::map<std::string, std::string> UNHOOK_BYTES_ORIGINAL_WIN10 = {
|
||||
{"SetupDiEnumDeviceInfo", "\x40\x53\x56\x57\x41\x54\x41\x55"},
|
||||
{"SetupDiGetClassDevsW", "\x48\x8B\xC4\x48\x89\x58\x08"},
|
||||
};
|
||||
|
||||
|
||||
} // namespace UnhookUtil
|
@ -0,0 +1,161 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\packages\Microsoft.Windows.CppWinRT.2.0.220531.1\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.220531.1\build\native\Microsoft.Windows.CppWinRT.props')" />
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{dfed4b7e-d04c-442b-bb48-5b6068a6b31b}</ProjectGuid>
|
||||
<RootNamespace>common</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Utility</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Utility</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<IncludePath>..\deps\json\include;..\deps\spdlog\include;..\deps\SFML\include;..\deps\imgui;..\deps\WinReg;..\deps\ValveFileVDF;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<IncludePath>..\deps\json\include;..\deps\spdlog\include;..\deps\SFML\include;..\deps\imgui;..\deps\WinReg;..\deps\ValveFileVDF;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="HidHide.h" />
|
||||
<ClInclude Include="nlohmann_json_wstring.h" />
|
||||
<ClInclude Include="Settings.h" />
|
||||
<ClInclude Include="steam_util.h" />
|
||||
<ClInclude Include="UnhookUtil.h" />
|
||||
<ClInclude Include="util.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="HidHide.cpp" />
|
||||
<ClCompile Include="UnhookUtil.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\packages\Microsoft.Windows.CppWinRT.2.0.220531.1\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.220531.1\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.220531.1\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.CppWinRT.2.0.220531.1\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.220531.1\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.CppWinRT.2.0.220531.1\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="nlohmann_json_wstring.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="util.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="UnhookUtil.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Settings.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="HidHide.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="steam_util.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="UnhookUtil.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="HidHide.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -0,0 +1,36 @@
|
||||
/*
|
||||
Copyright 2021-2023 Peter Repukat - FlatspotSoftware
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
|
||||
namespace nlohmann {
|
||||
template <>
|
||||
struct adl_serializer<std::wstring> {
|
||||
static void to_json(json& j, const std::wstring& str) {
|
||||
j = util::string::to_string(str);
|
||||
}
|
||||
|
||||
static void from_json(const json& j, std::wstring& str) {
|
||||
str = util::string::to_wstring(j.get<std::string>());
|
||||
}
|
||||
};
|
||||
}
|
@ -0,0 +1,221 @@
|
||||
/*
|
||||
Copyright 2021-2023 Peter Repukat - FlatspotSoftware
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#define SPDLOG_WCHAR_TO_UTF8_SUPPORT
|
||||
#define SPDLOG_WCHAR_FILENAMES
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <WinReg/WinReg.hpp>
|
||||
#include <vdf_parser.hpp>
|
||||
|
||||
|
||||
#include "util.h"
|
||||
#include "Settings.h"
|
||||
|
||||
namespace util
|
||||
{
|
||||
namespace steam
|
||||
{
|
||||
|
||||
static constexpr std::wstring_view user_data_path = L"/userdata/";
|
||||
static constexpr std::wstring_view config_file_name = L"/config/localconfig.vdf";
|
||||
static constexpr std::string_view overlay_hotkey_name = "InGameOverlayShortcutKey ";
|
||||
static constexpr std::string_view screenshot_hotkey_name = "InGameOverlayScreenshotHotKey ";
|
||||
|
||||
inline std::filesystem::path getSteamPath()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
try {
|
||||
// TODO: check if keys/value exist
|
||||
// steam should always be open and have written reg values...
|
||||
winreg::RegKey key{ HKEY_CURRENT_USER, L"SOFTWARE\\Valve\\Steam" };
|
||||
const auto res = key.GetStringValue(L"SteamPath");
|
||||
spdlog::info(L"Detected Steam Path: {}", res);
|
||||
return res;
|
||||
}
|
||||
catch (const winreg::RegException& e) {
|
||||
spdlog::error("Couldn't get Steam path from Registry; {}", e.what());
|
||||
}
|
||||
return Settings::common.steamPath;
|
||||
#else
|
||||
return L""; // TODO
|
||||
#endif
|
||||
}
|
||||
|
||||
inline std::wstring getSteamUserId()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
try {
|
||||
// TODO: check if keys/value exist
|
||||
// steam should always be open and have written reg values...
|
||||
winreg::RegKey key{ HKEY_CURRENT_USER, L"SOFTWARE\\Valve\\Steam\\ActiveProcess" };
|
||||
const auto res = std::to_wstring(key.GetDwordValue(L"ActiveUser"));
|
||||
spdlog::info(L"Detected Steam UserId: {}", res);
|
||||
return res;
|
||||
}
|
||||
catch (const winreg::RegException& e) {
|
||||
spdlog::error("Couldn't get Steam path from Registry; {}", e.what());
|
||||
}
|
||||
return Settings::common.steamUserId;
|
||||
#else
|
||||
return L""; // TODO
|
||||
#endif
|
||||
}
|
||||
|
||||
inline std::vector<std::string> getOverlayHotkey(const std::wstring& steam_path = getSteamPath(), const std::wstring& steam_user_id = getSteamPath())
|
||||
{
|
||||
const auto config_path = std::wstring(steam_path) + std::wstring(user_data_path) + steam_user_id + std::wstring(config_file_name);
|
||||
if (!std::filesystem::exists(config_path)) {
|
||||
spdlog::warn(L"Couldn't read Steam config file: \"{}\"", config_path);
|
||||
return { "Shift", "KEY_TAB" }; // default
|
||||
}
|
||||
std::ifstream config_file(config_path);
|
||||
auto root = tyti::vdf::read(config_file);
|
||||
|
||||
std::shared_ptr<tyti::vdf::basic_object<char>> children = root.childs["system"];
|
||||
if (!children || children->attribs.empty() || !children->attribs.contains("InGameOverlayShortcutKey")) {
|
||||
spdlog::warn("Couldn't detect overlay hotkey, using default: Shift+Tab");
|
||||
return { "Shift", "KEY_TAB" }; // default
|
||||
}
|
||||
auto hotkeys = children->attribs.at("InGameOverlayShortcutKey");
|
||||
|
||||
// has anyone more than 4 keys to open overlay?!
|
||||
std::smatch m;
|
||||
if (!std::regex_match(hotkeys, m, std::regex(R"((\w*)\s*(\w*)\s*(\w*)\s*(\w*))"))) {
|
||||
spdlog::warn("Couldn't detect overlay hotkey, using default: Shift+Tab");
|
||||
return { "Shift", "KEY_TAB" }; // default
|
||||
}
|
||||
|
||||
std::vector<std::string> res;
|
||||
for (auto i = 1; i < m.size(); i++) {
|
||||
const auto s = std::string(m[i]);
|
||||
if (!s.empty()) {
|
||||
res.push_back(s);
|
||||
}
|
||||
}
|
||||
if (res.empty()) {
|
||||
spdlog::warn("Couldn't detect overlay hotkey, using default: Shift+Tab");
|
||||
return { "Shift", "KEY_TAB" }; // default
|
||||
}
|
||||
spdlog::info("Detected Overlay hotkey(s): {}", std::accumulate(
|
||||
res.begin() + 1, res.end(), res[0],
|
||||
[](auto acc, const auto curr) { return acc += "+" + curr; }));
|
||||
return res;
|
||||
}
|
||||
|
||||
inline std::vector<std::string> getScreenshotHotkey(const std::wstring& steam_path = getSteamPath(), const std::wstring& steam_user_id = getSteamPath())
|
||||
{
|
||||
const auto config_path = std::wstring(steam_path) + std::wstring(user_data_path) + steam_user_id + std::wstring(config_file_name);
|
||||
if (!std::filesystem::exists(config_path)) {
|
||||
spdlog::warn(L"Couldn't read Steam config file: \"{}\"", config_path);
|
||||
return { "KEY_F12" }; // default
|
||||
}
|
||||
std::ifstream config_file(config_path);
|
||||
auto root = tyti::vdf::read(config_file);
|
||||
|
||||
std::shared_ptr<tyti::vdf::basic_object<char>> children = root.childs["system"];
|
||||
if (!children || children->attribs.empty() || !children->attribs.contains("InGameOverlayScreenshotHotKey")) {
|
||||
spdlog::warn("Couldn't detect overlay hotkey, using default: F12");
|
||||
return { "KEY_F12" }; // default
|
||||
}
|
||||
auto hotkeys = children->attribs.at("InGameOverlayScreenshotHotKey");
|
||||
|
||||
// has anyone more than 4 keys to screenshot?!
|
||||
std::smatch m;
|
||||
if (!std::regex_match(hotkeys, m, std::regex(R"((\w*)\s*(\w*)\s*(\w*)\s*(\w*))"))) {
|
||||
spdlog::warn("Couldn't detect overlay hotkey, using default: F12");
|
||||
return { "KEY_F12" }; // default
|
||||
}
|
||||
|
||||
std::vector<std::string> res;
|
||||
for (auto i = 1; i < m.size(); i++) {
|
||||
const auto s = std::string(m[i]);
|
||||
if (!s.empty()) {
|
||||
res.push_back(s);
|
||||
}
|
||||
}
|
||||
if (res.empty()) {
|
||||
spdlog::warn("Couldn't detect overlay hotkey, using default: F12");
|
||||
return { "KEY_F12" }; // default
|
||||
}
|
||||
spdlog::info("Detected screenshot hotkey(s): {}", std::accumulate(
|
||||
res.begin() + 1, res.end(), res[0],
|
||||
[](auto acc, const auto curr) { return acc += "+" + curr; }));
|
||||
return res;
|
||||
}
|
||||
|
||||
inline bool getXBCRebindingEnabled(const std::wstring& steam_path = getSteamPath(), const std::wstring& steam_user_id = getSteamPath())
|
||||
{
|
||||
const auto config_path = std::wstring(steam_path) + std::wstring(user_data_path) + steam_user_id + std::wstring(config_file_name);
|
||||
if (!std::filesystem::exists(config_path)) {
|
||||
spdlog::warn(L"Couldn't read Steam config file: \"{}\"", config_path);
|
||||
return false;
|
||||
}
|
||||
std::ifstream config_file(config_path);
|
||||
auto root = tyti::vdf::read(config_file);
|
||||
|
||||
if (root.attribs.empty() || !root.attribs.contains("SteamController_XBoxSupport")) {
|
||||
spdlog::warn("\"Xbox Configuration Support\" is disabled in Steam. This may cause doubled Inputs!");
|
||||
return false;
|
||||
}
|
||||
auto xbsup = root.attribs.at("SteamController_XBoxSupport");
|
||||
if (xbsup != "1") {
|
||||
spdlog::warn("\"Xbox Configuration Support\" is disabled in Steam. This may cause doubled Inputs!");
|
||||
}
|
||||
return xbsup == "1";
|
||||
}
|
||||
|
||||
inline nlohmann::json getSteamConfig(const std::wstring& steam_path = getSteamPath(), const std::wstring& steam_user_id = getSteamUserId())
|
||||
{
|
||||
const auto config_path = std::wstring(steam_path) + std::wstring(user_data_path) + steam_user_id + std::wstring(config_file_name);
|
||||
if (!std::filesystem::exists(config_path)) {
|
||||
spdlog::warn(L"Couldn't read Steam config file: \"{}\"", config_path);
|
||||
return nlohmann::json();
|
||||
}
|
||||
std::ifstream config_file(config_path);
|
||||
auto root = tyti::vdf::read(config_file);
|
||||
if (root.attribs.empty())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
auto res = nlohmann::json::object();
|
||||
res[root.name] = nlohmann::json::object();
|
||||
for (auto& [key, value] : root.attribs)
|
||||
{
|
||||
res[root.name][key] = value;
|
||||
}
|
||||
auto parse_child = [](nlohmann::json& j, std::shared_ptr<tyti::vdf::basic_object<char>> child, auto&& recurse) -> void
|
||||
{
|
||||
for (auto& [key, value] : child->attribs)
|
||||
{
|
||||
j[key] = value;
|
||||
for (auto& [childkey, childval] : child->childs)
|
||||
{
|
||||
j[childkey] = {};
|
||||
recurse(j[childkey], childval, recurse);
|
||||
}
|
||||
}
|
||||
};
|
||||
for (auto& [key, value] : root.childs)
|
||||
{
|
||||
res[root.name][key] = {};
|
||||
parse_child(res[root.name][key], value, parse_child);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,173 @@
|
||||
/*
|
||||
Copyright 2021-2023 Peter Repukat - FlatspotSoftware
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <locale>
|
||||
#include <codecvt>
|
||||
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define NOMINMAX
|
||||
#include <Windows.h>
|
||||
#include <tlhelp32.h>
|
||||
#include <ShlObj.h>
|
||||
#include <KnownFolders.h>
|
||||
#endif
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
#ifdef SPDLOG_H
|
||||
#define SPDLOG_WCHAR_TO_UTF8_SUPPORT
|
||||
#define SPDLOG_WCHAR_FILENAMES
|
||||
#include <spdlog/spdlog.h>
|
||||
#endif
|
||||
|
||||
namespace util {
|
||||
namespace string
|
||||
{
|
||||
template <typename T>
|
||||
inline std::wstring to_wstring(const T& t)
|
||||
{
|
||||
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
|
||||
return converter.from_bytes(t);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline std::string to_string(const T& t)
|
||||
{
|
||||
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
|
||||
return converter.to_bytes(t);
|
||||
}
|
||||
}
|
||||
|
||||
namespace path
|
||||
{
|
||||
inline std::filesystem::path getDataDirPath()
|
||||
{
|
||||
wchar_t* localAppDataFolder;
|
||||
std::filesystem::path path;
|
||||
if (SHGetKnownFolderPath(FOLDERID_LocalAppData, KF_FLAG_CREATE, nullptr, &localAppDataFolder) != S_OK) {
|
||||
path = std::filesystem::temp_directory_path().parent_path().parent_path().parent_path();
|
||||
}
|
||||
else {
|
||||
path = std::filesystem::path(localAppDataFolder).parent_path();
|
||||
}
|
||||
|
||||
path /= "Roaming";
|
||||
path /= "GlosSI";
|
||||
if (!std::filesystem::exists(path))
|
||||
std::filesystem::create_directories(path);
|
||||
return path;
|
||||
}
|
||||
|
||||
inline std::filesystem::path getGlosSIDir()
|
||||
{
|
||||
wchar_t result[MAX_PATH];
|
||||
std::filesystem::path res{ std::wstring{result, GetModuleFileNameW(NULL, result, MAX_PATH)} };
|
||||
return res.parent_path();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
namespace win
|
||||
{
|
||||
|
||||
typedef LONG NTSTATUS, * PNTSTATUS;
|
||||
#define STATUS_SUCCESS (0x00000000)
|
||||
|
||||
typedef NTSTATUS(WINAPI* RtlGetVersionPtr)(PRTL_OSVERSIONINFOW);
|
||||
|
||||
inline RTL_OSVERSIONINFOW GetRealOSVersion()
|
||||
{
|
||||
HMODULE hMod = ::GetModuleHandleW(L"ntdll.dll");
|
||||
if (hMod) {
|
||||
RtlGetVersionPtr fxPtr = (RtlGetVersionPtr)::GetProcAddress(hMod, "RtlGetVersion");
|
||||
if (fxPtr != nullptr) {
|
||||
RTL_OSVERSIONINFOW rovi = { 0 };
|
||||
rovi.dwOSVersionInfoSize = sizeof(rovi);
|
||||
if (STATUS_SUCCESS == fxPtr(&rovi)) {
|
||||
return rovi;
|
||||
}
|
||||
}
|
||||
}
|
||||
RTL_OSVERSIONINFOW rovi = { 0 };
|
||||
return rovi;
|
||||
}
|
||||
namespace process
|
||||
{
|
||||
inline DWORD PidByName(const std::wstring& name)
|
||||
{
|
||||
PROCESSENTRY32 entry;
|
||||
entry.dwSize = sizeof(PROCESSENTRY32);
|
||||
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
|
||||
if (Process32First(snapshot, &entry) == TRUE) {
|
||||
while (Process32Next(snapshot, &entry) == TRUE) {
|
||||
if (std::wstring(entry.szExeFile).find(name) != std::string::npos) {
|
||||
return entry.th32ProcessID;
|
||||
}
|
||||
}
|
||||
}
|
||||
CloseHandle(snapshot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline std::wstring GetProcName(DWORD pid)
|
||||
{
|
||||
PROCESSENTRY32 processInfo;
|
||||
processInfo.dwSize = sizeof(processInfo);
|
||||
const HANDLE processesSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
|
||||
if (processesSnapshot == INVALID_HANDLE_VALUE) {
|
||||
#ifdef SPDLOG_H
|
||||
spdlog::trace("util::GetProcName: can't get a process snapshot");
|
||||
#endif
|
||||
return L"";
|
||||
}
|
||||
|
||||
for (BOOL bok = Process32First(processesSnapshot, &processInfo);
|
||||
bok;
|
||||
bok = Process32Next(processesSnapshot, &processInfo)) {
|
||||
if (pid == processInfo.th32ProcessID) {
|
||||
CloseHandle(processesSnapshot);
|
||||
return processInfo.szExeFile;
|
||||
}
|
||||
}
|
||||
CloseHandle(processesSnapshot);
|
||||
return L"";
|
||||
}
|
||||
|
||||
inline bool KillProcess(DWORD pid)
|
||||
{
|
||||
auto res = true;
|
||||
if (const auto proc = OpenProcess(PROCESS_TERMINATE, FALSE, pid)) {
|
||||
#ifdef SPDLOG_H
|
||||
spdlog::debug("Terminating process: {}", pid);
|
||||
#endif
|
||||
res = TerminateProcess(proc, 0);
|
||||
if (!res) {
|
||||
#ifdef SPDLOG_H
|
||||
spdlog::error("Failed to terminate process: {}", pid);
|
||||
#endif
|
||||
}
|
||||
CloseHandle(proc);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
@ -1 +1 @@
|
||||
Subproject commit 3bc2cee48ab0b10b5dd31323a621677175cfb00d
|
||||
Subproject commit 20fb9cb05275acad6ab5c786160656d8f83e0c6f
|
@ -0,0 +1 @@
|
||||
Subproject commit afc1d8cfc584e0f1f4a77e8c0ce3e979d9fe7ce2
|
@ -1,3 +1,3 @@
|
||||
Invoke-WebRequest -o ViGEmBusSetup_x64.exe https://github.com/ViGEm/ViGEmBus/releases/download/v1.21.442.0/ViGEmBus_1.21.442_x64_x86_arm64.exe
|
||||
Invoke-WebRequest -o HidHideSetup.exe https://github.com/ViGEm/HidHide/releases/download/v1.2.98.0/HidHide_1.2.98_x64.exe
|
||||
Invoke-WebRequest -o ViGEmBusSetup_x64.exe https://github.com/nefarius/ViGEmBus/releases/download/v1.22.0/ViGEmBus_1.22.0_x64_x86_arm64.exe
|
||||
Invoke-WebRequest -o HidHideSetup.exe https://github.com/nefarius/HidHide/releases/download/v1.4.192.0/HidHide_1.4.192_x64.exe
|
||||
Invoke-WebRequest -o vc_redist.x64.exe https://aka.ms/vs/16/release/vc_redist.x64.exe
|
@ -1,15 +0,0 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": "GlosSIConfig"
|
||||
},
|
||||
{
|
||||
"path": "GlosSITarget"
|
||||
},
|
||||
{
|
||||
"name": "root",
|
||||
"path": "."
|
||||
}
|
||||
],
|
||||
"settings": {}
|
||||
}
|
@ -0,0 +1,137 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": "common"
|
||||
},
|
||||
{
|
||||
"path": "CEFInjectLib"
|
||||
},
|
||||
{
|
||||
"path": "GlosSIConfig"
|
||||
},
|
||||
{
|
||||
"path": "GlosSITarget"
|
||||
},
|
||||
{
|
||||
"path": "GlosSIWatchdog"
|
||||
},
|
||||
{
|
||||
"path": "UWPOverlayEnablerDLL"
|
||||
},
|
||||
{
|
||||
"path": "Installer"
|
||||
},
|
||||
{
|
||||
"path": "SteamTweaks"
|
||||
},
|
||||
{
|
||||
"name": "root",
|
||||
"path": "."
|
||||
},
|
||||
],
|
||||
"settings": {
|
||||
"files.associations": {
|
||||
"algorithm": "cpp",
|
||||
"chrono": "cpp",
|
||||
"filesystem": "cpp",
|
||||
"xstring": "cpp",
|
||||
"xutility": "cpp",
|
||||
"xhash": "cpp",
|
||||
"xtree": "cpp",
|
||||
"map": "cpp",
|
||||
"any": "cpp",
|
||||
"array": "cpp",
|
||||
"atomic": "cpp",
|
||||
"bit": "cpp",
|
||||
"cctype": "cpp",
|
||||
"charconv": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"codecvt": "cpp",
|
||||
"compare": "cpp",
|
||||
"concepts": "cpp",
|
||||
"condition_variable": "cpp",
|
||||
"coroutine": "cpp",
|
||||
"csignal": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cstring": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"deque": "cpp",
|
||||
"exception": "cpp",
|
||||
"resumable": "cpp",
|
||||
"format": "cpp",
|
||||
"forward_list": "cpp",
|
||||
"fstream": "cpp",
|
||||
"functional": "cpp",
|
||||
"future": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"ios": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"iostream": "cpp",
|
||||
"istream": "cpp",
|
||||
"iterator": "cpp",
|
||||
"limits": "cpp",
|
||||
"list": "cpp",
|
||||
"locale": "cpp",
|
||||
"memory": "cpp",
|
||||
"mutex": "cpp",
|
||||
"new": "cpp",
|
||||
"numeric": "cpp",
|
||||
"optional": "cpp",
|
||||
"ostream": "cpp",
|
||||
"queue": "cpp",
|
||||
"random": "cpp",
|
||||
"ranges": "cpp",
|
||||
"ratio": "cpp",
|
||||
"regex": "cpp",
|
||||
"set": "cpp",
|
||||
"span": "cpp",
|
||||
"sstream": "cpp",
|
||||
"stack": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"stop_token": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"string": "cpp",
|
||||
"system_error": "cpp",
|
||||
"thread": "cpp",
|
||||
"tuple": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"unordered_set": "cpp",
|
||||
"utility": "cpp",
|
||||
"valarray": "cpp",
|
||||
"variant": "cpp",
|
||||
"vector": "cpp",
|
||||
"xfacet": "cpp",
|
||||
"xiosbase": "cpp",
|
||||
"xlocale": "cpp",
|
||||
"xlocbuf": "cpp",
|
||||
"xlocinfo": "cpp",
|
||||
"xlocmes": "cpp",
|
||||
"xlocmon": "cpp",
|
||||
"xlocnum": "cpp",
|
||||
"xloctime": "cpp",
|
||||
"xmemory": "cpp",
|
||||
"xstddef": "cpp",
|
||||
"xtr1common": "cpp"
|
||||
}
|
||||
// uncomment if not already in user settings and wanting to debug/build c++ code (vs 2022 required!)
|
||||
// "terminal.integrated.profiles.windows": {
|
||||
// "Developer PowerShell for VS 2022": {
|
||||
// "source": "PowerShell",
|
||||
// "icon": "terminal-powershell",
|
||||
// "args": [
|
||||
// "-c",
|
||||
// "$vsPath = & '${env:ProgramFiles(x86)}/Microsoft Visual Studio/Installer/vswhere.exe' -property installationpath; Import-Module \"$vsPath/Common7/Tools/Microsoft.VisualStudio.DevShell.dll\"; Enter-VsDevShell -VsInstallPath $vsPath -SkipAutomaticLocation; powershell.exe"
|
||||
// ]
|
||||
// }
|
||||
// },
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
Get-Content "$env:appdata\GlosSI\glossiconfig.log" -Wait
|
@ -0,0 +1 @@
|
||||
Get-Content "$env:appdata\GlosSI\GlosSItarget.log" -Wait
|
Loading…
Reference in New Issue