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 plLauncherInfo s_launcherInfo;
static HANDLE s_thread;
static HANDLE s_event;
static CEvent s_shutdownDesiredEvent(kEventManualReset);
static HINSTANCE s_hInstance;
static HWND s_dialog;
static CEvent s_dialogCreateEvent(kEventManualReset);
static CCritSect s_critsect;
static LISTDECL(WndEvent, link) s_eventQ;
static CEvent s_shutdownEvent(kEventManualReset);
static CEvent s_shutdownDialogEvent(kEventManualReset);
static wchar s_workingDir[MAX_PATH];
static CEvent s_statusEvent(kEventManualReset);
@ -311,7 +310,7 @@ static void TerminateGame () {
//============================================================================
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)
{
@ -329,7 +328,7 @@ static void Recv_SetProgress (HWND hwnd, const SetProgressEvent &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)
{
@ -347,7 +346,7 @@ static void Recv_SetText (HWND hwnd, const SetTextEvent &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)
{
SendMessage(GetDlgItem(s_dialog, IDC_TIMEREMAINING), WM_SETTEXT, 0, (LPARAM) "estimating...");
SendMessage(GetDlgItem(s_launcherInfo.dialog, IDC_TIMEREMAINING), WM_SETTEXT, 0, (LPARAM) "...");
return;
}
@ -392,7 +391,7 @@ static void Recv_SetTimeRemaining (HWND hwnd, const SetTimeRemainingEvent &event
StrPrintf(text, arrsize(text), "%s%d min ", text, minutes);
if( seconds || !text[0])
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 bytes = event.bytes;
if (bytes == 0xffffffff) {
SendMessage(GetDlgItem(s_launcherInfo.dialog, IDC_BYTESREMAINING), WM_SETTEXT, 0, (LPARAM) "...");
return;
}
unsigned GB = bytes / 1000000000;
if(GB)
{
@ -416,7 +420,7 @@ static void Recv_SetBytesRemaining (HWND hwnd, const SetBytesRemainingEvent &eve
decimal = bytes / 100000; // to one decimal place
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
const DWORD result = MsgWaitForMultipleObjects(
1,
&s_event,
&s_shutdownDesiredEvent.Handle(),
false,
INFINITE,
QS_ALLEVENTS
);
if (result == WAIT_OBJECT_0)
return;
PostQuitMessage(0);
// process windows messages
MSG msg;
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
if (!IsDialogMessage(s_dialog, &msg)) {
if (!IsDialogMessage(s_launcherInfo.dialog, &msg)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
@ -503,8 +507,8 @@ BOOL CALLBACK SplashDialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM l
if(!s_shutdown)
{
s_shutdown = true;
SendMessage(GetDlgItem(s_dialog, IDC_TEXT), WM_SETTEXT, 0, (LPARAM) "Shutting Down...");
EnableWindow(GetDlgItem(s_dialog, IDCANCEL), false);
SendMessage(GetDlgItem(s_launcherInfo.dialog, IDC_TEXT), WM_SETTEXT, 0, (LPARAM) "Shutting Down...");
EnableWindow(GetDlgItem(s_launcherInfo.dialog, IDCANCEL), false);
}
}
break;
@ -538,12 +542,6 @@ BOOL CALLBACK SplashDialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM l
static void WindowThreadProc(void *) {
InitCommonControls();
s_event = CreateEvent(
(LPSECURITY_ATTRIBUTES) 0,
false, // auto reset
false, // initial state off
(LPCTSTR) 0 // name
);
if (TGIsCider)
{
@ -553,22 +551,22 @@ static void WindowThreadProc(void *) {
pTGApp = pTGLaunchUNIXApp (TG_OLD_DIALOG_POPEN_PATH, "w");
}
s_dialog = ::CreateDialog( s_hInstance, MAKEINTRESOURCE( IDD_DIALOG ), NULL, SplashDialogProc );
SetWindowText(s_dialog, "URU Launcher");
s_launcherInfo.dialog = ::CreateDialog( s_hInstance, MAKEINTRESOURCE( IDD_DIALOG ), NULL, SplashDialogProc );
SetWindowText(s_launcherInfo.dialog, "URU Launcher");
::SetDlgItemText( s_dialog, IDC_TEXT, "Initializing patcher...");
SetTimer(s_dialog, kEventTimer, 250, 0);
::SetDlgItemText( s_launcherInfo.dialog, IDC_TEXT, "Initializing patcher...");
SetTimer(s_launcherInfo.dialog, kEventTimer, 250, 0);
char productString[256];
wchar productStringW[256];
ProductString(productStringW, arrsize(productStringW));
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();
MessagePump(s_dialog);
MessagePump(s_launcherInfo.dialog);
if (pTGApp)
{
@ -577,9 +575,9 @@ static void WindowThreadProc(void *) {
pTGApp = NULL;
}
s_dialog = 0;
s_launcherInfo.dialog = 0;
s_shutdown = true;
s_shutdownEvent.Signal();
s_shutdownDialogEvent.Signal();
}
//============================================================================
@ -712,8 +710,12 @@ static void StatusCallback(void *)
HINTERNET hConnect = 0;
// 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())
{
hSession = WinHttpOpen(
@ -744,12 +746,7 @@ static void StatusCallback(void *)
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hSession);
}
for(unsigned i = 0; i < UPDATE_STATUSMSG_SECONDS && !s_shutdown; ++i)
{
Sleep(1000);
}
}
} while (!s_shutdown);
s_statusEvent.Signal();
}
@ -1062,15 +1059,16 @@ int __stdcall WinMain (
}
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)
CloseHandle(s_event);
SetConsoleCtrlHandler(CtrlHandler, FALSE);
s_eventQ.Clear();
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 <time.h>
#include "hsThread.h"
#include "pnUtils/pnUtils.h"
#include "pnNetBase/pnNetBase.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;
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.
HWND dialog;
};

Loading…
Cancel
Save