2016-11-18 00:40:14 +00:00
/*
Copyright 2016 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
2016-11-19 05:30:48 +00:00
http : //www.apache.org/licenses/LICENSE-2.0
2016-11-18 00:40:14 +00:00
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 .
*/
2016-11-18 00:22:07 +00:00
# include "SteamTargetRenderer.h"
2017-02-12 21:40:18 +00:00
std : : atomic < bool > SteamTargetRenderer : : overlayOpen = false ;
HHOOK SteamTargetRenderer : : hook = nullptr ;
2017-02-15 19:13:41 +00:00
std : : atomic < bool > SteamTargetRenderer : : bHookSteam = false ;
2016-11-19 01:24:49 +00:00
2017-01-25 16:54:08 +00:00
SteamTargetRenderer : : SteamTargetRenderer ( int & argc , char * * argv ) : QApplication ( argc , argv )
2016-11-18 00:22:07 +00:00
{
getSteamOverlay ( ) ;
2017-01-25 23:01:26 +00:00
loadLogo ( ) ;
2016-11-18 00:22:07 +00:00
2017-02-15 19:13:41 +00:00
SetConsoleCtrlHandler ( reinterpret_cast < PHANDLER_ROUTINE > ( ConsoleCtrlCallback ) , true ) ;
2017-04-19 06:13:38 +00:00
if ( this - > arguments ( ) . size ( ) = = 1 )
{
2017-04-19 13:43:04 +00:00
std : : cerr < < " Target configuration file must be specified! " < < std : : endl ;
MessageBoxW ( NULL , L " Target configuration file must be specified! " , L " GloSC-SteamTarget " , MB_OK ) ;
2017-05-31 13:01:38 +00:00
QTimer : : singleShot ( 0 , this , [ ] ( )
2016-11-18 00:22:07 +00:00
{
2017-05-31 13:01:38 +00:00
QApplication : : exit ( 1 ) ;
} ) ; //call after ctor
} else {
QSettings settings ( this - > arguments ( ) . at ( 1 ) , QSettings : : IniFormat ) ;
settings . beginGroup ( " BaseConf " ) ;
const QStringList childKeys = settings . childKeys ( ) ;
for ( auto & childkey : childKeys )
{
if ( childkey = = " bDrawDebugEdges " )
{
bDrawDebugEdges = settings . value ( childkey ) . toBool ( ) ;
}
else if ( childkey = = " bEnableOverlay " ) {
bDrawOverlay = settings . value ( childkey ) . toBool ( ) ;
}
else if ( childkey = = " bEnableControllers " ) {
bEnableControllers = settings . value ( childkey ) . toBool ( ) ;
}
else if ( childkey = = " bHookSteam " ) {
bHookSteam = settings . value ( childkey ) . toBool ( ) ;
}
else if ( childkey = = " bUseDesktopConfig " ) {
bUseDesktopConfig = settings . value ( childkey ) . toBool ( ) ;
}
2017-02-15 03:04:27 +00:00
}
2017-05-31 13:01:38 +00:00
settings . endGroup ( ) ;
2016-11-18 00:22:07 +00:00
2016-11-19 05:35:52 +00:00
# ifndef NDEBUG
2017-05-31 13:01:38 +00:00
bDrawDebugEdges = true ;
2016-11-19 05:35:52 +00:00
# endif // NDEBUG
2017-05-31 13:01:38 +00:00
sfCshape = sf : : CircleShape ( 100.f ) ;
sfCshape . setFillColor ( sf : : Color ( 128 , 128 , 128 , 128 ) ) ;
sfCshape . setOrigin ( sf : : Vector2f ( 100 , 100 ) ) ;
sf : : VideoMode mode = sf : : VideoMode : : getDesktopMode ( ) ;
sfWindow . create ( sf : : VideoMode ( mode . width - 16 , mode . height - 32 ) , " GloSC_OverlayWindow " ) ; //Window is too large ; always 16 and 32 pixels? - sf::Style::None breaks transparency!
sfWindow . setFramerateLimit ( iRefreshRate ) ;
sfWindow . setPosition ( sf : : Vector2i ( 0 , 0 ) ) ;
makeSfWindowTransparent ( sfWindow ) ;
sfWindow . setActive ( false ) ;
consoleHwnd = GetConsoleWindow ( ) ; //We need a console for a dirty hack to make sure we stay in game bindings
//QT Windows cause trouble with the overlay, so we cannot use them
2017-05-31 13:17:30 +00:00
# ifdef NDEBUG
2017-05-31 13:01:38 +00:00
ShowWindow ( consoleHwnd , SW_HIDE ) ;
2017-05-31 13:17:30 +00:00
# endif // NDEBUG
2016-11-18 00:22:07 +00:00
2017-09-29 19:45:06 +00:00
2017-05-31 13:01:38 +00:00
if ( bEnableControllers )
controllerThread . run ( ) ;
2016-11-18 00:22:07 +00:00
2017-05-31 13:01:38 +00:00
QTimer : : singleShot ( 2000 , this , & SteamTargetRenderer : : launchApp ) ; // lets steam do its thing
2017-02-12 21:40:18 +00:00
2017-05-31 13:01:38 +00:00
if ( hmodGameOverlayRenderer ! = nullptr )
{
//Hook MessageQueue to detect if overlay gets opened / closed
//Steam Posts a Message with 0x14FA / 0x14F7 when the overlay gets opened / closed
hook = SetWindowsHookEx ( WH_GETMESSAGE , HookCallback , nullptr , GetCurrentThreadId ( ) ) ;
}
2017-02-15 03:04:27 +00:00
2017-05-31 13:01:38 +00:00
if ( bUseDesktopConfig )
2017-02-15 03:04:27 +00:00
{
2017-05-31 13:01:38 +00:00
bHookSteam = false ;
QTimer : : singleShot ( 1000 , this , [ ] ( )
{
HWND taskbar = FindWindow ( L " Shell_TrayWnd " , nullptr ) ;
SetFocus ( taskbar ) ;
SetForegroundWindow ( taskbar ) ;
} ) ;
}
2017-02-15 03:04:27 +00:00
}
2016-11-18 00:22:07 +00:00
}
SteamTargetRenderer : : ~ SteamTargetRenderer ( )
{
2017-02-12 21:40:18 +00:00
if ( hmodGameOverlayRenderer ! = nullptr )
{
UnhookWindowsHookEx ( hook ) ;
}
2016-11-18 00:22:07 +00:00
renderThread . join ( ) ;
2016-11-19 01:24:49 +00:00
if ( controllerThread . isRunning ( ) )
controllerThread . stop ( ) ;
2016-11-18 00:22:07 +00:00
}
void SteamTargetRenderer : : run ( )
{
renderThread = std : : thread ( & SteamTargetRenderer : : RunSfWindowLoop , this ) ;
}
2017-01-25 16:54:08 +00:00
void SteamTargetRenderer : : stop ( )
{
bRunLoop = false ;
2017-02-15 20:58:44 +00:00
unhookBindings ( ) ;
2017-01-25 16:54:08 +00:00
QApplication : : exit ( 0 ) ;
}
2017-02-12 21:40:18 +00:00
2016-11-18 00:22:07 +00:00
void SteamTargetRenderer : : RunSfWindowLoop ( )
{
if ( ! bRunLoop )
return ;
sfWindow . setActive ( true ) ;
2017-11-11 16:39:04 +00:00
bool hasJustLaunched = true ;
2016-11-18 00:22:07 +00:00
2016-11-19 03:41:04 +00:00
if ( bDrawOverlay )
SetWindowPos ( sfWindow . getSystemHandle ( ) , HWND_TOPMOST , 0 , 0 , 0 , 0 , SWP_NOMOVE | SWP_NOSIZE | SWP_ASYNCWINDOWPOS ) ;
2017-04-19 06:13:38 +00:00
else
2017-11-12 00:43:36 +00:00
{
2017-11-12 01:08:16 +00:00
ShowWindow ( sfWindow . getSystemHandle ( ) , SW_HIDE ) ;
2017-11-12 00:43:36 +00:00
sfWindow . setFramerateLimit ( 1 ) ; //Window is not shown anyway,
2017-11-15 21:40:49 +00:00
ShowWindow ( consoleHwnd , SW_SHOW ) ; //Show the console window so the user sees SOMETHING
2017-11-12 00:43:36 +00:00
}
2016-11-19 03:41:04 +00:00
2016-11-18 00:22:07 +00:00
while ( sfWindow . isOpen ( ) & & bRunLoop )
{
sf : : Event event ;
while ( sfWindow . pollEvent ( event ) )
{
if ( event . type = = sf : : Event : : Closed )
sfWindow . close ( ) ;
}
sfWindow . clear ( sf : : Color : : Transparent ) ;
if ( bDrawDebugEdges )
drawDebugEdges ( ) ;
2016-11-26 21:57:32 +00:00
//we inject and hook here to spare IPC and let the dll grab the steam appID of the launched process when the config switches (config switches w/ focus)
2017-11-11 16:39:04 +00:00
if ( hasJustLaunched )
2016-11-18 00:22:07 +00:00
{
2016-11-26 21:57:32 +00:00
if ( bHookSteam )
hookBindings ( ) ; //cleanup - unhooking / unloading of dll is managed by the GloSC gamelauncher rather than here
2017-11-11 16:39:04 +00:00
hasJustLaunched = false ;
2016-11-19 01:24:49 +00:00
}
2016-11-18 00:22:07 +00:00
2017-11-11 16:39:04 +00:00
//Window focus trickery
2017-11-18 17:56:53 +00:00
if ( hmodGameOverlayRenderer ! = nullptr )
2016-11-19 01:24:49 +00:00
{
if ( overlayOpen )
2016-11-18 00:22:07 +00:00
{
2016-11-19 01:24:49 +00:00
if ( ! bNeedFocusSwitch )
2016-11-18 00:22:07 +00:00
{
2016-11-19 01:24:49 +00:00
bNeedFocusSwitch = true ;
2016-11-18 00:22:07 +00:00
2016-11-19 01:24:49 +00:00
hwForeGroundWindow = GetForegroundWindow ( ) ;
2016-11-18 00:22:07 +00:00
2016-11-19 03:41:04 +00:00
std : : cout < < " Saving current ForegorundWindow HWND: " < < hwForeGroundWindow < < std : : endl ;
std : : cout < < " Activating OverlayWindow " < < std : : endl ;
2016-11-18 00:22:07 +00:00
2017-01-25 16:13:48 +00:00
SetWindowLong ( sfWindow . getSystemHandle ( ) , GWL_EXSTYLE , WS_EX_LAYERED ) ; //make overlay window clickable
2016-11-18 00:22:07 +00:00
2016-11-19 03:41:04 +00:00
//Actually activate the overlaywindow
2017-11-18 17:56:53 +00:00
stealFocus ( sfWindow . getSystemHandle ( ) ) ;
2016-12-04 21:58:52 +00:00
//Move the mouse cursor inside the overlaywindow
//this is neccessary because steam doesn't want to switch to big picture bindings if mouse isn't inside
2017-11-18 17:56:53 +00:00
moveMouseIntoOverlay ( ) ;
2016-11-18 00:22:07 +00:00
}
2017-01-25 23:01:26 +00:00
sfWindow . draw ( backgroundSprite ) ;
2016-11-19 03:41:04 +00:00
} else {
2016-11-19 01:24:49 +00:00
if ( bNeedFocusSwitch )
2016-11-18 00:22:07 +00:00
{
2016-11-19 03:41:04 +00:00
std : : cout < < " Deactivating OverlayWindow " < < std : : endl ;
2016-11-18 00:22:07 +00:00
2016-11-19 03:41:04 +00:00
//make overlaywindow clickthrough - WS_EX_TRANSPARENT - again
2017-01-25 16:13:48 +00:00
SetWindowLong ( sfWindow . getSystemHandle ( ) , GWL_EXSTYLE , WS_EX_LAYERED | WS_EX_TRANSPARENT ) ;
2016-11-18 00:22:07 +00:00
2016-11-19 03:41:04 +00:00
std : : cout < < " Switching to previously focused window " < < std : : endl ;
2016-11-18 00:22:07 +00:00
2016-11-19 03:41:04 +00:00
//switch back the the previosly focused window
2017-11-18 17:56:53 +00:00
stealFocus ( hwForeGroundWindow ) ;
2016-11-19 01:24:49 +00:00
bNeedFocusSwitch = false ;
2016-11-18 00:22:07 +00:00
}
}
}
2017-01-25 23:01:26 +00:00
sfWindow . display ( ) ;
2016-11-18 00:22:07 +00:00
}
2017-01-25 16:54:08 +00:00
stop ( ) ;
2016-11-18 00:22:07 +00:00
}
void SteamTargetRenderer : : getSteamOverlay ( )
{
2017-02-12 21:40:18 +00:00
hmodGameOverlayRenderer = GetModuleHandle ( overlayModuleName ) ;
2016-11-18 00:22:07 +00:00
2017-01-25 16:13:48 +00:00
if ( hmodGameOverlayRenderer ! = nullptr )
2016-11-18 00:22:07 +00:00
{
2017-02-12 21:40:18 +00:00
std : : cout < < overlayModuleName < < " found; Module at: 0x " < < hmodGameOverlayRenderer < < std : : endl ;
2016-11-18 00:22:07 +00:00
}
}
void SteamTargetRenderer : : makeSfWindowTransparent ( sf : : RenderWindow & window )
{
HWND hwnd = window . getSystemHandle ( ) ;
SetWindowLong ( hwnd , GWL_STYLE , WS_VISIBLE | WS_POPUP & ~ WS_CAPTION ) ;
2017-01-25 16:13:48 +00:00
SetWindowLong ( hwnd , GWL_EXSTYLE , WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_TOPMOST ) ;
2016-11-18 00:22:07 +00:00
MARGINS margins ;
margins . cxLeftWidth = - 1 ;
DwmExtendFrameIntoClientArea ( hwnd , & margins ) ;
2016-11-19 03:41:04 +00:00
SetWindowPos ( hwnd , HWND_TOPMOST , 0 , 0 , 0 , 0 , SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE ) ;
2016-11-18 00:22:07 +00:00
2017-01-25 16:13:48 +00:00
2016-11-18 00:22:07 +00:00
window . clear ( sf : : Color : : Transparent ) ;
window . display ( ) ;
}
void SteamTargetRenderer : : drawDebugEdges ( )
{
sfCshape . setPosition ( sf : : Vector2f ( - 25 , - 25 ) ) ;
sfWindow . draw ( sfCshape ) ;
sfCshape . setPosition ( sf : : Vector2f ( sfWindow . getSize ( ) . x + 25 , - 25 ) ) ;
sfWindow . draw ( sfCshape ) ;
sfCshape . setPosition ( sf : : Vector2f ( - 25 , sfWindow . getSize ( ) . y ) ) ;
sfWindow . draw ( sfCshape ) ;
sfCshape . setPosition ( sf : : Vector2f ( sfWindow . getSize ( ) . x , sfWindow . getSize ( ) . y ) ) ;
sfWindow . draw ( sfCshape ) ;
}
2017-04-19 13:38:30 +00:00
void SteamTargetRenderer : : hookBindings ( ) const
2016-11-18 00:22:07 +00:00
{
2016-11-26 21:57:32 +00:00
std : : cout < < " Hooking Steam... " < < std : : endl ;
QString dir = QDir : : toNativeSeparators ( QCoreApplication : : applicationDirPath ( ) ) ;
dir = dir . mid ( 0 , dir . lastIndexOf ( " \\ " ) ) ;
2016-11-18 00:22:07 +00:00
2016-11-26 21:57:32 +00:00
QProcess proc ;
2016-11-29 17:30:56 +00:00
proc . setNativeArguments ( " --inject " ) ;
2016-12-04 20:43:31 +00:00
proc . setWorkingDirectory ( dir ) ;
2017-04-19 06:13:38 +00:00
proc . start ( " ./Injector.exe " , QIODevice : : ReadOnly ) ;
2016-12-04 20:43:31 +00:00
proc . waitForStarted ( ) ;
2016-11-26 21:57:32 +00:00
proc . waitForFinished ( ) ;
2016-12-04 20:43:31 +00:00
2016-11-29 17:30:56 +00:00
if ( QString : : fromStdString ( proc . readAll ( ) . toStdString ( ) ) . contains ( " Inject success! " ) ) //if we have injected (and patched the function)
2016-11-26 21:57:32 +00:00
{
std : : cout < < " Successfully hooked Steam! " < < std : : endl ;
//tell the GloSC_GameLauncher that we have hooked steam
//it will deal with checking if the target is still alive and unload the dll / unhook then
// - ensures unloading / unhooking even if this process crashes or gets unexpectedly killed
QSharedMemory sharedMemInstance ( " GloSC_GameLauncher " ) ;
if ( ! sharedMemInstance . create ( 1024 ) & & sharedMemInstance . error ( ) = = QSharedMemory : : AlreadyExists )
{
QBuffer buffer ;
QDataStream dataStream ( & buffer ) ;
QStringList stringList ;
sharedMemInstance . attach ( ) ;
sharedMemInstance . lock ( ) ;
2017-01-25 16:13:48 +00:00
buffer . setData ( static_cast < const char * > ( sharedMemInstance . constData ( ) ) , sharedMemInstance . size ( ) ) ;
2016-11-26 21:57:32 +00:00
buffer . open ( QBuffer : : ReadOnly ) ;
dataStream > > stringList ;
buffer . close ( ) ;
int i = stringList . indexOf ( IsSteamHooked ) + 1 ;
stringList . replace ( i , " 1 " ) ;
buffer . open ( QBuffer : : ReadWrite ) ;
QDataStream out ( & buffer ) ;
out < < stringList ;
int size = buffer . size ( ) ;
2017-01-25 16:13:48 +00:00
char * to = static_cast < char * > ( sharedMemInstance . data ( ) ) ;
2016-11-26 21:57:32 +00:00
const char * from = buffer . data ( ) . data ( ) ;
memcpy ( to , from , qMin ( sharedMemInstance . size ( ) , size ) ) ;
buffer . close ( ) ;
sharedMemInstance . unlock ( ) ;
sharedMemInstance . detach ( ) ;
}
} else {
std : : cout < < " Hooking Steam failed! " < < std : : endl ;
2017-01-25 16:13:48 +00:00
MessageBoxW ( NULL , L " Hooking Steam failed! " , L " GloSC-SteamTarget " , MB_OK ) ;
2016-11-26 21:57:32 +00:00
}
}
2017-01-25 23:01:26 +00:00
void SteamTargetRenderer : : loadLogo ( )
{
HRSRC rsrcData = FindResource ( NULL , L " ICOPNG " , RT_RCDATA ) ;
DWORD rsrcDataSize = SizeofResource ( NULL , rsrcData ) ;
HGLOBAL grsrcData = LoadResource ( NULL , rsrcData ) ;
LPVOID firstByte = LockResource ( grsrcData ) ;
spriteTexture = std : : make_unique < sf : : Texture > ( ) ;
spriteTexture - > loadFromMemory ( firstByte , rsrcDataSize ) ;
backgroundSprite . setTexture ( * spriteTexture ) ;
backgroundSprite . setOrigin ( sf : : Vector2f ( spriteTexture - > getSize ( ) . x / 2.f , spriteTexture - > getSize ( ) . y / 2 ) ) ;
sf : : VideoMode winSize = sf : : VideoMode : : getDesktopMode ( ) ;
backgroundSprite . setPosition ( sf : : Vector2f ( winSize . width / 2.f , winSize . height / 2.f ) ) ;
}
2017-11-18 17:56:53 +00:00
void SteamTargetRenderer : : moveMouseIntoOverlay ( )
{
RECT rect = { 0 } ;
if ( GetWindowRect ( sfWindow . getSystemHandle ( ) , & rect ) )
{
POINT cursorPos = { 0 } ;
GetCursorPos ( & cursorPos ) ;
if ( PtInRect ( & rect , cursorPos ) )
{
SetCursorPos ( cursorPos . x + 1 , cursorPos . y ) ;
}
else
{
SetCursorPos ( rect . left + 16 , rect . top + 16 ) ;
}
}
}
2017-11-11 16:39:04 +00:00
//WinHook Callback to check if the overlay is opened/closed
2017-02-12 21:40:18 +00:00
LRESULT WINAPI SteamTargetRenderer : : HookCallback ( int nCode , WPARAM wParam , LPARAM lParam )
{
if ( nCode > = 0 )
{
PMSG msg = reinterpret_cast < PMSG > ( lParam ) ;
2017-12-28 21:20:17 +00:00
std : : cout < < " DEBUG: " < < " message: " < < msg - > message < < std : : endl ;
2017-02-12 21:40:18 +00:00
if ( msg - > message = = 0x14FA ) //Posted when the overlay gets opened
{
overlayOpen = true ;
std : : cout < < " Overlay Opened! \n " ;
}
2017-12-28 21:20:17 +00:00
else if ( msg - > message = = 0x14F7 | | msg - > message = = 0x14FD | | msg - > message = = 512 | | msg - > message = = 0x2a3 )
2017-02-12 21:40:18 +00:00
{
overlayOpen = false ;
std : : cout < < " Overlay closed! \n " ;
}
}
return CallNextHookEx ( hook , nCode , wParam , lParam ) ;
}
2017-02-15 20:58:44 +00:00
void SteamTargetRenderer : : unhookBindings ( )
{
if ( bHookSteam )
{
QString dir = QDir : : toNativeSeparators ( QCoreApplication : : applicationDirPath ( ) ) ;
dir = dir . mid ( 0 , dir . lastIndexOf ( " \\ " ) ) ;
QProcess proc ;
proc . setNativeArguments ( " --eject " ) ;
proc . setWorkingDirectory ( dir ) ;
2017-04-19 19:05:05 +00:00
proc . start ( " ./Injector.exe " , QIODevice : : ReadOnly ) ;
2017-02-15 20:58:44 +00:00
proc . waitForStarted ( ) ;
proc . waitForFinished ( ) ;
}
}
2017-02-15 19:13:41 +00:00
BOOL SteamTargetRenderer : : ConsoleCtrlCallback ( DWORD dwCtrlType )
{
if ( dwCtrlType = = CTRL_CLOSE_EVENT | | dwCtrlType = = CTRL_BREAK_EVENT | | dwCtrlType = = CTRL_C_EVENT )
{
2017-02-15 20:58:44 +00:00
unhookBindings ( ) ;
2017-02-15 19:13:41 +00:00
return true ;
}
return false ;
}
2017-11-18 17:56:53 +00:00
void SteamTargetRenderer : : stealFocus ( HWND hwnd )
{
DWORD dwCurrentThread = GetCurrentThreadId ( ) ;
DWORD dwFGThread = GetWindowThreadProcessId ( GetForegroundWindow ( ) , nullptr ) ;
AttachThreadInput ( dwCurrentThread , dwFGThread , TRUE ) ;
// Possible actions you may wan to bring the window into focus.
SetForegroundWindow ( hwnd ) ;
SetCapture ( hwnd ) ;
SetFocus ( hwnd ) ;
SetActiveWindow ( hwnd ) ;
EnableWindow ( hwnd , TRUE ) ;
AttachThreadInput ( dwCurrentThread , dwFGThread , FALSE ) ;
}
2016-11-26 21:57:32 +00:00
void SteamTargetRenderer : : launchApp ( )
{
2017-04-19 14:07:57 +00:00
SetPriorityClass ( GetCurrentProcess ( ) , HIGH_PRIORITY_CLASS ) ;
2016-11-18 00:22:07 +00:00
bool launchGame = false ;
2016-11-19 05:30:48 +00:00
bool closeWhenDone = false ;
2016-11-18 00:22:07 +00:00
QString type = " Win32 " ;
QString path = " " ;
2017-04-19 06:13:38 +00:00
QString args ;
QSettings settings ( this - > arguments ( ) . at ( 1 ) , QSettings : : IniFormat ) ;
2016-11-18 00:22:07 +00:00
settings . beginGroup ( " LaunchGame " ) ;
const QStringList childKeys = settings . childKeys ( ) ;
for ( auto & childkey : childKeys )
{
if ( childkey = = " bLaunchGame " )
launchGame = settings . value ( childkey ) . toBool ( ) ;
2017-04-19 06:13:38 +00:00
else if ( childkey = = " Type " )
2016-11-18 00:22:07 +00:00
type = settings . value ( childkey ) . toString ( ) ;
2017-04-19 06:13:38 +00:00
else if ( childkey = = " Path " )
2016-11-18 00:22:07 +00:00
path = settings . value ( childkey ) . toString ( ) ;
2017-04-19 06:13:38 +00:00
else if ( childkey = = " Args " )
args = settings . value ( childkey ) . toString ( ) ;
else if ( childkey = = " bCloseWhenDone " )
2016-11-19 05:30:48 +00:00
closeWhenDone = settings . value ( " bCloseWhenDone " ) . toBool ( ) ;
2016-11-18 00:22:07 +00:00
}
settings . endGroup ( ) ;
if ( launchGame )
{
QSharedMemory sharedMemInstance ( " GloSC_GameLauncher " ) ;
if ( ! sharedMemInstance . create ( 1024 ) & & sharedMemInstance . error ( ) = = QSharedMemory : : AlreadyExists )
{
2017-11-18 18:04:33 +00:00
if ( type = = " UWP " )
{
HWND hwnd = sfWindow . getSystemHandle ( ) ;
SetWindowPos ( hwnd , HWND_BOTTOM , 0 , 0 , 0 , 0 , SWP_NOMOVE | SWP_NOSIZE | SWP_ASYNCWINDOWPOS ) ;
QTimer : : singleShot ( 5000 , [ hwnd ] ( )
{
SetWindowPos ( hwnd , HWND_TOPMOST , 0 , 0 , 0 , 0 , SWP_NOMOVE | SWP_NOSIZE | SWP_ASYNCWINDOWPOS ) ;
} ) ;
}
2016-11-26 21:57:32 +00:00
QBuffer buffer ;
QDataStream dataStream ( & buffer ) ;
2016-11-18 00:22:07 +00:00
QStringList stringList ;
2016-11-26 21:57:32 +00:00
sharedMemInstance . attach ( ) ;
sharedMemInstance . lock ( ) ;
2017-01-25 16:13:48 +00:00
buffer . setData ( static_cast < const char * > ( sharedMemInstance . constData ( ) ) , sharedMemInstance . size ( ) ) ;
2016-11-26 21:57:32 +00:00
buffer . open ( QBuffer : : ReadOnly ) ;
dataStream > > stringList ;
buffer . close ( ) ;
int lgt_index = stringList . indexOf ( LaunchGame ) ;
stringList . replace ( lgt_index + 1 , type ) ;
stringList . replace ( lgt_index + 2 , path ) ;
2017-05-31 13:07:20 +00:00
stringList . replace ( lgt_index + 3 , args ) ;
2016-11-26 21:57:32 +00:00
2016-11-18 00:22:07 +00:00
buffer . open ( QBuffer : : ReadWrite ) ;
QDataStream out ( & buffer ) ;
out < < stringList ;
int size = buffer . size ( ) ;
2017-01-25 16:13:48 +00:00
char * to = static_cast < char * > ( sharedMemInstance . data ( ) ) ;
2016-11-18 00:22:07 +00:00
const char * from = buffer . data ( ) . data ( ) ;
memcpy ( to , from , qMin ( sharedMemInstance . size ( ) , size ) ) ;
2016-11-26 21:57:32 +00:00
buffer . close ( ) ;
2016-11-18 00:22:07 +00:00
sharedMemInstance . unlock ( ) ;
sharedMemInstance . detach ( ) ;
2016-11-19 05:30:48 +00:00
if ( closeWhenDone )
{
updateTimer . setInterval ( 1111 ) ;
connect ( & updateTimer , SIGNAL ( timeout ( ) ) , this , SLOT ( checkSharedMem ( ) ) ) ;
updateTimer . start ( ) ;
}
}
}
}
void SteamTargetRenderer : : checkSharedMem ( )
{
QSharedMemory sharedMemInstance ( " GloSC_GameLauncher " ) ;
if ( ! sharedMemInstance . create ( 1024 ) & & sharedMemInstance . error ( ) = = QSharedMemory : : AlreadyExists )
{
QBuffer buffer ;
QDataStream in ( & buffer ) ;
QStringList stringList ;
sharedMemInstance . attach ( ) ;
sharedMemInstance . lock ( ) ;
2017-01-25 16:13:48 +00:00
buffer . setData ( static_cast < const char * > ( sharedMemInstance . constData ( ) ) , sharedMemInstance . size ( ) ) ;
2016-11-19 05:30:48 +00:00
buffer . open ( QBuffer : : ReadOnly ) ;
in > > stringList ;
2016-11-26 21:57:32 +00:00
buffer . close ( ) ;
2016-11-19 05:30:48 +00:00
sharedMemInstance . unlock ( ) ;
sharedMemInstance . detach ( ) ;
2017-04-19 06:06:04 +00:00
int close_index = stringList . indexOf ( LaunchedProcessFinished ) + 1 ;
2016-11-26 21:57:32 +00:00
if ( close_index > 0 & & stringList . at ( close_index ) . toInt ( ) = = 1 )
2016-11-19 05:30:48 +00:00
bRunLoop = false ;
2016-11-18 00:22:07 +00:00
}
2017-02-12 21:40:18 +00:00
2016-11-18 00:22:07 +00:00
}