Logs in Overlay / Open Close Overlay on double steam overlay

main
Peter Repukat 3 years ago
parent 9ccc46088a
commit b829c4b680

@ -127,7 +127,7 @@
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>hid.lib;Cfgmgr32.lib;opengl32.lib;sfml-window-d.lib;sfml-system-d.lib;sfml-graphics-d.lib;dwmapi.lib;xinput9_1_0.lib;setupapi.lib;ViGEmClient.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
@ -143,7 +143,7 @@
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
@ -153,7 +153,6 @@
<ItemGroup>
<ClCompile Include="..\deps\imgui-sfml\imgui-SFML.cpp" />
<ClCompile Include="..\deps\imgui\imgui.cpp" />
<ClCompile Include="..\deps\imgui\imgui_demo.cpp" />
<ClCompile Include="..\deps\imgui\imgui_draw.cpp" />
<ClCompile Include="..\deps\imgui\imgui_tables.cpp" />
<ClCompile Include="..\deps\imgui\imgui_widgets.cpp" />
@ -174,6 +173,7 @@
<ClInclude Include="imconfig.h" />
<ClInclude Include="InputRedirector.h" />
<ClInclude Include="Overlay.h" />
<ClInclude Include="OverlayLogSink.h" />
<ClInclude Include="SteamOverlayDetector.h" />
<ClInclude Include="SteamTarget.h" />
<ClInclude Include="steam_sf_keymap.h" />

@ -72,9 +72,6 @@
<ClCompile Include="..\deps\imgui-sfml\imgui-SFML.cpp">
<Filter>Source Files\imgui-sfml</Filter>
</ClCompile>
<ClCompile Include="..\deps\imgui\imgui_demo.cpp">
<Filter>Source Files\imgui</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="SteamTarget.h">
@ -110,6 +107,9 @@
<ClInclude Include="..\deps\imgui-sfml\imgui-SFML.h">
<Filter>Header Files\imgui-sfml</Filter>
</ClInclude>
<ClInclude Include="OverlayLogSink.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\deps\SFML\out\build\x64-Debug\lib\sfml-system-d-2.dll" />

@ -53,6 +53,7 @@ void InputRedirector::run()
void InputRedirector::stop()
{
run_ = false;
controller_thread_.join();
if (vigem_connected_) {
for (const auto& target : vt_x360_) {
vigem_target_remove(driver_, target);

@ -1,9 +1,8 @@
#include "Overlay.h"
#define IMGUI_USER_CONFIG "imconfig.h"
#include "imgui.h"
#include "imgui-SFML.h"
#include "imgui.h"
Overlay::Overlay(sf::RenderWindow& window, std::function<void()> on_close) : window_(window), on_close_(on_close)
{
@ -84,6 +83,12 @@ void Overlay::setEnabled(bool enabled)
enabled_ = enabled;
}
bool Overlay::isEnabled() const
{
return enabled_;
}
bool Overlay::toggle()
{
enabled_ = !enabled_;
@ -94,14 +99,16 @@ void Overlay::update()
{
ImGui::SFML::Update(window_, update_clock_.restart());
bool open = true;
showLogs();
if (enabled_) {
window_.clear(sf::Color(0, 0, 0, 64)); // make window slightly dim screen with overlay
ImGui::ShowDemoWindow(&open);
if (closeButton()) {
return;
}
}
}
ImGui::SFML::Render(window_);
@ -117,15 +124,61 @@ void Overlay::Shutdown()
ImGui::SFML::Shutdown();
}
void Overlay::ShowNotification(std::string noti_text)
{}
void Overlay::ShowNotification(const spdlog::details::log_msg& msg)
{
LOG_MSGS_.push_back({.time = msg.time, .level = msg.level, .payload = msg.payload.data()});
}
void Overlay::showLogs() const
{
std::vector<Log> logs;
if (enabled_) {
logs = LOG_MSGS_;
}
else {
std::ranges::copy_if(LOG_MSGS_,
std::back_inserter(logs),
[](const auto& log) {
return log.time.time_since_epoch() + std::chrono::seconds(LOG_RETENTION_TIME_) > std::chrono::system_clock::now().time_since_epoch();
});
}
if (logs.empty())
return;
if (!enabled_) {
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, {32.f, 32.f});
ImGui::Begin("Log", nullptr,
ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoTitleBar);
}
else {
ImGui::Begin("Log", nullptr);
}
std::ranges::for_each(LOG_MSGS_, [](const auto& msg) {
switch (msg.level) {
case spdlog::level::warn:
ImGui::TextColored({1.f, 0.8f, 0.f, 1.f}, msg.payload.data());
break;
case spdlog::level::err:
ImGui::TextColored({.8f, 0.0f, 0.f, 1.f}, msg.payload.data());
break;
case spdlog::level::debug:
ImGui::TextColored({.8f, 0.8f, 0.8f, .9f}, msg.payload.data());
break;
default:
ImGui::Text(msg.payload.data());
}
});
ImGui::End();
if (!enabled_) {
ImGui::PopStyleVar();
}
}
bool Overlay::closeButton() const
{
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, {0, 0});
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.0f, 0.f, 0.f, 0.0f));
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0.6f, 0.f, 0.f, 0.9f));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered,ImVec4(1.f, 0.16f, 0.16f, 1.00f));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(1.f, 0.16f, 0.16f, 1.00f));
ImGui::Begin("##CloseButton", nullptr, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize);
ImGui::SetWindowSize({56 + 24, 32 + 24});
ImGui::SetWindowPos({window_.getSize().x - ImGui::GetWindowWidth() + 24, -24});

@ -3,21 +3,34 @@
#include <string>
#include <SFML/Graphics.hpp>
#include <spdlog/spdlog.h>
class Overlay {
public:
Overlay(sf::RenderWindow& window, std::function<void()> on_close);
void setEnabled(bool enabled);
bool isEnabled() const;
bool toggle();
void update();
static void ProcessEvent(sf::Event evnt);
static void Shutdown();
static void ShowNotification(std::string noti_text);
static void ShowNotification(const spdlog::details::log_msg& msg);
private:
sf::RenderWindow& window_;
sf::Clock update_clock_;
bool enabled_ = true;
std::function<void()> on_close_;
void showLogs() const;
bool closeButton() const;
struct Log {
std::chrono::system_clock::time_point time;
spdlog::level::level_enum level;
std::string payload;
};
static inline std::vector<Log> LOG_MSGS_;
static constexpr int LOG_RETENTION_TIME_ = 5;
};

@ -0,0 +1,40 @@
#pragma once
#include "Overlay.h"
namespace spdlog {
namespace sinks {
template <typename Mutex>
class overlay_sink : public spdlog::sinks::base_sink<Mutex> {
public:
overlay_sink() = default;
protected:
void sink_it_(const spdlog::details::log_msg& msg) override
{
Overlay::ShowNotification(msg);
}
void flush_() override
{
// Do nothing because statement executed in sink_it_().
}
void set_pattern_(const std::string& pattern) override
{
// Don't format log message.
}
void set_formatter_(std::unique_ptr<spdlog::formatter> sink_formatter) override
{
// Don't format log message.
}
};
using overlay_sink_mt = overlay_sink<std::mutex>;
} // namespace sinks
} // namespace spdlog

@ -67,4 +67,11 @@ void SteamOverlayDetector::update()
}
}
#endif
}
}
bool SteamOverlayDetector::IsSteamInjected()
{
#ifdef _WIN32
return GetModuleHandle(L"GameOverlayRenderer64.dll") != nullptr;
#endif
}

@ -27,6 +27,7 @@ class SteamOverlayDetector {
explicit SteamOverlayDetector(
std::function<void(bool)> overlay_changed = [](bool) {});
void update();
static bool IsSteamInjected();
private:
std::function<void(bool)> overlay_changed_;

@ -35,12 +35,16 @@ SteamTarget::SteamTarget(int argc, char* argv[])
int SteamTarget::run()
{
// TODO: Hide GlosSI overlay not based on time, but on game launch.
sf::Clock mock_clock;
bool mock_clock_flag = SteamOverlayDetector::IsSteamInjected();
if (!mock_clock_flag) {
spdlog::warn("Steam Overlay not detected. Keeping GlosSI Overlay!\n\
if (!SteamOverlayDetector::IsSteamInjected()) {
spdlog::warn("Steam-overlay not detected. Showing GlosSI-overlay!\n\
Application will not function!");
window_.setClickThrough(false);
overlay_.setEnabled(true);
} else {
spdlog::info("Steam-overlay detected.");
spdlog::warn("Open/Close Steam-overlay twice to show GlosSI-overlay"); // Just to color output and really get users attention
window_.setClickThrough(true);
overlay_.setEnabled(false);
}
run_ = true;
@ -52,11 +56,6 @@ Application will not function!");
keepControllerConfig(true);
while (run_) {
if (mock_clock_flag && mock_clock.getElapsedTime().asSeconds() > 5) {
window_.setClickThrough(true);
overlay_.setEnabled(false);
mock_clock_flag = false;
}
detector_.update();
window_.update();
overlayHotkeyWorkaround();
@ -72,7 +71,6 @@ Application will not function!");
void SteamTarget::onOverlayChanged(bool overlay_open)
{
window_.setClickThrough(!overlay_open);
if (overlay_open) {
focusWindow(target_window_handle_);
}
@ -84,12 +82,22 @@ void SteamTarget::onOverlayChanged(bool overlay_open)
}
else {
if (overlay_trigger_clock_.getElapsedTime().asSeconds() <= overlay_trigger_max_seconds_) {
window_.setClickThrough(!overlay_.toggle());
const auto ov_opened = overlay_.toggle();
window_.setClickThrough(!ov_opened);
if (ov_opened) {
spdlog::info("Opened GlosSI-overlay");
focusWindow(target_window_handle_);
} else {
focusWindow(last_foreground_window_);
spdlog::info("Closed GlosSI-overlay");
}
}
overlay_trigger_flag_ = false;
}
focusWindow(last_foreground_window_);
if (!overlay_.isEnabled()) {
window_.setClickThrough(!overlay_open);
focusWindow(last_foreground_window_);
}
}
}
@ -98,19 +106,23 @@ void SteamTarget::focusWindow(WindowHandle hndl)
#ifdef _WIN32
if (hndl == target_window_handle_) {
spdlog::info("Bring own window to foreground");
spdlog::debug("Bring own window to foreground");
}
else {
spdlog::info("Bring window \"{:#x}\" to foreground", reinterpret_cast<uint64_t>(hndl));
spdlog::debug("Bring window \"{:#x}\" to foreground", reinterpret_cast<uint64_t>(hndl));
}
keepControllerConfig(false); // unhook GetForegroundWindow
last_foreground_window_ = GetForegroundWindow();
const DWORD fg_thread = GetWindowThreadProcessId(last_foreground_window_, nullptr);
const auto current_fgw = GetForegroundWindow();
if (current_fgw != target_window_handle_) {
last_foreground_window_ = current_fgw;
}
const auto fg_thread = GetWindowThreadProcessId(current_fgw, nullptr);
keepControllerConfig(true); // re-hook GetForegroundWindow
// lot's of ways actually bringing our window to foreground...
const DWORD current_thread = GetCurrentThreadId();
const auto current_thread = GetCurrentThreadId();
AttachThreadInput(current_thread, fg_thread, TRUE);
SetForegroundWindow(hndl);
@ -231,14 +243,14 @@ void SteamTarget::keepControllerConfig(bool keep)
{
#ifdef _WIN32
if (keep && !getFgWinHook.IsInstalled()) {
spdlog::debug("Hooking GetForegroudnWindow (in own process)");
spdlog::debug("Hooking GetForegroundWindow (in own process)");
getFgWinHook.Install(&GetForegroundWindow, &keepFgWindowHookFn, subhook::HookFlags::HookFlag64BitOffset);
if (!getFgWinHook.IsInstalled()) {
spdlog::error("Couldn't install GetForegroundWindow hook!");
}
}
else if (!keep && getFgWinHook.IsInstalled()) {
spdlog::debug("Un-Hooking GetForegroudnWindow (in own process)");
spdlog::debug("Un-Hooking GetForegroundWindow (in own process)");
getFgWinHook.Remove();
if (getFgWinHook.IsInstalled()) {
spdlog::error("Couldn't un-install GetForegroundWindow hook!");
@ -261,7 +273,7 @@ void SteamTarget::overlayHotkeyWorkaround()
[](const auto& key) {
return sf::Keyboard::isKeyPressed(keymap::sfkey[key]);
})) {
spdlog::debug("Detected overlay hotkey(s)");
spdlog::trace("Detected overlay hotkey(s)");
pressed = true;
std::ranges::for_each(overlay_hotkey_, [this](const auto& key) {
#ifdef _WIN32
@ -270,7 +282,7 @@ void SteamTarget::overlayHotkeyWorkaround()
#endif
});
spdlog::debug("Sending Overlay KeyDown events...");
spdlog::trace("Sending Overlay KeyDown events...");
}
else if (pressed) {
pressed = false;
@ -281,6 +293,6 @@ void SteamTarget::overlayHotkeyWorkaround()
#endif
});
spdlog::debug("Sending Overlay KeyUp events...");
spdlog::trace("Sending Overlay KeyUp events...");
}
}

@ -23,8 +23,9 @@ limitations under the License.
#include <spdlog/sinks/basic_file_sink.h>
#include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/spdlog.h>
#include "OverlayLogSink.h"
#define CONSOLE
#ifdef _WIN32
#ifdef CONSOLE
int main(int argc, char* argv[])
@ -47,7 +48,15 @@ int main(int argc, char* argv[])
auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>("/tmp/glossitarget.log", true);
#endif
file_sink->set_level(spdlog::level::trace);
std::vector<spdlog::sink_ptr> sinks{file_sink, console_sink};
const auto overlay_sink = std::make_shared<spdlog::sinks::overlay_sink_mt>();
#ifdef _DEBUG
overlay_sink->set_level(spdlog::level::debug); // TODO: make configurable
#else
overlay_sink->set_level(spdlog::level::info);
#endif
std::vector<spdlog::sink_ptr> sinks{file_sink, console_sink, overlay_sink};
auto logger = std::make_shared<spdlog::logger>("log", sinks.begin(), sinks.end());
logger->set_level(spdlog::level::trace);
logger->flush_on(spdlog::level::info);

Loading…
Cancel
Save