mirror of https://github.com/Alia5/GlosSI
Compare commits
154 Commits
Author | SHA1 | Date |
---|---|---|
Peter Repukat | 2b41208e6f | 5 months ago |
Peter Repukat | 0ebfd1e973 | 5 months ago |
Peter Repukat | 73226d3c62 | 5 months ago |
Peter Repukat | f2f2144017 | 5 months ago |
Peter Repukat | d303f2be79 | 5 months ago |
Peter Repukat | 954d953f4b | 5 months ago |
Peter Repukat | b359053771 | 5 months ago |
Peter Repukat | de2bd57979 | 5 months ago |
Peter Repukat | 56c4003810 | 5 months ago |
Peter Repukat | 77c7b639ab | 5 months ago |
Peter Repukat | 2ddb3f1bb0 | 5 months ago |
Peter Repukat | 906e40b753 | 5 months ago |
Peter Repukat | 6bebae6c7b | 5 months ago |
Peter Repukat | e9a02d046b | 5 months ago |
Peter Repukat | 545fc6af1c | 5 months ago |
Peter Repukat | 8015853d1b | 5 months ago |
Peter Repukat | fe91680fd1 | 5 months ago |
Peter Repukat | fe21af6787 | 5 months ago |
Peter Repukat | 88856be11a | 5 months ago |
Peter Repukat | b9cb0414a7 | 5 months ago |
Peter Repukat | ffdb227d2b | 5 months ago |
Peter Repukat | 50a4ea814d | 5 months ago |
Peter Repukat | 0745e3684d | 5 months ago |
James Lamine | 6c0a6145ec | 5 months ago |
Peter Repukat | 9c98b28c72 | 5 months ago |
Peter Repukat | 34b3f5322d | 5 months ago |
Peter Repukat | 89c90a2ea0 | 5 months ago |
Peter Repukat | bf8caca40e | 5 months ago |
Peter Repukat | cb6cbdeac6 | 5 months ago |
Peter Repukat | 4c847543fc | 5 months ago |
Peter Repukat | 4d96ed94a1 | 5 months ago |
Peter Repukat | 08ffcad760 | 5 months ago |
Peter Repukat | e5368744f1 | 5 months ago |
Peter Repukat | 0e356801e7 | 5 months ago |
Peter Repukat | efe12dc333 | 5 months ago |
Peter Repukat | aa3f513e13 | 5 months ago |
Peter Repukat | 54fb29a79d | 5 months ago |
Peter Repukat | b86d548fc2 | 5 months ago |
Peter Repukat | b0b67f8c9d | 5 months ago |
Peter Repukat | b35f422a54 | 5 months ago |
Peter Repukat | 226b8368b1 | 5 months ago |
Peter Repukat | 18241c1fc4 | 5 months ago |
Peter Repukat | b26fd9faf5 | 5 months ago |
Peter Repukat | a07faa926c | 5 months ago |
Peter Repukat | d60def51d5 | 5 months ago |
Peter Repukat | 766cac3969 | 5 months ago |
Peter Repukat | 816b89cce6 | 5 months ago |
Peter Repukat | 00127dcd2b | 5 months ago |
Peter Repukat | e6db328273 | 5 months ago |
Peter Repukat | cf23edafdb | 5 months ago |
Peter Repukat | f68e3070d0 | 5 months ago |
Peter Repukat | d89c84478f | 5 months ago |
Peter Repukat | 531857003e | 5 months ago |
Peter Repukat | baa7aec0c8 | 5 months ago |
Peter Repukat | 04653b2fb7 | 5 months ago |
Peter Repukat | 2a8df5fdc3 | 5 months ago |
Peter Repukat | da0b99d679 | 5 months ago |
Peter Repukat | f7df3deb7d | 5 months ago |
Peter Repukat | 738803fa2e | 5 months ago |
Peter Repukat | b33b2a0691 | 5 months ago |
Peter Repukat | b69bd4abdd | 5 months ago |
Peter Repukat | 70187090e7 | 5 months ago |
Peter Repukat | 10b65a1a9b | 5 months ago |
Peter Repukat | 2941b4548e | 5 months ago |
Peter Repukat | 4b57c6cb94 | 5 months ago |
Peter Repukat | 7a01ceede1 | 5 months ago |
Peter Repukat | ba777193a5 | 9 months ago |
Peter Repukat | db403cd6e7 | 9 months ago |
Peter Repukat | 69f11f8e28 | 9 months ago |
Peter Repukat | beb6bbadc5 | 9 months ago |
Peter Repukat | 1571cc8abd | 10 months ago |
Adonis | 66f3c26ec7 | 10 months ago |
Peter Repukat | a4d2bd81ad | 1 year ago |
Peter Repukat | b76b6ee595 | 1 year ago |
Peter Repukat | 2ac3325c5b | 1 year ago |
Peter Repukat | 4e4c85885c | 1 year ago |
Peter Repukat | 2824329687 | 1 year ago |
Peter Repukat | 924a7ecba7 | 1 year ago |
Peter Repukat | efdcc8f881 | 1 year ago |
Peter Repukat | 9b2c57b0db | 1 year ago |
Peter Repukat | b4351d2743 | 1 year ago |
Marocco2 | 2594512c12 | 1 year ago |
Marocco2 | 41c385e551 | 1 year ago |
Marocco2 | be4c8fb209 | 1 year ago |
Marocco2 | 4fc3ff8e93 | 1 year ago |
Marocco2 | c0303c88d0 | 1 year ago |
Peter Repukat | 85ab663804 | 1 year ago |
Peter Repukat | be8e206683 | 1 year ago |
Peter Repukat | 51180c6306 | 1 year ago |
Peter Repukat | 87330a521f | 1 year ago |
Peter Repukat | 3c4584d0a8 | 1 year ago |
Peter Repukat | ebd44ba53a | 1 year ago |
Peter Repukat | fb641048c9 | 2 years ago |
Peter Repukat | 128e7f4a62 | 2 years ago |
Peter Repukat | 9e170d24bd | 2 years ago |
Peter Repukat | 5176dab9be | 2 years ago |
Peter Repukat | a8235ca9c9 | 2 years ago |
Peter Repukat | 9232eead0a | 2 years ago |
Peter Repukat | 6ee8317f77 | 2 years ago |
Peter Repukat | 45bd68e595 | 2 years ago |
Peter Repukat | 2fbf3b444d | 2 years ago |
Peter Repukat | 78a9bbdc9d | 2 years ago |
Peter Repukat | 5528dfb733 | 2 years ago |
Peter Repukat | 63fdab1685 | 2 years ago |
Peter Repukat | 3df6cf510a | 2 years ago |
Peter Repukat | 20e86ce8e4 | 2 years ago |
Peter Repukat | 6e69b6ec1c | 2 years ago |
Peter Repukat | 93026dfb75 | 2 years ago |
Peter Repukat | 616650c04c | 2 years ago |
Peter Repukat | e5d7dd4432 | 2 years ago |
Peter Repukat | 3458f907ca | 2 years ago |
Peter Repukat | c4f2382928 | 2 years ago |
Peter Repukat | be48ffee40 | 2 years ago |
Peter Repukat | 01efd8d02d | 2 years ago |
Peter Repukat | b568418891 | 2 years ago |
Peter Repukat | 929abfe5f2 | 2 years ago |
Peter Repukat | e56a53a0b7 | 2 years ago |
Peter Repukat | 1a22423f56 | 2 years ago |
Peter Repukat | cafb4e85a8 | 2 years ago |
Peter Repukat | 18a960abab | 2 years ago |
Peter Repukat | fc03e91c2b | 2 years ago |
Peter Repukat | 96d8f24c93 | 2 years ago |
Peter Repukat | 138dd98c59 | 2 years ago |
Peter Repukat | 11e3029915 | 2 years ago |
Peter Repukat | eee7390547 | 2 years ago |
Peter Repukat | 51c2268dc0 | 2 years ago |
Peter Repukat | d22f44d37d | 2 years ago |
Peter Repukat | bf89cb8ddc | 2 years ago |
Peter Repukat | e3a55d9b1c | 2 years ago |
Peter Repukat | ed0b43a651 | 2 years ago |
Peter Repukat | d9c45a4a7b | 2 years ago |
Peter Repukat | 7b8eb7391b | 2 years ago |
Peter Repukat | 496b8fc146 | 2 years ago |
Peter Repukat | 14d3e45379 | 2 years ago |
Peter Repukat | 1b2b8b759a | 2 years ago |
Peter Repukat | 31ce36095f | 2 years ago |
Peter Repukat | a1c1a7d141 | 2 years ago |
Peter Repukat | 73bbffd6cf | 2 years ago |
Peter Repukat | 655d3b0853 | 2 years ago |
Peter Repukat | 3903f38c0e | 2 years ago |
Peter Repukat | febebafc25 | 2 years ago |
Peter Repukat | e879d0ba5c | 2 years ago |
Peter Repukat | c9c6a32432 | 2 years ago |
Peter Repukat | ab575c1e29 | 2 years ago |
Peter Repukat | f9c993dc50 | 2 years ago |
Peter Repukat | 9e08309a1a | 2 years ago |
Peter Repukat | f6d959eab6 | 2 years ago |
Peter Repukat | d4e22c2a8a | 2 years ago |
Peter Repukat | 1c18e84648 | 2 years ago |
Peter Repukat | eacd05b4c6 | 2 years ago |
Peter Repukat | d2fd3a75da | 2 years ago |
Peter Repukat | ff014a935a | 2 years ago |
Peter Repukat | d4a3e22e9c | 2 years ago |
Peter Repukat | a24c16a44e | 2 years ago |
@ -0,0 +1,24 @@
|
||||
---
|
||||
name: Other
|
||||
about: Create issue that doesn't fit other templates
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
- [ ] _**I have read and understand that tickets without Logs (or other info if Logs are 1000% not relevant) will be closed without comment.**_
|
||||
|
||||
## General Information
|
||||
|
||||
- Version: (0.0.0.0-0-g1234567)
|
||||
- Platform: (Win10/Win11 / Desktop/SteamDeck)
|
||||
- Controller(s): (1 Steam Controller + 1 Switch Pro Controller)
|
||||
- Application: (GlosSITarget/GlosSIConfig)
|
||||
|
||||
## Logs / Additional Files
|
||||
|
||||
Log and config files are located in `%appdata%/GlosSI`
|
||||
The files are called: glossiconfig.log, glossitarget.log, GlosSIWatchdog.log and UWPOverlayEnabler.log
|
||||
|
||||
_(Windows-search may not pick up the files when searching for `log` **if** file endings are hidden (default setting))_
|
@ -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 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="48" width="48" fill="#FFFFFF"><path d="M29.45 6v3H9v30h30V18.6h3V39q0 1.2-.9 2.1-.9.9-2.1.9H9q-1.2 0-2.1-.9Q6 40.2 6 39V9q0-1.2.9-2.1Q7.8 6 9 6ZM38 6v4.05h4.05v3H38v4.05h-3v-4.05h-4.05v-3H35V6ZM12 33.9h24l-7.2-9.6-6.35 8.35-4.7-6.2ZM9 9v30V9Z"/></svg>
|
After Width: | Height: | Size: 299 B |
@ -0,0 +1,37 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Win32",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/**",
|
||||
"${workspaceFolder}/../deps/SFML/include",
|
||||
"${workspaceFolder}/../deps/WinReg",
|
||||
"${workspaceFolder}/../deps/spdlog/include",
|
||||
"${workspaceFolder}/../deps/ValveFileVDF",
|
||||
"${workspaceFolder}/../deps/subhook",
|
||||
"${workspaceFolder}/../deps/ViGEmClient/include",
|
||||
"${workspaceFolder}/../deps/imgui",
|
||||
"${workspaceFolder}/../deps/imgui-sfml",
|
||||
"${workspaceFolder}/../deps/json/include",
|
||||
"${workspaceFolder}/../deps/traypp/tray/include",
|
||||
"${workspaceFolder}/../deps/cpp-httplib",
|
||||
"${workspaceFolder}/../CEFInjectLib"
|
||||
],
|
||||
"defines": [
|
||||
"_DEBUG",
|
||||
"UNICODE",
|
||||
"_UNICODE",
|
||||
"SPDLOG_WCHAR_TO_UTF8_SUPPORT",
|
||||
"SPDLOG_WCHAR_FILENAMES",
|
||||
"_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING",
|
||||
"SUBHOOK_STATIC"
|
||||
],
|
||||
"windowsSdkVersion": "10.0.18362.0",
|
||||
"compilerPath": "C:/Program Files (x86)/Microsoft Visual Studio/2019/BuildTools/VC/Tools/MSVC/14.24.28314/bin/Hostx64/x64/cl.exe",
|
||||
"cStandard": "c11",
|
||||
"cppStandard": "c++20",
|
||||
"intelliSenseMode": "msvc-x64"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
{
|
||||
"C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools"
|
||||
}
|
@ -1,15 +1,43 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "cmake",
|
||||
"command": "build",
|
||||
"label": "Build",
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"problemMatcher": []
|
||||
}
|
||||
]
|
||||
}
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "shell",
|
||||
"label": "Build GlosSITarget (Debug)",
|
||||
"command": "msbuild.exe",
|
||||
"args": [
|
||||
"GlosSI.sln",
|
||||
"/target:GlosSITarget",
|
||||
"/p:Configuration=Debug",
|
||||
"/p:Platform=x64"
|
||||
],
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/..",
|
||||
|
||||
},
|
||||
"problemMatcher": ["$msCompile"],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
},
|
||||
},
|
||||
{
|
||||
"type": "shell",
|
||||
"label": "Re-Build GlosSITarget (Debug)",
|
||||
"command": "msbuild.exe",
|
||||
"args": [
|
||||
"GlosSI.sln",
|
||||
"/target:GlosSITarget:Rebuild",
|
||||
"/p:Configuration=Debug",
|
||||
"/p:Platform=x64"
|
||||
],
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/..",
|
||||
|
||||
},
|
||||
"problemMatcher": ["$msCompile"],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
#pragma once
|
||||
#include "HttpServer.h"
|
||||
#include "../common/Settings.h"
|
||||
#include "../common/steam_util.h"
|
||||
|
||||
namespace CHTE {
|
||||
|
||||
inline void addEndpoints()
|
||||
{
|
||||
|
||||
HttpServer::AddEndpoint(
|
||||
{"/running",
|
||||
HttpServer::Method::GET,
|
||||
[](const httplib::Request& req, httplib::Response& res) {
|
||||
// TODO: extend this when "passive" running of global mods is implemented
|
||||
res.set_content(nlohmann::json{{"state", nlohmann::json{{"running", true}}}}.dump(), "text/json");
|
||||
}});
|
||||
|
||||
HttpServer::AddEndpoint(
|
||||
{"/settings",
|
||||
HttpServer::Method::GET,
|
||||
[](const httplib::Request& req, httplib::Response& res) {
|
||||
res.set_content(Settings::toJson().dump(), "text/json");
|
||||
},
|
||||
"json"});
|
||||
|
||||
HttpServer::AddEndpoint(
|
||||
{"/steam_settings",
|
||||
HttpServer::Method::GET,
|
||||
[](const httplib::Request& req, httplib::Response& res) {
|
||||
res.set_content(util::steam::getSteamConfig().dump(4), "text/json");
|
||||
},
|
||||
"json"});
|
||||
|
||||
HttpServer::AddEndpoint({
|
||||
"/log",
|
||||
HttpServer::Method::POST,
|
||||
[](const httplib::Request& req, httplib::Response& res) {
|
||||
struct LogEntry {
|
||||
std::string level;
|
||||
std::string message;
|
||||
};
|
||||
auto entry = LogEntry{};
|
||||
try {
|
||||
const nlohmann::json postbody = nlohmann::json::parse(req.body);
|
||||
entry.level = postbody.at("level");
|
||||
entry.message = postbody.at("message");
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
res.status = 401;
|
||||
res.set_content(nlohmann::json{
|
||||
{"code", 401},
|
||||
{"name", "Bad Request"},
|
||||
{"message", e.what()},
|
||||
}
|
||||
.dump(),
|
||||
"text/json");
|
||||
}
|
||||
if (entry.level == "info") {
|
||||
spdlog::info("GlosSITweaks: {}", entry.message);
|
||||
}
|
||||
else if (entry.level == "warn") {
|
||||
spdlog::warn("GlosSITweaks: {}", entry.message);
|
||||
}
|
||||
else if (entry.level == "error") {
|
||||
spdlog::error("GlosSITweaks: {}", entry.message);
|
||||
}
|
||||
else if (entry.level == "debug") {
|
||||
spdlog::debug("GlosSITweaks: {}", entry.message);
|
||||
}
|
||||
else {
|
||||
spdlog::trace("GlosSITweaks: {}", entry.message);
|
||||
}
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
} // namespace CHTE
|
@ -0,0 +1,144 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
#include "HttpServer.h"
|
||||
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <utility>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
HttpServer::HttpServer(std::function<void()> close) : close_(std::move(close))
|
||||
{
|
||||
}
|
||||
|
||||
std::string HttpServer::ToString(Method m)
|
||||
{
|
||||
switch (m) {
|
||||
case POST:
|
||||
return "POST";
|
||||
case PATCH:
|
||||
return "PATCH";
|
||||
case PUT:
|
||||
return "PUT";
|
||||
default:
|
||||
return "GET";
|
||||
}
|
||||
}
|
||||
|
||||
void HttpServer::AddEndpoint(const Endpoint&& e)
|
||||
{
|
||||
endpoints_.push_back(e);
|
||||
}
|
||||
|
||||
void HttpServer::run()
|
||||
{
|
||||
auto setCorsHeader = [](httplib::Response& res) {
|
||||
res.set_header("Access-Control-Allow-Origin", "*");
|
||||
};
|
||||
|
||||
server_.Get("/", [this, &setCorsHeader](const httplib::Request& req, httplib::Response& res) {
|
||||
setCorsHeader(res);
|
||||
|
||||
auto content_json = nlohmann::json{
|
||||
{"endpoints", nlohmann::json::array()}};
|
||||
|
||||
for (const auto& e : endpoints_) {
|
||||
content_json["endpoints"].push_back(
|
||||
nlohmann::json{
|
||||
{"path", e.path},
|
||||
{"method", ToString(e.method)},
|
||||
{"response", e.response_hint},
|
||||
{"payload", e.payload_hint},
|
||||
});
|
||||
}
|
||||
|
||||
content_json["endpoints"].push_back(
|
||||
nlohmann::json{
|
||||
{"path", "/quit"},
|
||||
{"method", "POST"}
|
||||
});
|
||||
|
||||
res.set_content(content_json.dump(4),
|
||||
"text/json");
|
||||
});
|
||||
|
||||
for (const auto& e : endpoints_) {
|
||||
const auto fn = ([this, &e]() -> httplib::Server& (httplib::Server::*)(const std::string&, httplib::Server::Handler) {
|
||||
switch (e.method) {
|
||||
case POST:
|
||||
return &httplib::Server::Post;
|
||||
case PUT:
|
||||
return &httplib::Server::Put;
|
||||
case PATCH:
|
||||
return &httplib::Server::Patch;
|
||||
default:
|
||||
return &httplib::Server::Get;
|
||||
}
|
||||
})();
|
||||
|
||||
(server_.*fn)(e.path, [this, &e, &setCorsHeader](const httplib::Request& req, httplib::Response& res) {
|
||||
setCorsHeader(res);
|
||||
res.status = 0;
|
||||
res.content_length_ = 0;
|
||||
try {
|
||||
e.handler(req, res);
|
||||
}
|
||||
catch (std::exception& err) {
|
||||
spdlog::error("Exception in http handler: {}", err.what());
|
||||
res.status = res.status == 0 ? 500 : res.status;
|
||||
if (res.content_length_ == 0) {
|
||||
res.set_content(nlohmann::json{
|
||||
{"code", res.status},
|
||||
{"name", "HandlerError"},
|
||||
{"message", err.what()},
|
||||
}
|
||||
.dump(),
|
||||
"text/json");
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
res.status = 500;
|
||||
res.set_content(nlohmann::json{
|
||||
{"code", res.status},
|
||||
{"name", "Internal Server Error"},
|
||||
{"message", "Unknown Error"},
|
||||
}
|
||||
.dump(),
|
||||
"text/json");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
server_.Post("/quit", [this, &setCorsHeader](const httplib::Request& req, httplib::Response& res) {
|
||||
setCorsHeader(res);
|
||||
close_();
|
||||
});
|
||||
|
||||
server_thread_ = std::thread([this]() {
|
||||
if (!server_.listen("0.0.0.0", port_)) {
|
||||
spdlog::error("Couldn't start http-server");
|
||||
return;
|
||||
}
|
||||
spdlog::debug("Started http-server on port {}", static_cast<int>(port_));
|
||||
});
|
||||
}
|
||||
|
||||
void HttpServer::stop()
|
||||
{
|
||||
server_.stop();
|
||||
if (server_thread_.joinable())
|
||||
server_thread_.join();
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
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 <thread>
|
||||
|
||||
#include <httplib.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
class AppLauncher;
|
||||
|
||||
class HttpServer {
|
||||
|
||||
public:
|
||||
explicit HttpServer(std::function<void()> close);
|
||||
|
||||
// C++ enums suck.
|
||||
enum Method {
|
||||
GET,
|
||||
POST,
|
||||
PUT,
|
||||
PATCH,
|
||||
};
|
||||
// but im not in the mood of adding yet another dependency for just that shit here.
|
||||
static std::string ToString(Method m);
|
||||
|
||||
struct Endpoint {
|
||||
std::string path;
|
||||
Method method;
|
||||
std::function<void(const httplib::Request& req, httplib::Response& res)> handler;
|
||||
nlohmann::json response_hint = nullptr;
|
||||
nlohmann::json payload_hint = nullptr;
|
||||
};
|
||||
|
||||
static void AddEndpoint(const Endpoint&& e);
|
||||
|
||||
void run();
|
||||
void stop();
|
||||
|
||||
|
||||
private:
|
||||
httplib::Server server_;
|
||||
std::thread server_thread_;
|
||||
uint16_t port_ = 8756;
|
||||
|
||||
std::function<void()> close_;
|
||||
|
||||
static inline std::vector<Endpoint> endpoints_;
|
||||
|
||||
};
|
@ -1,260 +0,0 @@
|
||||
/*
|
||||
Copyright 2021-2022 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>
|
||||
#endif
|
||||
|
||||
namespace Settings {
|
||||
|
||||
inline struct Launch {
|
||||
bool launch = false;
|
||||
std::wstring launchPath;
|
||||
std::wstring launchAppArgs;
|
||||
bool closeOnExit = true;
|
||||
bool waitForChildProcs = true;
|
||||
bool isUWP = false;
|
||||
} 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;
|
||||
} window;
|
||||
|
||||
inline struct Controller {
|
||||
int maxControllers = 1;
|
||||
bool allowDesktopConfig = false;
|
||||
bool emulateDS4 = false;
|
||||
} controller;
|
||||
|
||||
inline bool extendedLogging = 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;
|
||||
|
||||
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(std::wstring arg1)
|
||||
{
|
||||
const auto config_specified = !std::views::filter(arg1, [](const auto& ch) {
|
||||
return ch != ' ';
|
||||
}).empty();
|
||||
if (config_specified) {
|
||||
if (!arg1.ends_with(L".json")) {
|
||||
arg1 += L".json";
|
||||
}
|
||||
}
|
||||
std::filesystem::path path = std::filesystem::temp_directory_path()
|
||||
.parent_path()
|
||||
.parent_path()
|
||||
.parent_path();
|
||||
|
||||
path /= "Roaming";
|
||||
path /= "GlosSI";
|
||||
if (config_specified) {
|
||||
path /= "Targets";
|
||||
path /= arg1;
|
||||
}
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
const auto json = nlohmann::json::parse(json_file);
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
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());
|
||||
}
|
||||
|
||||
safeParseValue(json, "extendedLogging", extendedLogging);
|
||||
|
||||
json_file.close();
|
||||
|
||||
spdlog::debug("Read config file \"{}\"; config: {}", path.string(), json.dump());
|
||||
|
||||
if (launch.launch) {
|
||||
launch.isUWP = checkIsUwp(launch.launchPath);
|
||||
}
|
||||
}
|
||||
|
||||
inline void StoreSettings()
|
||||
{
|
||||
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["controller"]["maxControllers"] = controller.maxControllers;
|
||||
json["controller"]["allowDesktopConfig"] = controller.allowDesktopConfig;
|
||||
json["controller"]["emulateDS4"] = controller.emulateDS4;
|
||||
|
||||
json["extendedLogging"] = extendedLogging;
|
||||
|
||||
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,55 +0,0 @@
|
||||
/*
|
||||
Copyright 2021-2022 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.
|
||||
*/
|
||||
#include "UnhookUtil.h"
|
||||
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
#include "Settings.h"
|
||||
|
||||
void UnhookUtil::UnPatchHook(const std::string& name, HMODULE module)
|
||||
{
|
||||
spdlog::trace("Patching \"{}\"...", name);
|
||||
|
||||
BYTE* address = reinterpret_cast<BYTE*>(GetProcAddress(module, name.c_str()));
|
||||
if (!address) {
|
||||
spdlog::error("failed to unpatch \"{}\"", name);
|
||||
}
|
||||
std::string bytes;
|
||||
if (Settings::isWin10 && UNHOOK_BYTES_ORIGINAL_WIN10.contains(name)) {
|
||||
bytes = UNHOOK_BYTES_ORIGINAL_WIN10.at(name);
|
||||
}
|
||||
else {
|
||||
bytes = UNHOOK_BYTES_ORIGINAL_22000.at(name);
|
||||
}
|
||||
DWORD dw_old_protect, dw_bkup;
|
||||
const auto len = bytes.size();
|
||||
if (!VirtualProtect(address, len, PAGE_EXECUTE_READWRITE, &dw_old_protect)) { // Change permissions of memory..
|
||||
spdlog::error("Couldn't change permissions of memory for \"{}\"", name);
|
||||
return;
|
||||
}
|
||||
const auto opcode = *(address);
|
||||
if (!std::ranges::any_of(JUMP_INSTR_OPCODES, [&opcode](const auto& op) { return op == opcode; })) {
|
||||
spdlog::debug("\"{}\" Doesn't appear to be hooked, skipping!", name);
|
||||
}
|
||||
else {
|
||||
for (DWORD i = 0; i < len; i++) // unpatch Valve's hook
|
||||
{
|
||||
*(address + i) = bytes[i];
|
||||
}
|
||||
spdlog::trace("Unpatched \"{}\"", name);
|
||||
}
|
||||
VirtualProtect(address, len, dw_old_protect, &dw_bkup); // Revert permission change...
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
/*
|
||||
Copyright 2021-2022 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);
|
||||
|
||||
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...
|
||||
// 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,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,162 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#include <httplib.h>
|
||||
|
||||
#include "../common/util.h"
|
||||
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
#include <spdlog/sinks/basic_file_sink.h>
|
||||
#include <spdlog/sinks/stdout_color_sinks.h>
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
|
||||
#include "../version.hpp"
|
||||
#include "../common/Settings.h"
|
||||
#include "../common/HidHide.h"
|
||||
|
||||
bool IsProcessRunning(DWORD pid)
|
||||
{
|
||||
const HANDLE process = OpenProcess(SYNCHRONIZE, FALSE, pid);
|
||||
if (process == nullptr)
|
||||
return false;
|
||||
const DWORD ret = WaitForSingleObject(process, 0);
|
||||
CloseHandle(process);
|
||||
return ret == WAIT_TIMEOUT;
|
||||
}
|
||||
|
||||
void fetchSettings(httplib::Client& http_client, int retried_count = 0) {
|
||||
http_client.set_connection_timeout(1 + (retried_count > 0 ? 2 : 0));
|
||||
|
||||
auto http_res = http_client.Get("/settings");
|
||||
if (http_res.error() == httplib::Error::Success && http_res->status == 200)
|
||||
{
|
||||
const auto json = nlohmann::json::parse(http_res->body);
|
||||
spdlog::debug("Received settings from GlosSITarget: {}", json.dump());
|
||||
Settings::Parse(json);
|
||||
}
|
||||
else
|
||||
{
|
||||
spdlog::error("Couldn't get settings from GlosSITarget. Error: {}", (int)http_res.error());
|
||||
if (retried_count < 2)
|
||||
{
|
||||
spdlog::info("Retrying... {}", retried_count);
|
||||
fetchSettings(http_client, retried_count + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DWORD WINAPI watchdog(HMODULE hModule)
|
||||
{
|
||||
auto configDirPath = util::path::getDataDirPath();
|
||||
auto logPath = configDirPath;
|
||||
logPath /= "GlosSIWatchdog.log";
|
||||
const auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>(logPath.wstring(), true);
|
||||
std::vector<spdlog::sink_ptr> sinks{ file_sink };
|
||||
auto logger = std::make_shared<spdlog::logger>("log", sinks.begin(), sinks.end());
|
||||
logger->set_level(spdlog::level::trace);
|
||||
logger->flush_on(spdlog::level::trace);
|
||||
spdlog::set_default_logger(logger);
|
||||
|
||||
spdlog::info("GlosSIWatchdog loaded");
|
||||
spdlog::info("Version: {}", version::VERSION_STR);
|
||||
|
||||
auto glossi_hwnd = FindWindowA(nullptr, "GlosSITarget");
|
||||
if (!glossi_hwnd)
|
||||
{
|
||||
spdlog::error("Couldn't find GlosSITarget window. Exiting...");
|
||||
FreeLibraryAndExitThread(hModule, 1);
|
||||
return 1;
|
||||
}
|
||||
spdlog::debug("Found GlosSITarget window; Starting watch loop");
|
||||
|
||||
httplib::Client http_client("http://localhost:8756");
|
||||
|
||||
fetchSettings(http_client);
|
||||
|
||||
std::vector<DWORD> pids;
|
||||
while (glossi_hwnd)
|
||||
{
|
||||
http_client.set_connection_timeout(120);
|
||||
const auto http_res = http_client.Get("/launched-pids");
|
||||
if (http_res.error() == httplib::Error::Success && http_res->status == 200)
|
||||
{
|
||||
const auto json = nlohmann::json::parse(http_res->body);
|
||||
if (Settings::common.extendedLogging)
|
||||
{
|
||||
spdlog::trace("Received pids: {}", json.dump());
|
||||
}
|
||||
pids = json.get<std::vector<DWORD>>();
|
||||
}
|
||||
else {
|
||||
spdlog::error("Couldn't fetch launched PIDs: {}", (int)http_res.error());
|
||||
}
|
||||
|
||||
glossi_hwnd = FindWindowA(nullptr, "GlosSITarget");
|
||||
|
||||
Sleep(333);
|
||||
}
|
||||
spdlog::info("GlosSITarget was closed. Resetting HidHide state...");
|
||||
HidHide hidhide;
|
||||
hidhide.disableHidHide();
|
||||
|
||||
if (Settings::launch.closeOnExit)
|
||||
{
|
||||
spdlog::info("Closing launched processes");
|
||||
|
||||
for (const auto pid : pids)
|
||||
{
|
||||
if (Settings::common.extendedLogging)
|
||||
{
|
||||
spdlog::debug("Checking if process {} is running", pid);
|
||||
}
|
||||
if (IsProcessRunning(pid))
|
||||
{
|
||||
util::win::process::KillProcess(pid);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Settings::common.extendedLogging)
|
||||
{
|
||||
spdlog::debug("Process {} is not running", pid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
spdlog::info("Unloading Watchdog...");
|
||||
FreeLibraryAndExitThread(hModule, 0);
|
||||
}
|
||||
|
||||
BOOL APIENTRY DllMain(HMODULE hModule,
|
||||
DWORD ul_reason_for_call,
|
||||
LPVOID lpReserved
|
||||
)
|
||||
{
|
||||
if (ul_reason_for_call == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
CloseHandle(CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)watchdog, hModule, 0, nullptr));
|
||||
}
|
||||
else if (ul_reason_for_call == DLL_PROCESS_DETACH) {
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
/*
|
||||
Copyright 2021-2022 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.
|
||||
*/
|
||||
|
||||
#define NOMINMAX
|
||||
#include <Windows.h>
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
#include <spdlog/sinks/basic_file_sink.h>
|
||||
#include <spdlog/sinks/stdout_color_sinks.h>
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
#include "../version.hpp"
|
||||
#include "../GlosSITarget/HidHide.h"
|
||||
|
||||
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
|
||||
_In_opt_ HINSTANCE hPrevInstance,
|
||||
_In_ LPWSTR lpCmdLine,
|
||||
_In_ int nCmdShow)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(hPrevInstance);
|
||||
UNREFERENCED_PARAMETER(lpCmdLine);
|
||||
|
||||
auto configDirPath = std::filesystem::temp_directory_path()
|
||||
.parent_path()
|
||||
.parent_path()
|
||||
.parent_path();
|
||||
|
||||
configDirPath /= "Roaming";
|
||||
configDirPath /= "GlosSI";
|
||||
if (!std::filesystem::exists(configDirPath))
|
||||
std::filesystem::create_directories(configDirPath);
|
||||
|
||||
auto logPath = configDirPath;
|
||||
logPath /= "GlosSIWatchdog.log";
|
||||
const auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>(logPath.wstring(), true);
|
||||
std::vector<spdlog::sink_ptr> sinks{ file_sink };
|
||||
auto logger = std::make_shared<spdlog::logger>("log", sinks.begin(), sinks.end());
|
||||
logger->set_level(spdlog::level::trace);
|
||||
logger->flush_on(spdlog::level::trace);
|
||||
spdlog::set_default_logger(logger);
|
||||
|
||||
spdlog::info("GlosSIWatchdog loaded");
|
||||
spdlog::info("Version: {}", version::VERSION_STR);
|
||||
|
||||
auto glossi_hwnd = FindWindowA(nullptr, "GlosSITarget");
|
||||
if (!glossi_hwnd)
|
||||
{
|
||||
spdlog::error("Couldn't find GlosSITarget window. Exiting...");
|
||||
return 1;
|
||||
}
|
||||
spdlog::debug("Found GlosSITarget window; Starting watch loop");
|
||||
|
||||
while (glossi_hwnd)
|
||||
{
|
||||
glossi_hwnd = FindWindowA(nullptr, "GlosSITarget");
|
||||
Sleep(1337);
|
||||
}
|
||||
spdlog::info("GlosSITarget was closed. Cleaning up...");
|
||||
HidHide hidhide;
|
||||
hidhide.disableHidHide();
|
||||
|
||||
return 0;
|
||||
}
|
@ -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
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue