Browse Source

Rewrite SelfPatcher to include the ability to install updates.

To register an update for install, there are three options:
- List any executable or msi file in the [External|Internal]Patcher manifest.
- As above, but in the *optional* DependencyPatcher manifest.
- Flag a file with the bit flag 0x10 in either of the above manifests.

This also fixes a bug that caused the status thread to deadlock in certain situations, causing the launcher to get stuck open.

(cherry picked from commit e0e918084395f93170abcea2853ad25ae3012385)
hoikas/newpatcher-1
Adam Johnson 5 years ago committed by rarified
parent
commit
60b108a6b7
  1. 80
      MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/Apps/plUruLauncher/Main.cpp
  2. 1
      MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/Apps/plUruLauncher/Pch.h
  3. 905
      MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/Apps/plUruLauncher/SelfPatcher.cpp
  4. 1
      MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/Apps/plUruLauncher/plLauncherInfo.h

80
MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/Apps/plUruLauncher/Main.cpp

@ -157,13 +157,12 @@ static long s_terminationIssued;
static bool s_terminated; static bool s_terminated;
static plLauncherInfo s_launcherInfo; static plLauncherInfo s_launcherInfo;
static HANDLE s_thread; static HANDLE s_thread;
static HANDLE s_event; static CEvent s_shutdownDesiredEvent(kEventManualReset);
static HINSTANCE s_hInstance; static HINSTANCE s_hInstance;
static HWND s_dialog;
static CEvent s_dialogCreateEvent(kEventManualReset); static CEvent s_dialogCreateEvent(kEventManualReset);
static CCritSect s_critsect; static CCritSect s_critsect;
static LISTDECL(WndEvent, link) s_eventQ; static LISTDECL(WndEvent, link) s_eventQ;
static CEvent s_shutdownEvent(kEventManualReset); static CEvent s_shutdownDialogEvent(kEventManualReset);
static wchar s_workingDir[MAX_PATH]; static wchar s_workingDir[MAX_PATH];
static CEvent s_statusEvent(kEventManualReset); static CEvent s_statusEvent(kEventManualReset);
@ -311,7 +310,7 @@ static void TerminateGame () {
//============================================================================ //============================================================================
static void Recv_SetProgress (HWND hwnd, const SetProgressEvent &event) { static void Recv_SetProgress (HWND hwnd, const SetProgressEvent &event) {
SendMessage(GetDlgItem(s_dialog, IDC_PROGRESS), PBM_SETPOS, event.progress, NULL); SendMessage(GetDlgItem(s_launcherInfo.dialog, IDC_PROGRESS), PBM_SETPOS, event.progress, NULL);
if (pTGApp) if (pTGApp)
{ {
@ -329,7 +328,7 @@ static void Recv_SetProgress (HWND hwnd, const SetProgressEvent &event) {
//============================================================================ //============================================================================
static void Recv_SetText (HWND hwnd, const SetTextEvent &event) { static void Recv_SetText (HWND hwnd, const SetTextEvent &event) {
bool b = SendMessage(GetDlgItem(s_dialog, IDC_TEXT), WM_SETTEXT, 0, (LPARAM) event.text); bool b = SendMessage(GetDlgItem(s_launcherInfo.dialog, IDC_TEXT), WM_SETTEXT, 0, (LPARAM) event.text);
if (pTGApp) if (pTGApp)
{ {
@ -347,7 +346,7 @@ static void Recv_SetText (HWND hwnd, const SetTextEvent &event) {
//============================================================================ //============================================================================
static void Recv_SetStatusText (HWND hwnd, const SetStatusTextEvent &event) { static void Recv_SetStatusText (HWND hwnd, const SetStatusTextEvent &event) {
bool b = SendMessage(GetDlgItem(s_dialog, IDC_STATUS_TEXT), WM_SETTEXT, 0, (LPARAM) event.text); bool b = SendMessage(GetDlgItem(s_launcherInfo.dialog, IDC_STATUS_TEXT), WM_SETTEXT, 0, (LPARAM) event.text);
} }
//============================================================================ //============================================================================
@ -359,7 +358,7 @@ static void Recv_SetTimeRemaining (HWND hwnd, const SetTimeRemainingEvent &event
if(event.seconds == 0xffffffff) if(event.seconds == 0xffffffff)
{ {
SendMessage(GetDlgItem(s_dialog, IDC_TIMEREMAINING), WM_SETTEXT, 0, (LPARAM) "estimating..."); SendMessage(GetDlgItem(s_launcherInfo.dialog, IDC_TIMEREMAINING), WM_SETTEXT, 0, (LPARAM) "...");
return; return;
} }
@ -392,7 +391,7 @@ static void Recv_SetTimeRemaining (HWND hwnd, const SetTimeRemainingEvent &event
StrPrintf(text, arrsize(text), "%s%d min ", text, minutes); StrPrintf(text, arrsize(text), "%s%d min ", text, minutes);
if( seconds || !text[0]) if( seconds || !text[0])
StrPrintf(text, arrsize(text), "%s%d sec", text, seconds); StrPrintf(text, arrsize(text), "%s%d sec", text, seconds);
bool b = SendMessage(GetDlgItem(s_dialog, IDC_TIMEREMAINING), WM_SETTEXT, 0, (LPARAM) text); bool b = SendMessage(GetDlgItem(s_launcherInfo.dialog, IDC_TIMEREMAINING), WM_SETTEXT, 0, (LPARAM) text);
} }
//============================================================================ //============================================================================
@ -402,6 +401,11 @@ static void Recv_SetBytesRemaining (HWND hwnd, const SetBytesRemainingEvent &eve
unsigned decimal; unsigned decimal;
unsigned bytes = event.bytes; unsigned bytes = event.bytes;
if (bytes == 0xffffffff) {
SendMessage(GetDlgItem(s_launcherInfo.dialog, IDC_BYTESREMAINING), WM_SETTEXT, 0, (LPARAM) "...");
return;
}
unsigned GB = bytes / 1000000000; unsigned GB = bytes / 1000000000;
if(GB) if(GB)
{ {
@ -416,7 +420,7 @@ static void Recv_SetBytesRemaining (HWND hwnd, const SetBytesRemainingEvent &eve
decimal = bytes / 100000; // to one decimal place decimal = bytes / 100000; // to one decimal place
StrPrintf(text, arrsize(text), "%d.%d MB", MB, decimal); StrPrintf(text, arrsize(text), "%d.%d MB", MB, decimal);
} }
bool b = SendMessage(GetDlgItem(s_dialog, IDC_BYTESREMAINING), WM_SETTEXT, 0, (LPARAM) text); bool b = SendMessage(GetDlgItem(s_launcherInfo.dialog, IDC_BYTESREMAINING), WM_SETTEXT, 0, (LPARAM) text);
} }
//============================================================================ //============================================================================
@ -462,19 +466,19 @@ static void MessagePump (HWND hwnd) {
// wait for a message or the shutdown event // wait for a message or the shutdown event
const DWORD result = MsgWaitForMultipleObjects( const DWORD result = MsgWaitForMultipleObjects(
1, 1,
&s_event, &s_shutdownDesiredEvent.Handle(),
false, false,
INFINITE, INFINITE,
QS_ALLEVENTS QS_ALLEVENTS
); );
if (result == WAIT_OBJECT_0) if (result == WAIT_OBJECT_0)
return; PostQuitMessage(0);
// process windows messages // process windows messages
MSG msg; MSG msg;
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) { while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
if (!IsDialogMessage(s_dialog, &msg)) { if (!IsDialogMessage(s_launcherInfo.dialog, &msg)) {
TranslateMessage(&msg); TranslateMessage(&msg);
DispatchMessage(&msg); DispatchMessage(&msg);
} }
@ -503,8 +507,8 @@ BOOL CALLBACK SplashDialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM l
if(!s_shutdown) if(!s_shutdown)
{ {
s_shutdown = true; s_shutdown = true;
SendMessage(GetDlgItem(s_dialog, IDC_TEXT), WM_SETTEXT, 0, (LPARAM) "Shutting Down..."); SendMessage(GetDlgItem(s_launcherInfo.dialog, IDC_TEXT), WM_SETTEXT, 0, (LPARAM) "Shutting Down...");
EnableWindow(GetDlgItem(s_dialog, IDCANCEL), false); EnableWindow(GetDlgItem(s_launcherInfo.dialog, IDCANCEL), false);
} }
} }
break; break;
@ -538,12 +542,6 @@ BOOL CALLBACK SplashDialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM l
static void WindowThreadProc(void *) { static void WindowThreadProc(void *) {
InitCommonControls(); InitCommonControls();
s_event = CreateEvent(
(LPSECURITY_ATTRIBUTES) 0,
false, // auto reset
false, // initial state off
(LPCTSTR) 0 // name
);
if (TGIsCider) if (TGIsCider)
{ {
@ -553,22 +551,22 @@ static void WindowThreadProc(void *) {
pTGApp = pTGLaunchUNIXApp (TG_OLD_DIALOG_POPEN_PATH, "w"); pTGApp = pTGLaunchUNIXApp (TG_OLD_DIALOG_POPEN_PATH, "w");
} }
s_dialog = ::CreateDialog( s_hInstance, MAKEINTRESOURCE( IDD_DIALOG ), NULL, SplashDialogProc ); s_launcherInfo.dialog = ::CreateDialog( s_hInstance, MAKEINTRESOURCE( IDD_DIALOG ), NULL, SplashDialogProc );
SetWindowText(s_dialog, "URU Launcher"); SetWindowText(s_launcherInfo.dialog, "URU Launcher");
::SetDlgItemText( s_dialog, IDC_TEXT, "Initializing patcher..."); ::SetDlgItemText( s_launcherInfo.dialog, IDC_TEXT, "Initializing patcher...");
SetTimer(s_dialog, kEventTimer, 250, 0); SetTimer(s_launcherInfo.dialog, kEventTimer, 250, 0);
char productString[256]; char productString[256];
wchar productStringW[256]; wchar productStringW[256];
ProductString(productStringW, arrsize(productStringW)); ProductString(productStringW, arrsize(productStringW));
StrToAnsi(productString, productStringW, arrsize(productString)); StrToAnsi(productString, productStringW, arrsize(productString));
SendMessage(GetDlgItem(s_dialog, IDC_PRODUCTSTRING), WM_SETTEXT, 0, (LPARAM) productString); SendMessage(GetDlgItem(s_launcherInfo.dialog, IDC_PRODUCTSTRING), WM_SETTEXT, 0, (LPARAM) productString);
s_dialogCreateEvent.Signal(); s_dialogCreateEvent.Signal();
MessagePump(s_dialog); MessagePump(s_launcherInfo.dialog);
if (pTGApp) if (pTGApp)
{ {
@ -577,9 +575,9 @@ static void WindowThreadProc(void *) {
pTGApp = NULL; pTGApp = NULL;
} }
s_dialog = 0; s_launcherInfo.dialog = 0;
s_shutdown = true; s_shutdown = true;
s_shutdownEvent.Signal(); s_shutdownDialogEvent.Signal();
} }
//============================================================================ //============================================================================
@ -712,8 +710,12 @@ static void StatusCallback(void *)
HINTERNET hConnect = 0; HINTERNET hConnect = 0;
// update while we are running // update while we are running
while(!s_shutdown) do
{ {
DWORD result = WaitForSingleObject(s_shutdownDesiredEvent.Handle(), UPDATE_STATUSMSG_SECONDS * 1000);
if (result == WAIT_OBJECT_0)
break;
if(BuildTypeServerStatusPath()) if(BuildTypeServerStatusPath())
{ {
hSession = WinHttpOpen( hSession = WinHttpOpen(
@ -744,12 +746,7 @@ static void StatusCallback(void *)
WinHttpCloseHandle(hConnect); WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hSession); WinHttpCloseHandle(hSession);
} }
} while (!s_shutdown);
for(unsigned i = 0; i < UPDATE_STATUSMSG_SECONDS && !s_shutdown; ++i)
{
Sleep(1000);
}
}
s_statusEvent.Signal(); s_statusEvent.Signal();
} }
@ -1062,15 +1059,16 @@ int __stdcall WinMain (
} }
ShutdownAsyncCore(); ShutdownAsyncCore();
s_statusEvent.Wait(kEventWaitForever);
PostMessage(s_dialog, WM_QUIT, 0, 0); // tell our window to shutdown
s_shutdownEvent.Wait(kEventWaitForever); // wait for our window to shutdown
SetConsoleCtrlHandler(CtrlHandler, FALSE); // Signal teardown of our junk and stuff.
s_shutdownDesiredEvent.Signal();
// Wait for the hwnd and status event to shutdown
s_statusEvent.Wait(kEventWaitForever);
s_shutdownDialogEvent.Wait(kEventWaitForever);
if (s_event) SetConsoleCtrlHandler(CtrlHandler, FALSE);
CloseHandle(s_event);
s_eventQ.Clear(); s_eventQ.Clear();
break; break;

1
MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/Apps/plUruLauncher/Pch.h

@ -52,6 +52,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include <process.h> #include <process.h>
#include <time.h> #include <time.h>
#include "hsThread.h"
#include "pnUtils/pnUtils.h" #include "pnUtils/pnUtils.h"
#include "pnNetBase/pnNetBase.h" #include "pnNetBase/pnNetBase.h"
#include "pnAsyncCore/pnAsyncCore.h" #include "pnAsyncCore/pnAsyncCore.h"

905
MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/Apps/plUruLauncher/SelfPatcher.cpp

File diff suppressed because it is too large Load Diff

1
MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/Apps/plUruLauncher/plLauncherInfo.h

@ -87,6 +87,7 @@ struct plLauncherInfo {
PatchInfo patchInfo; PatchInfo patchInfo;
bool IsTGCider; bool IsTGCider;
DWORD returnCode; // used so we can pass a new process id back to gametap. That way gametap wont think uru has exited when the patcher quits. DWORD returnCode; // used so we can pass a new process id back to gametap. That way gametap wont think uru has exited when the patcher quits.
HWND dialog;
}; };

Loading…
Cancel
Save