diff --git a/ImGui/imconfig.h b/ImGui/imconfig.h
index 2b771298..712b03cf 100644
--- a/ImGui/imconfig.h
+++ b/ImGui/imconfig.h
@@ -27,12 +27,12 @@
//---- Don't implement demo windows functionality (ShowDemoWindow()/ShowStyleEditor()/ShowUserGuide() methods will be empty)
// It is very strongly recommended to NOT disable the demo windows during development. Please read the comments in imgui_demo.cpp.
-//#define IMGUI_DISABLE_DEMO_WINDOWS
-//#define IMGUI_DISABLE_METRICS_WINDOW
+#define IMGUI_DISABLE_DEMO_WINDOWS
+#define IMGUI_DISABLE_METRICS_WINDOW
//---- Don't implement some functions to reduce linkage requirements.
//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc.
-//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] Don't implement default IME handler. Won't use and link with ImmGetContext/ImmSetCompositionWindow.
+#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] Don't implement default IME handler. Won't use and link with ImmGetContext/ImmSetCompositionWindow.
//#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, ime).
//#define IMGUI_DISABLE_OSX_FUNCTIONS // [OSX] Won't use and link with any OSX function (clipboard).
//#define IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself if you don't want to link with vsnprintf.
@@ -91,3 +91,6 @@ namespace ImGui
void MyFunction(const char* name, const MyMatrix44& v);
}
*/
+
+#define GLEW_STATIC
+#define IMGUI_IMPL_OPENGL_LOADER_GLEW
\ No newline at end of file
diff --git a/dll/steam_client.cpp b/dll/steam_client.cpp
index ddc12f38..3bab4f8f 100644
--- a/dll/steam_client.cpp
+++ b/dll/steam_client.cpp
@@ -303,7 +303,7 @@ Steam_Client::Steam_Client()
PRINT_DEBUG("steam client init: id: %llu server id: %llu appid: %u port: %u \n", user_id.ConvertToUint64(), settings_server->get_local_steam_id().ConvertToUint64(), appid, port);
- steam_overlay = new Steam_Overlay(settings_client, callback_results_client, callbacks_client, run_every_runcb);
+ steam_overlay = new Steam_Overlay(settings_client, callback_results_client, callbacks_client, run_every_runcb, network);
steam_user = new Steam_User(settings_client, local_storage, network, callback_results_client, callbacks_client);
steam_friends = new Steam_Friends(settings_client, network, callback_results_client, callbacks_client, run_every_runcb, steam_overlay);
diff --git a/dll/steam_friends.h b/dll/steam_friends.h
index 7d1992fb..dda67f15 100644
--- a/dll/steam_friends.h
+++ b/dll/steam_friends.h
@@ -15,7 +15,11 @@
License along with the Goldberg Emulator; if not, see
. */
+#ifndef __INCLUDED_STEAM_FRIENDS_H__
+#define __INCLUDED_STEAM_FRIENDS_H__
+
#include "base.h"
+#include "../overlay_experimental/steam_overlay.h"
#define SEND_FRIEND_RATE 4.0
@@ -113,6 +117,8 @@ Steam_Friends(Settings* settings, Networking* network, SteamCallResults* callbac
this->network->setCallback(CALLBACK_ID_USER_STATUS, settings->get_local_steam_id(), &Steam_Friends::steam_friends_callback, this);
this->run_every_runcb->add(&Steam_Friends::steam_friends_run_every_runcb, this);
modified = false;
+
+ overlay->SetupFriends(&friends);
}
~Steam_Friends()
@@ -491,6 +497,7 @@ void SetInGameVoiceSpeaking( CSteamID steamIDUser, bool bSpeaking )
void ActivateGameOverlay( const char *pchDialog )
{
PRINT_DEBUG("Steam_Friends::ActivateGameOverlay %s\n", pchDialog);
+ overlay->OpenOverlay(pchDialog);
}
@@ -547,7 +554,7 @@ void SetPlayedWith( CSteamID steamIDUserPlayedWith )
void ActivateGameOverlayInviteDialog( CSteamID steamIDLobby )
{
PRINT_DEBUG("Steam_Friends::ActivateGameOverlayInviteDialog\n");
- // TODO: Here open the overlay
+ overlay->OpenOverlayInvite(steamIDLobby);
}
// gets the small (32x32) avatar of the current user, which is a handle to be used in IClientUtils::GetImageRGBA(), or 0 if none set
@@ -1048,3 +1055,5 @@ void Callback(Common_Message *msg)
}
};
+
+#endif//__INCLUDED_STEAM_FRIENDS_H__
\ No newline at end of file
diff --git a/overlay_experimental/steam_overlay.cpp b/overlay_experimental/steam_overlay.cpp
new file mode 100644
index 00000000..c6aba7c3
--- /dev/null
+++ b/overlay_experimental/steam_overlay.cpp
@@ -0,0 +1,528 @@
+#include "steam_overlay.h"
+
+#include
+#include
+#include
+#include
+#include
+
+#include // iota
+
+extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
+
+static decltype(DispatchMessageA)* _DispatchMessageA = DispatchMessageA;
+static decltype(DispatchMessageW)* _DispatchMessageW = DispatchMessageW;
+
+LRESULT CALLBACK Steam_Overlay::sHookWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ return Hook_Manager::Inst().GetOverlay()->HookWndProc(hWnd, uMsg, wParam, lParam);
+}
+
+LRESULT Steam_Overlay::HookWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ // Is the event is a key press
+ if (uMsg == WM_KEYDOWN)
+ {
+ // Tab is pressed and was not pressed before
+ if (wParam == VK_TAB && !(lParam & (1 << 30)))
+ {
+ // If Left Shift is pressed
+ if (GetAsyncKeyState(VK_LSHIFT) & (1 << 15))
+ ShowOverlay(!show_overlay);
+ }
+
+ }
+ // If we should show the overlay
+ if (show_overlay)
+ {
+ // Call the overlay window procedure
+ ImGui_ImplWin32_WndProcHandler(hWnd, uMsg, wParam, lParam);
+ return true;
+ }
+ // Else call the game window procedure
+ return CallWindowProc(game_hwnd_proc, hWnd, uMsg, wParam, lParam);
+}
+
+bool Steam_Overlay::IgnoreMsg(const MSG* lpMsg)
+{
+ if (lpMsg->hwnd == game_hwnd && show_overlay)
+ {
+ switch (lpMsg->message)
+ {
+ case WM_MOUSEMOVE:
+ case WM_MOUSEWHEEL: case WM_MOUSEHWHEEL:
+ case WM_LBUTTONUP: case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK:
+ case WM_RBUTTONUP: case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK:
+ case WM_MBUTTONUP: case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK:
+ case WM_XBUTTONUP: case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK:
+ case WM_KEYDOWN: case WM_KEYUP:
+ case WM_SYSKEYDOWN: case WM_SYSKEYUP:
+ case WM_CHAR:
+ // We ignore theses message in the game windows, but our overlay needs them.
+ HookWndProc(lpMsg->hwnd, lpMsg->message, lpMsg->wParam, lpMsg->lParam);
+ return true;
+ }
+ }
+ return false;
+}
+
+LRESULT WINAPI Steam_Overlay::MyDispatchMessageA(const MSG* lpMsg)
+{
+ Steam_Overlay* _this = Hook_Manager::Inst().GetOverlay();
+ if (_this->IgnoreMsg(lpMsg))
+ return 0;
+ return _DispatchMessageA(lpMsg);
+}
+
+LRESULT WINAPI Steam_Overlay::MyDispatchMessageW(const MSG* lpMsg)
+{
+ Steam_Overlay* _this = Hook_Manager::Inst().GetOverlay();
+ if (_this->IgnoreMsg(lpMsg))
+ return 0;
+ return _DispatchMessageW(lpMsg);
+}
+
+Steam_Overlay::Steam_Overlay(Settings* settings, SteamCallResults* callback_results, SteamCallBacks* callbacks, RunEveryRunCB* run_every_runcb, Networking *network) :
+ settings(settings),
+ callback_results(callback_results),
+ callbacks(callbacks),
+ run_every_runcb(run_every_runcb),
+ network(network),
+ game_hwnd(NULL),
+ game_hwnd_proc(nullptr),
+ show_overlay(false),
+ is_ready(false),
+ notif_position(ENotificationPosition::k_EPositionBottomLeft),
+ h_inset(0),
+ v_inset(0),
+ friend_action(friend_action_none),
+ overlay_state_changed(false)
+{
+ run_every_runcb->add(&Steam_Overlay::steam_overlay_run_every_runcb, this);
+}
+
+Steam_Overlay::~Steam_Overlay()
+{
+ run_every_runcb->remove(&Steam_Overlay::steam_overlay_run_every_runcb, this);
+}
+
+void Steam_Overlay::steam_overlay_run_every_runcb(void* object)
+{
+ Steam_Overlay* _this = reinterpret_cast(object);
+ _this->RunCallbacks();
+}
+
+HWND Steam_Overlay::GetGameHwnd() const
+{
+ return game_hwnd;
+}
+
+bool Steam_Overlay::Ready() const
+{
+ return is_ready;
+}
+
+bool Steam_Overlay::NeedPresent() const
+{
+ return true;
+}
+
+void Steam_Overlay::SetNotificationPosition(ENotificationPosition eNotificationPosition)
+{
+ notif_position = eNotificationPosition;
+}
+
+void Steam_Overlay::SetNotificationInset(int nHorizontalInset, int nVerticalInset)
+{
+ h_inset = nHorizontalInset;
+ v_inset = nVerticalInset;
+}
+
+void Steam_Overlay::SetupOverlay()
+{
+ Hook_Manager::Inst().HookRenderer(this);
+}
+
+void Steam_Overlay::HookReady(void* hWnd)
+{
+ if (game_hwnd != hWnd)
+ {
+ if (!is_ready) // If this is the first time we are ready, hook the window dispatch message, so we can intercept em and disable mouse.
+ {
+ window_hooks.BeginHook();
+
+ window_hooks.HookFuncs(std::make_pair(&(PVOID&)_DispatchMessageA, &Steam_Overlay::MyDispatchMessageA),
+ std::make_pair(&(PVOID&)_DispatchMessageW, &Steam_Overlay::MyDispatchMessageW)
+ // Add XInput and DirectInput hooks to catch all mouse & controllers input when overlay is on
+ );
+
+ window_hooks.EndHook();
+
+ is_ready = true;
+ }
+
+ if (game_hwnd)
+ SetWindowLongPtr(game_hwnd, GWLP_WNDPROC, (LONG_PTR)game_hwnd_proc);
+
+ game_hwnd = (HWND)hWnd;
+ game_hwnd_proc = (WNDPROC)SetWindowLongPtr(game_hwnd, GWLP_WNDPROC, (LONG_PTR)&Steam_Overlay::sHookWndProc);
+ }
+}
+
+// https://niemand.com.ar/2019/01/01/how-to-hook-directx-11-imgui/
+// https://github.com/spazzarama/Direct3DHook/blob/master/Capture/Hook
+// https://github.com/unknownv2/LinuxDetours
+
+void Steam_Overlay::SetupFriends(const std::vector* friends)
+{
+ this->friends = friends;
+}
+
+void Steam_Overlay::OpenOverlayInvite(CSteamID lobbyId)
+{
+ //this->lobbyId = lobbyId;
+ show_overlay = true;
+}
+
+void Steam_Overlay::OpenOverlay(const char* pchDialog)
+{
+ // TODO: Show pages depending on pchDialog
+ show_overlay = true;
+}
+
+void Steam_Overlay::ShowOverlay(bool state)
+{
+ static RECT old_clip;
+
+ if (show_overlay == state)
+ return;
+
+ show_overlay = state;
+ if (show_overlay)
+ {
+ RECT cliRect, wndRect, clipRect;
+
+ GetClipCursor(&old_clip);
+ // The window rectangle has borders and menus counted in the size
+ GetWindowRect(game_hwnd, &wndRect);
+ // The client rectangle is the window without borders
+ GetClientRect(game_hwnd, &cliRect);
+
+ clipRect = wndRect; // Init clip rectangle
+
+ // Get Window width with borders
+ wndRect.right -= wndRect.left;
+ // Get Window height with borders & menus
+ wndRect.bottom -= wndRect.top;
+ // Compute the border width
+ int borderWidth = (wndRect.right - cliRect.right) / 2;
+ // Client top clip is the menu bar width minus bottom border
+ clipRect.top += wndRect.bottom - cliRect.bottom - borderWidth;
+ // Client left clip is the left border minus border width
+ clipRect.left += borderWidth;
+ // Here goes the same for right and bottom
+ clipRect.right -= borderWidth;
+ clipRect.bottom -= borderWidth;
+
+ ClipCursor(&clipRect);
+
+ ImGui::GetIO().MouseDrawCursor = true;
+ }
+ else
+ {
+ ClipCursor(&old_clip);
+ ImGui::GetIO().MouseDrawCursor = false;
+ }
+ overlay_state_changed = true;
+}
+
+void Steam_Overlay::OverlayProc( int width, int height )
+{
+ if (!show_overlay)
+ return;
+
+ int friend_size = friends->size();
+
+ // Set the overlay windows to the size of the game window
+ ImGui::SetNextWindowPos({ 0,0 });
+ ImGui::SetNextWindowSize({ static_cast(width),
+ static_cast(height) });
+
+ bool close = false;
+ if (ImGui::Begin("SteamOverlay", &close, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse))
+ {
+ ImGui::LabelText("", "Username: %s(%llu) playing %u",
+ settings->get_local_name(),
+ settings->get_local_steam_id().ConvertToUint64(),
+ settings->get_local_game_id().AppID());
+
+ ImGui::Spacing();
+
+ ImGui::ListBoxHeader("Friends", friend_size);
+ if (friend_size)
+ {
+ for (int i = 0; i < friend_size; ++i)
+ {
+ ImGui::PushID(i);
+ ImGui::Selectable(friends->at(i).name().c_str(), false, ImGuiSelectableFlags_AllowDoubleClick);
+ if (ImGui::BeginPopupContextItem("Friends", 1))
+ {
+ if (ImGui::Button("Invite"))
+ {
+ friend_action |= friend_action_invite;
+ friend_to_action = friends->at(i).id();
+ }
+ if (ImGui::Button("Join"))
+ {
+ friend_action |= friend_action_join;
+ friend_to_action = friends->at(i).id();
+ }
+ ImGui::EndPopup();
+ }
+ else if (ImGui::IsMouseDoubleClicked(0))
+ {
+ // Here handle the chat with the user friends->at(i).id()
+ }
+ ImGui::PopID();
+ }
+ }
+ ImGui::ListBoxFooter();
+
+ //RECT rect;
+ //GetWindowRect(game_hwnd, &rect);
+ //auto pos = ImGui::GetMousePos();
+ //ImGui::LabelText("", "Window pos: %dx%d %dx%d", rect.left, rect.top, rect.right, rect.bottom);
+ //ImGui::LabelText("", "Mouse pos: %dx%d", (int)pos.x, (int)pos.y);
+
+
+ ImGui::End();
+ }
+
+ //ImGui::ShowDemoWindow();
+}
+
+#include "../dll/dll.h"
+
+void Steam_Overlay::RunCallbacks()
+{
+ if (overlay_state_changed)
+ {
+ GameOverlayActivated_t data = { 0 };
+ data.m_bActive = show_overlay;
+ callbacks->addCBResult(data.k_iCallback, &data, sizeof(data));
+
+ overlay_state_changed = false;
+ }
+
+ if (friend_action & friend_action_invite)
+ {
+ Common_Message msg;
+ Friend_Messages* friend_messages = new Friend_Messages();
+ friend_messages->set_type(Friend_Messages::LOBBY_INVITE);
+ friend_messages->set_lobby_id(settings->get_lobby().ConvertToUint64());
+ msg.set_allocated_friend_messages(friend_messages);
+ msg.set_source_id(settings->get_local_steam_id().ConvertToUint64());
+ msg.set_dest_id(friend_to_action);
+ network->sendTo(&msg, true);
+
+ friend_action &= ~friend_action_invite;
+ }
+
+ if (friend_action & friend_action_join)
+ {
+ FriendGameInfo_t friend_info = {};
+ Steam_Friends* steamFriends = get_steam_client()->steam_friends;
+ steamFriends->GetFriendGamePlayed(friend_to_action, &friend_info);
+ //get_steam_client()->steam_matchmaking->JoinLobby(friend_info.m_steamIDLobby);
+
+ const char* connect = steamFriends->GetFriendRichPresence(friend_to_action, "connect");
+ GameRichPresenceJoinRequested_t data = {};
+ data.m_steamIDFriend.SetFromUint64(friend_to_action);
+ strncpy(data.m_rgchConnect, connect, k_cchMaxRichPresenceValueLength - 1);
+ callbacks->addCBResult(data.k_iCallback, &data, sizeof(data));
+
+
+ friend_action &= ~friend_action_join;
+ }
+}
+
+ /*
+ switchstr(args[0])
+ {
+ casestr("get"):
+ sstr << "Steam ID: " << _this->_client->settings_client->get_local_steam_id().ConvertToUint64() << std::endl;
+ sstr << "Steam Server ID: " << _this->_client->settings_server->get_local_steam_id().ConvertToUint64() << std::endl;
+ sstr << "Your lobby: " << _this->_client->settings_client->get_lobby().ConvertToUint64() << std::endl;
+ ovlay.write(sstr.str());
+ sstr.str("");
+ break;
+
+ casestr("get_id") :
+ sstr << _this->_client->settings_client->get_local_steam_id().ConvertToUint64() << std::endl;
+ ovlay.write(sstr.str());
+ sstr.str("");
+ break;
+
+ casestr("get_server_id") :
+ sstr << _this->_client->settings_server->get_local_steam_id().ConvertToUint64() << std::endl;
+ ovlay.write(sstr.str());
+ sstr.str("");
+ break;
+
+ casestr("get_lobby") :
+ sstr << "Your lobby: " << _this->_client->settings_client->get_lobby().ConvertToUint64() << std::endl;
+ ovlay.write(sstr.str());
+ sstr.str("");
+ break;
+
+ casestr("list_friends") :
+ {
+ ovlay.write(str + "\n");
+
+ int cnt = steamFriends->GetFriendCount(0);
+ for (int i = 0; i < cnt; ++i)
+ {
+ CSteamID id = steamFriends->GetFriendByIndex(i, 0);
+ const char* name = steamFriends->GetFriendPersonaName(id);
+
+ FriendGameInfo_t friend_info = {};
+ steamFriends->GetFriendGamePlayed(id, &friend_info);
+ sstr << id.ConvertToUint64() << '(' << name << ") is playing: " << friend_info.m_gameID.AppID() << std::endl;
+ ovlay.write(sstr.str());
+ }
+ }
+ break;
+ casestr("list_games") :
+ {
+ ovlay.write(str + "\n");
+
+ int cnt = steamFriends->GetFriendCount(0);
+ for (int i = 0; i < cnt; ++i)
+ {
+ CSteamID id = steamFriends->GetFriendByIndex(i, 0);
+ const char* name = steamFriends->GetFriendPersonaName(id);
+
+ std::string connect = steamFriends->GetFriendRichPresence(id, "connect");
+ FriendGameInfo_t friend_info = {};
+ steamFriends->GetFriendGamePlayed(id, &friend_info);
+
+ if (connect.length() > 0)
+ {
+ sstr << friend_info.m_gameID.AppID() << "\t" << name << "\t" << connect << std::endl;
+ }
+ else if (friend_info.m_steamIDLobby != k_steamIDNil)
+ {
+ connect = "+connect_lobby " + std::to_string(friend_info.m_steamIDLobby.ConvertToUint64());
+ sstr << friend_info.m_gameID.AppID() << "\t" << name << "\t" << connect << std::endl;
+ }
+ ovlay.write(sstr.str());
+ sstr.str("");
+ }
+ }
+ break;
+
+ casestr("invite_user") :
+ {
+ ovlay.write(str + "\n");
+
+ if (_this->lobbyID.IsValid())
+ {
+ if (args.size() == 2)
+ {
+ std::string& friendName = args[1];
+ int cnt = steamFriends->GetFriendCount(0);
+ for (int i = 0; i < cnt; ++i)
+ {
+ CSteamID id = steamFriends->GetFriendByIndex(i, 0);
+ const char* name = steamFriends->GetFriendPersonaName(id);
+
+ if (friendName == name)
+ {
+ Common_Message msg;
+ Friend_Messages* friend_messages = new Friend_Messages();
+ friend_messages->set_type(Friend_Messages::LOBBY_INVITE);
+ friend_messages->set_lobby_id(_this->lobbyID.ConvertToUint64());
+ msg.set_allocated_friend_messages(friend_messages);
+ msg.set_source_id(_this->_client->settings_client->get_local_steam_id().ConvertToUint64());
+ msg.set_dest_id(id.ConvertToUint64());
+ _this->_client->network->sendTo(&msg, true);
+
+ sstr << "Invite sent" << std::endl;
+ ovlay.write(sstr.str());
+ break;
+ }
+ }
+
+ }
+ else
+ {
+ sstr << "'invite_user' needs only 1 parameter: friendname" << std::endl;
+ ovlay.write(sstr.str());
+ }
+ }
+ }
+ break;
+
+ casestr("join_game") :
+ if (args.size() == 2)
+ {
+ ovlay.write(str + "\n");
+ int cnt = steamFriends->GetFriendCount(0);
+ for (int i = 0; i < cnt; ++i)
+ {
+ CSteamID id = steamFriends->GetFriendByIndex(i, 0);
+ const char* name = steamFriends->GetFriendPersonaName(id);
+
+ std::string connect = steamFriends->GetFriendRichPresence(id, "connect");
+ FriendGameInfo_t friend_info = {};
+ steamFriends->GetFriendGamePlayed(id, &friend_info);
+
+ if (connect.length() > 0)
+ {
+ sstr << "1: " << friend_info.m_gameID.AppID() << "\t" << name << "\t" << connect << std::endl;
+ }
+ else if (std::to_string(friend_info.m_steamIDLobby.ConvertToUint64()) == args[1])
+ {
+ connect = "connect " + std::to_string(friend_info.m_steamIDLobby.ConvertToUint64());
+ sstr << "2: " << friend_info.m_gameID.AppID() << "\t" << name << "\t" << connect << std::endl;
+ matchMaking->JoinLobby(friend_info.m_steamIDLobby);
+ }
+ ovlay.write(sstr.str());
+ sstr.str("");
+ }
+ }
+ break;
+
+ casestr("join_user") :
+ if (args.size() == 2)
+ {
+ ovlay.write(str + "\n");
+ int cnt = steamFriends->GetFriendCount(0);
+ for (int i = 0; i < cnt; ++i)
+ {
+ CSteamID id = steamFriends->GetFriendByIndex(i, 0);
+ const char* name = steamFriends->GetFriendPersonaName(id);
+
+ std::string connect = steamFriends->GetFriendRichPresence(id, "connect");
+ FriendGameInfo_t friend_info = {};
+ steamFriends->GetFriendGamePlayed(id, &friend_info);
+
+ if (connect.length() > 0)
+ {
+ sstr << "1: " << friend_info.m_gameID.AppID() << "\t" << name << "\t" << connect << std::endl;
+ }
+ else if (args[1] == name )
+ {
+ connect = "connect " + std::to_string(friend_info.m_steamIDLobby.ConvertToUint64());
+ sstr << "2: " << friend_info.m_gameID.AppID() << "\t" << name << "\t" << connect << std::endl;
+ matchMaking->JoinLobby(friend_info.m_steamIDLobby);
+ }
+ ovlay.write(sstr.str());
+ sstr.str("");
+ }
+ }
+ break;
+ }
+ }
+ }
+ */
diff --git a/overlay_experimental/steam_overlay.h b/overlay_experimental/steam_overlay.h
index 2edd2191..2c61dd4d 100644
--- a/overlay_experimental/steam_overlay.h
+++ b/overlay_experimental/steam_overlay.h
@@ -1,17 +1,16 @@
-#pragma once
+#ifndef __INCLUDED_STEAM_OVERLAY_H__
+#define __INCLUDED_STEAM_OVERLAY_H__
-#include
-#include
-#include
-#include
-#include
-extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
-
-#include "base.h"
+#include "../dll/base.h"
#include "Hook_Manager.h"
+#include
-static decltype(DispatchMessageA)* _DispatchMessageA = DispatchMessageA;
-static decltype(DispatchMessageW)* _DispatchMessageW = DispatchMessageW;
+enum friend_action
+{
+ friend_action_none = 0,
+ friend_action_invite = 1<<0,
+ friend_action_join = 1<<1
+};
class Steam_Overlay
{
@@ -19,6 +18,9 @@ class Steam_Overlay
SteamCallResults* callback_results;
SteamCallBacks* callbacks;
RunEveryRunCB* run_every_runcb;
+ Networking* network;
+
+ const std::vector* friends;
HWND game_hwnd;
WNDPROC game_hwnd_proc;
@@ -28,401 +30,52 @@ class Steam_Overlay
ENotificationPosition notif_position;
int h_inset, v_inset;
+ // Callback infos
+ uint64 friend_to_action;
+ int friend_action;
+ bool overlay_state_changed;
+
Steam_Overlay(Steam_Overlay const&) = delete;
Steam_Overlay(Steam_Overlay&&) = delete;
Steam_Overlay& operator=(Steam_Overlay const&) = delete;
Steam_Overlay& operator=(Steam_Overlay&&) = delete;
- static LRESULT CALLBACK sHookWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { Hook_Manager::Inst().GetOverlay()->HookWndProc(hWnd, uMsg, wParam, lParam); }
+ bool IgnoreMsg(const MSG* lpMsg);
+ LRESULT HookWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- LRESULT HookWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- // Is the event is a key press
- if (uMsg == WM_KEYDOWN)
- {
- // Tab is pressed and was not pressed before
- if (wParam == VK_TAB && !(lParam & (1 << 30)))
- {
- static RECT old_clip;
- // If Left Shift is pressed
- if (GetAsyncKeyState(VK_LSHIFT) & (1 << (sizeof(SHORT) * 8 - 1)))
- {
- show_overlay = !show_overlay;
- }
+ static LRESULT CALLBACK sHookWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+ static LRESULT WINAPI MyDispatchMessageA(const MSG* lpMsg);
+ static LRESULT WINAPI MyDispatchMessageW(const MSG* lpMsg);
- if (show_overlay)
- {
- RECT cliRect, wndRect, clipRect;
-
- GetClipCursor(&old_clip);
- // The window rectangle has borders and menus counted in the size
- GetWindowRect(hWnd, &wndRect);
- // The client rectangle is the window without borders
- GetClientRect(hWnd, &cliRect);
-
- clipRect = wndRect; // Init clip rectangle
-
- // Get Window width with borders
- wndRect.right -= wndRect.left;
- // Get Window height with borders & menus
- wndRect.bottom -= wndRect.top;
- // Compute the border width
- int borderWidth = (wndRect.right - cliRect.right) / 2;
- // Client top clip is the menu bar width minus bottom border
- clipRect.top += wndRect.bottom - cliRect.bottom - borderWidth;
- // Client left clip is the left border minus border width
- clipRect.left += borderWidth;
- // Here goes the same for right and bottom
- clipRect.right -= borderWidth;
- clipRect.bottom -= borderWidth;
-
- ClipCursor(&clipRect);
-
- ImGui::GetIO().MouseDrawCursor = true;
-
- {
- GameOverlayActivated_t data = { 0 };
- data.m_bActive = true;
- callbacks->addCBResult(data.k_iCallback, &data, sizeof(data));
- }
- }
- else
- {
- ClipCursor(&old_clip);
- ImGui::GetIO().MouseDrawCursor = false;
-
- {
- GameOverlayActivated_t data = { 0 };
- data.m_bActive = false;
- callbacks->addCBResult(data.k_iCallback, &data, sizeof(data));
- }
- }
- }
-
- }
- // If we should show the overlay
- if (show_overlay)
- {
- // Call the overlay window procedure
- ImGui_ImplWin32_WndProcHandler(hWnd, uMsg, wParam, lParam);
- return true;
- }
- // Else call the game window procedure
- return CallWindowProc(game_hwnd_proc, hWnd, uMsg, wParam, lParam);
- }
-
- bool IgnoreMsg(const MSG* lpMsg)
- {
- if (lpMsg->hwnd == game_hwnd && show_overlay)
- {
- switch (lpMsg->message)
- {
- case WM_MOUSEMOVE:
- case WM_MOUSEWHEEL: case WM_MOUSEHWHEEL:
- case WM_LBUTTONUP: case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK:
- case WM_RBUTTONUP: case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK:
- case WM_MBUTTONUP: case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK:
- case WM_XBUTTONUP: case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK:
- case WM_KEYDOWN: case WM_KEYUP:
- case WM_SYSKEYDOWN: case WM_SYSKEYUP:
- case WM_CHAR:
- // We ignore theses message in the game windows, but our overlay needs them.
- HookWndProc(lpMsg->hwnd, lpMsg->message, lpMsg->wParam, lpMsg->lParam);
- return true;
- }
- }
- return false;
- }
-
- static LRESULT WINAPI MyDispatchMessageA(const MSG* lpMsg)
- {
- Steam_Overlay* _this = Hook_Manager::Inst().GetOverlay();
- if (_this->IgnoreMsg(lpMsg))
- return 0;
- return _DispatchMessageA(lpMsg);
- }
-
- static LRESULT WINAPI MyDispatchMessageW(const MSG* lpMsg)
- {
- Steam_Overlay* _this = Hook_Manager::Inst().GetOverlay();
- if (_this->IgnoreMsg(lpMsg))
- return 0;
- return _DispatchMessageW(lpMsg);
- }
+ static void steam_overlay_run_every_runcb(void* object);
+ void RunCallbacks();
public:
- Steam_Overlay(Settings* settings, SteamCallResults* callback_results, SteamCallBacks* callbacks, RunEveryRunCB* run_every_runcb) :
- settings(settings),
- callback_results(callback_results),
- callbacks(callbacks),
- run_every_runcb(run_every_runcb),
- game_hwnd(NULL),
- game_hwnd_proc(nullptr),
- show_overlay(false),
- is_ready(false)
- {}
+ Steam_Overlay(Settings* settings, SteamCallResults* callback_results, SteamCallBacks* callbacks, RunEveryRunCB* run_every_runcb, Networking *network);
- ~Steam_Overlay()
- {}
+ ~Steam_Overlay();
- bool Ready() const { return is_ready; }
- bool NeedPresent() const { return true; }
- void SetNotificationPosition(ENotificationPosition eNotificationPosition) { notif_position = eNotificationPosition; }
- void SetNotificationInset(int nHorizontalInset, int nVerticalInset) { h_inset = nHorizontalInset, v_inset = nVerticalInset; }
- void SetupOverlay() { Hook_Manager::Inst().HookRenderer(this); }
+ HWND GetGameHwnd() const;
- void HookReady(void* hWnd)
- {
- if (game_hwnd != hWnd)
- {
- if (!is_ready) // If this is the first time we are ready, hook the window dispatch message, so we can intercept em and disable mouse.
- {
- window_hooks.BeginHook();
-
- window_hooks.HookFuncs(std::make_pair(&(PVOID&)_DispatchMessageA, &Steam_Overlay::MyDispatchMessageA),
- std::make_pair(&(PVOID&)_DispatchMessageW, &Steam_Overlay::MyDispatchMessageW));
+ bool Ready() const;
- window_hooks.EndHook();
- }
+ bool NeedPresent() const;
- is_ready = true;
- if (game_hwnd)
- SetWindowLongPtr(game_hwnd, GWLP_WNDPROC, (LONG_PTR)game_hwnd_proc);
+ void SetNotificationPosition(ENotificationPosition eNotificationPosition);
- game_hwnd = (HWND)hWnd;
- game_hwnd_proc = (WNDPROC)SetWindowLongPtr(game_hwnd, GWLP_WNDPROC, (LONG_PTR)&Steam_Overlay::sHookWndProc);
- }
- }
+ void SetNotificationInset(int nHorizontalInset, int nVerticalInset);
+ void SetupOverlay();
- // https://niemand.com.ar/2019/01/01/how-to-hook-directx-11-imgui/
- // https://github.com/spazzarama/Direct3DHook/blob/master/Capture/Hook
+ void HookReady(void* hWnd);
- void OverlayProc( int width, int height )
- {
- static int item = -1;
- static const char* strs[] = {
- "test1",
- "test2",
- "test3",
- };
+ void OverlayProc(int width, int height);
- if (!show_overlay)
- return;
+ void SetupFriends(const std::vector* friends);
- // Set the overlay windows to the size of the game window
- ImGui::SetNextWindowPos({ 0,0 });
- ImGui::SetNextWindowSize({ static_cast(width),
- static_cast(height) });
+ void OpenOverlayInvite(CSteamID lobbyId);
+ void OpenOverlay(const char* pchDialog);
- ImGui::Begin("SteamOverlay", NULL, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse);
+ void ShowOverlay(bool state);
+};
- ImGui::LabelText("", "Username: %s(%llu) playing %u",
- settings->get_local_name(),
- settings->get_local_steam_id().ConvertToUint64(),
- settings->get_local_game_id().AppID());
-
- ImGui::Spacing();
-
- //ImGui::ListBoxHeader("");
- ImGui::ListBox("Friends", &item, strs, (sizeof(strs) / sizeof(*strs)));
- //ImGui::ListBoxFooter();
-
- ImGui::Spacing();
-
- RECT rect;
-
- GetWindowRect(game_hwnd, &rect);
-
- auto pos = ImGui::GetMousePos();
-
-
- ImGui::LabelText("", "Window pos: %dx%d %dx%d", rect.left, rect.top, rect.right, rect.bottom);
- ImGui::LabelText("", "Mouse pos: %dx%d", (int)pos.x, (int)pos.y);
-
- ImGui::End();
-
- }
-
- /*
- switchstr(args[0])
- {
- casestr("get"):
- sstr << "Steam ID: " << _this->_client->settings_client->get_local_steam_id().ConvertToUint64() << std::endl;
- sstr << "Steam Server ID: " << _this->_client->settings_server->get_local_steam_id().ConvertToUint64() << std::endl;
- sstr << "Your lobby: " << _this->_client->settings_client->get_lobby().ConvertToUint64() << std::endl;
- ovlay.write(sstr.str());
- sstr.str("");
- break;
-
- casestr("get_id") :
- sstr << _this->_client->settings_client->get_local_steam_id().ConvertToUint64() << std::endl;
- ovlay.write(sstr.str());
- sstr.str("");
- break;
-
- casestr("get_server_id") :
- sstr << _this->_client->settings_server->get_local_steam_id().ConvertToUint64() << std::endl;
- ovlay.write(sstr.str());
- sstr.str("");
- break;
-
- casestr("get_lobby") :
- sstr << "Your lobby: " << _this->_client->settings_client->get_lobby().ConvertToUint64() << std::endl;
- ovlay.write(sstr.str());
- sstr.str("");
- break;
-
- casestr("list_friends") :
- {
- ovlay.write(str + "\n");
-
- int cnt = steamFriends->GetFriendCount(0);
- for (int i = 0; i < cnt; ++i)
- {
- CSteamID id = steamFriends->GetFriendByIndex(i, 0);
- const char* name = steamFriends->GetFriendPersonaName(id);
-
- FriendGameInfo_t friend_info = {};
- steamFriends->GetFriendGamePlayed(id, &friend_info);
- sstr << id.ConvertToUint64() << '(' << name << ") is playing: " << friend_info.m_gameID.AppID() << std::endl;
- ovlay.write(sstr.str());
- }
- }
- break;
- casestr("list_games") :
- {
- ovlay.write(str + "\n");
-
- int cnt = steamFriends->GetFriendCount(0);
- for (int i = 0; i < cnt; ++i)
- {
- CSteamID id = steamFriends->GetFriendByIndex(i, 0);
- const char* name = steamFriends->GetFriendPersonaName(id);
-
- std::string connect = steamFriends->GetFriendRichPresence(id, "connect");
- FriendGameInfo_t friend_info = {};
- steamFriends->GetFriendGamePlayed(id, &friend_info);
-
- if (connect.length() > 0)
- {
- sstr << friend_info.m_gameID.AppID() << "\t" << name << "\t" << connect << std::endl;
- }
- else if (friend_info.m_steamIDLobby != k_steamIDNil)
- {
- connect = "+connect_lobby " + std::to_string(friend_info.m_steamIDLobby.ConvertToUint64());
- sstr << friend_info.m_gameID.AppID() << "\t" << name << "\t" << connect << std::endl;
- }
- ovlay.write(sstr.str());
- sstr.str("");
- }
- }
- break;
-
- casestr("invite_user") :
- {
- ovlay.write(str + "\n");
-
- if (_this->lobbyID.IsValid())
- {
- if (args.size() == 2)
- {
- std::string& friendName = args[1];
- int cnt = steamFriends->GetFriendCount(0);
- for (int i = 0; i < cnt; ++i)
- {
- CSteamID id = steamFriends->GetFriendByIndex(i, 0);
- const char* name = steamFriends->GetFriendPersonaName(id);
-
- if (friendName == name)
- {
- Common_Message msg;
- Friend_Messages* friend_messages = new Friend_Messages();
- friend_messages->set_type(Friend_Messages::LOBBY_INVITE);
- friend_messages->set_lobby_id(_this->lobbyID.ConvertToUint64());
- msg.set_allocated_friend_messages(friend_messages);
- msg.set_source_id(_this->_client->settings_client->get_local_steam_id().ConvertToUint64());
- msg.set_dest_id(id.ConvertToUint64());
- _this->_client->network->sendTo(&msg, true);
-
- sstr << "Invite sent" << std::endl;
- ovlay.write(sstr.str());
- break;
- }
- }
-
- }
- else
- {
- sstr << "'invite_user' needs only 1 parameter: friendname" << std::endl;
- ovlay.write(sstr.str());
- }
- }
- }
- break;
-
- casestr("join_game") :
- if (args.size() == 2)
- {
- ovlay.write(str + "\n");
- int cnt = steamFriends->GetFriendCount(0);
- for (int i = 0; i < cnt; ++i)
- {
- CSteamID id = steamFriends->GetFriendByIndex(i, 0);
- const char* name = steamFriends->GetFriendPersonaName(id);
-
- std::string connect = steamFriends->GetFriendRichPresence(id, "connect");
- FriendGameInfo_t friend_info = {};
- steamFriends->GetFriendGamePlayed(id, &friend_info);
-
- if (connect.length() > 0)
- {
- sstr << "1: " << friend_info.m_gameID.AppID() << "\t" << name << "\t" << connect << std::endl;
- }
- else if (std::to_string(friend_info.m_steamIDLobby.ConvertToUint64()) == args[1])
- {
- connect = "connect " + std::to_string(friend_info.m_steamIDLobby.ConvertToUint64());
- sstr << "2: " << friend_info.m_gameID.AppID() << "\t" << name << "\t" << connect << std::endl;
- matchMaking->JoinLobby(friend_info.m_steamIDLobby);
- }
- ovlay.write(sstr.str());
- sstr.str("");
- }
- }
- break;
-
- casestr("join_user") :
- if (args.size() == 2)
- {
- ovlay.write(str + "\n");
- int cnt = steamFriends->GetFriendCount(0);
- for (int i = 0; i < cnt; ++i)
- {
- CSteamID id = steamFriends->GetFriendByIndex(i, 0);
- const char* name = steamFriends->GetFriendPersonaName(id);
-
- std::string connect = steamFriends->GetFriendRichPresence(id, "connect");
- FriendGameInfo_t friend_info = {};
- steamFriends->GetFriendGamePlayed(id, &friend_info);
-
- if (connect.length() > 0)
- {
- sstr << "1: " << friend_info.m_gameID.AppID() << "\t" << name << "\t" << connect << std::endl;
- }
- else if (args[1] == name )
- {
- connect = "connect " + std::to_string(friend_info.m_steamIDLobby.ConvertToUint64());
- sstr << "2: " << friend_info.m_gameID.AppID() << "\t" << name << "\t" << connect << std::endl;
- matchMaking->JoinLobby(friend_info.m_steamIDLobby);
- }
- ovlay.write(sstr.str());
- sstr.str("");
- }
- }
- break;
- }
- }
- }
- */
-
-
-};
\ No newline at end of file
+#endif//__INCLUDED_STEAM_OVERLAY_H__