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",
|
"version": "2.0.0",
|
||||||
"tasks": [
|
"tasks": [
|
||||||
{
|
{
|
||||||
"type": "cmake",
|
"type": "shell",
|
||||||
"command": "build",
|
"label": "Build GlosSITarget (Debug)",
|
||||||
"label": "Build",
|
"command": "msbuild.exe",
|
||||||
"group": {
|
"args": [
|
||||||
"kind": "build",
|
"GlosSI.sln",
|
||||||
"isDefault": true
|
"/target:GlosSITarget",
|
||||||
},
|
"/p:Configuration=Debug",
|
||||||
"problemMatcher": []
|
"/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 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/ViGEm/HidHide/releases/download/v1.2.98.0/HidHide_1.2.98_x64.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
|
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