You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
500 lines
13 KiB
500 lines
13 KiB
14 years ago
|
/*==LICENSE==*
|
||
|
|
||
|
CyanWorlds.com Engine - MMOG client, server and tools
|
||
|
Copyright (C) 2011 Cyan Worlds, Inc.
|
||
|
|
||
|
This program is free software: you can redistribute it and/or modify
|
||
|
it under the terms of the GNU General Public License as published by
|
||
|
the Free Software Foundation, either version 3 of the License, or
|
||
|
(at your option) any later version.
|
||
|
|
||
|
This program is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
GNU General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU General Public License
|
||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
|
||
|
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||
|
or by snail mail at:
|
||
|
Cyan Worlds, Inc.
|
||
|
14617 N Newport Hwy
|
||
|
Mead, WA 99021
|
||
|
|
||
|
*==LICENSE==*/
|
||
|
#include "HeadSpin.h"
|
||
|
#include "plPlasmaUpdate.h"
|
||
|
#include "resource.h"
|
||
|
#include <windowsx.h>
|
||
|
#include <commctrl.h>
|
||
|
#include <direct.h>
|
||
|
#include "jvCoreUtil.h"
|
||
|
#include "jvDialogResizer.h"
|
||
|
|
||
|
#include "hsTypes.h"
|
||
|
#include "../plFile/plFileUtils.h"
|
||
|
#include "../plUnifiedTime/plUnifiedTime.h"
|
||
|
#include "hsStream.h"
|
||
|
#include "plManifest.h"
|
||
|
#include "hsUtils.h"
|
||
|
#include "../plStatusLog/plStatusLog.h"
|
||
|
|
||
|
static plPlasmaUpdate* gInst = nil;
|
||
|
|
||
|
#define WM_UPDATE_SERVER WM_APP+1
|
||
|
|
||
|
std::string plPlasmaUpdate::fUserName = "dataserver";
|
||
|
std::string plPlasmaUpdate::fPassword = "parabledata";
|
||
|
|
||
|
plPlasmaUpdate::plPlasmaUpdate() : fCanExit(true), fProgressType(kValidating), fResizer(nil), fAutoDownload(false)
|
||
|
{
|
||
|
INITCOMMONCONTROLSEX icc = {0};
|
||
|
icc.dwSize = sizeof(INITCOMMONCONTROLSEX);
|
||
|
icc.dwICC = ICC_PROGRESS_CLASS;
|
||
|
InitCommonControlsEx(&icc);
|
||
|
gInst = this;
|
||
|
|
||
|
_getcwd(fIniPath, sizeof(fIniPath));
|
||
|
char lastChar = fIniPath[strlen(fIniPath)];
|
||
|
if (lastChar != '\\' && lastChar != '/')
|
||
|
strcat(fIniPath, "\\");
|
||
|
strcat(fIniPath, "ParableUpdate.ini");
|
||
|
|
||
|
fFileGrabber = new plNetShareFileGrabber;
|
||
|
}
|
||
|
|
||
|
plPlasmaUpdate::~plPlasmaUpdate()
|
||
|
{
|
||
|
delete fResizer;
|
||
|
if (fFileGrabber)
|
||
|
delete fFileGrabber;
|
||
|
}
|
||
|
|
||
|
bool plPlasmaUpdate::Create()
|
||
|
{
|
||
|
if (!fServers.GetServerInfo())
|
||
|
return false;
|
||
|
|
||
|
ICreateDialog(IDD_UPDATE, NULL);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
BOOL CALLBACK plPlasmaUpdate::ILoginWinProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
||
|
{
|
||
|
switch( msg )
|
||
|
{
|
||
|
case WM_INITDIALOG:
|
||
|
SetFocus(GetDlgItem(hDlg, IDC_USERNAME));
|
||
|
break;
|
||
|
case WM_COMMAND:
|
||
|
if (HIWORD(wParam) == BN_CLICKED && (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL))
|
||
|
{
|
||
|
bool ok = (LOWORD(wParam) == IDOK);
|
||
|
if (ok)
|
||
|
{
|
||
|
char username[25];
|
||
|
char password[25];
|
||
|
|
||
|
GetDlgItemText(hDlg, IDC_USERNAME, username, 25);
|
||
|
GetDlgItemText(hDlg, IDC_PASSWORD, password, 25);
|
||
|
|
||
|
fUserName = username;
|
||
|
hsAssert(false, "who uses this program?");
|
||
|
// plChallengeResponse::HashPassword(password, fPassword);
|
||
|
}
|
||
|
EndDialog(hDlg, ok);
|
||
|
return TRUE;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
void plPlasmaUpdate::IInit()
|
||
|
{
|
||
|
char curServerAddress[256];
|
||
|
GetPrivateProfileString("PlasmaUpdate", "ServerAddress", "", curServerAddress, sizeof(curServerAddress), fIniPath);
|
||
|
bool external = (GetPrivateProfileInt("PlasmaUpdate", "External", 0, fIniPath) != 0);
|
||
|
|
||
|
HWND hCombo = GetDlgItem(fDlg, IDC_BUILD_COMBO);
|
||
|
|
||
|
for (int i = 0; i < fServers.GetNumServers(); i++)
|
||
|
{
|
||
|
std::string& serverAddress = fServers.GetServerAddress(i);
|
||
|
std::string& serverName = fServers.GetServerName(i);
|
||
|
std::string& currentDir = fServers.GetServerCurrentDir(i);
|
||
|
|
||
|
if (!fFileGrabber->IsServerAvailable(serverAddress.c_str(), currentDir.c_str()))
|
||
|
continue;
|
||
|
|
||
|
bool thisServer = (serverAddress == curServerAddress);
|
||
|
|
||
|
int idx = ComboBox_AddString(hCombo, serverName.c_str());
|
||
|
ComboBox_SetItemData(hCombo, idx, MAKELPARAM(i, 0));
|
||
|
if (thisServer && !external)
|
||
|
ComboBox_SetCurSel(hCombo, idx);
|
||
|
|
||
|
std::string extName = serverName + " (External)";
|
||
|
idx = ComboBox_AddString(hCombo, extName.c_str());
|
||
|
ComboBox_SetItemData(hCombo, idx, MAKELPARAM(i, 1));
|
||
|
if (thisServer && external)
|
||
|
ComboBox_SetCurSel(hCombo, idx);
|
||
|
}
|
||
|
|
||
|
if (ComboBox_GetCurSel(hCombo) == -1)
|
||
|
ComboBox_SetCurSel(hCombo, 0);
|
||
|
|
||
|
SendMessage(fDlg, WM_SETICON, ICON_BIG, (LPARAM)LoadIcon(jvCoreUtil::GetHInstance(), MAKEINTRESOURCE(IDI_ICON)));
|
||
|
SendMessage(fDlg, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon(jvCoreUtil::GetHInstance(), MAKEINTRESOURCE(IDI_ICON)));
|
||
|
|
||
|
fResizer = new jvDialogResizer(fDlg);
|
||
|
fResizer->AddControl(IDC_BUILD_COMBO, jvDialogResizer::kResizeX);
|
||
|
fResizer->AddControl(IDC_STATUS_LIST, jvDialogResizer::kResizeX | jvDialogResizer::kResizeY);
|
||
|
fResizer->AddControl(IDC_PROGRESS, jvDialogResizer::kLockBottom | jvDialogResizer::kResizeX);
|
||
|
fResizer->AddControl(IDC_DL_TEXT, jvDialogResizer::kLockBottom | jvDialogResizer::kResizeX);
|
||
|
fResizer->AddControl(IDC_DL_BUTTON, jvDialogResizer::kLockBottom | jvDialogResizer::kCenterX);
|
||
|
fResizer->SetSize(360, 320);
|
||
|
fResizer->LoadPosAndSize("PlasmaUpdate");
|
||
|
|
||
|
bool goTime = true;
|
||
|
if (fFileGrabber->NeedsAuth())
|
||
|
{
|
||
|
/*
|
||
|
if (!DialogBox(NULL, MAKEINTRESOURCE(IDD_PLASMAUPDATE_LOGIN), fDlg, ILoginWinProc))
|
||
|
goTime = false;
|
||
|
else
|
||
|
*/
|
||
|
fFileGrabber->SetUsernamePassword(fUserName, fPassword);
|
||
|
}
|
||
|
|
||
|
if (goTime)
|
||
|
{
|
||
|
ShowWindow(fDlg, SW_SHOW);
|
||
|
PostMessage(fDlg, WM_UPDATE_SERVER, 0, 0);
|
||
|
}
|
||
|
else
|
||
|
PostQuitMessage(0);
|
||
|
}
|
||
|
|
||
|
void plPlasmaUpdate::IShutdown()
|
||
|
{
|
||
|
fResizer->SavePosAndSize("PlasmaUpdate");
|
||
|
delete fResizer;
|
||
|
fResizer = NULL;
|
||
|
|
||
|
IDeleteManifests();
|
||
|
}
|
||
|
|
||
|
void plPlasmaUpdate::IEnableCtrls(bool enable)
|
||
|
{
|
||
|
fCanExit = enable;
|
||
|
EnableWindow(GetDlgItem(fDlg, IDC_BUILD_COMBO), enable);
|
||
|
|
||
|
HWND hDlButton = GetDlgItem(fDlg, IDC_DL_BUTTON);
|
||
|
|
||
|
if (fManifests.empty())
|
||
|
SetWindowText(hDlButton, "Close");
|
||
|
else
|
||
|
SetWindowText(hDlButton, "Download");
|
||
|
|
||
|
EnableWindow(hDlButton, enable);
|
||
|
|
||
|
if (enable)
|
||
|
SetFocus(hDlButton);
|
||
|
}
|
||
|
|
||
|
void plPlasmaUpdate::IDeleteManifests()
|
||
|
{
|
||
|
for (int i = 0; i < fManifests.size(); i++)
|
||
|
delete fManifests[i];
|
||
|
fManifests.clear();
|
||
|
}
|
||
|
|
||
|
bool plPlasmaUpdate::IGetManifests(const char* serverRoot, bool external)
|
||
|
{
|
||
|
IDeleteManifests();
|
||
|
|
||
|
char filePath[MAX_PATH];
|
||
|
sprintf(filePath, "%sCurrent.txt", serverRoot);
|
||
|
|
||
|
enum Sections
|
||
|
{
|
||
|
kVersion,
|
||
|
kInternal,
|
||
|
kExternal,
|
||
|
kAll
|
||
|
};
|
||
|
int curSection = kVersion;
|
||
|
|
||
|
hsRAMStream s;
|
||
|
hsRAMStream manifestStream;
|
||
|
|
||
|
if (fFileGrabber->FileToStream(filePath, &s))
|
||
|
{
|
||
|
char buf[256];
|
||
|
while (s.ReadLn(buf, sizeof(buf)))
|
||
|
{
|
||
|
if (buf[0] == '[')
|
||
|
{
|
||
|
if (hsStrEQ(buf, "[Version]"))
|
||
|
curSection = kVersion;
|
||
|
else if (hsStrEQ(buf, "[Internal]"))
|
||
|
curSection = kInternal;
|
||
|
else if (hsStrEQ(buf, "[External]"))
|
||
|
curSection = kExternal;
|
||
|
else if (hsStrEQ(buf, "[All]"))
|
||
|
curSection = kAll;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (curSection == kVersion)
|
||
|
{
|
||
|
int version = atoi(buf);
|
||
|
if (version != 1)
|
||
|
{
|
||
|
hsMessageBox("Your copy of PlasmaUpdate is out of date.\nPlease get the latest version.", "Error", hsMessageBoxNormal, hsMessageBoxIconError);
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
else if ((!external && curSection == kInternal)
|
||
|
|| (external && curSection == kExternal)
|
||
|
|| curSection == kAll)
|
||
|
{
|
||
|
//if (curSection == kAll && !(!strcmp(buf, "Data\\Movies.mfs") || !strcmp(buf, "Data\\Sounds.mfs")))
|
||
|
// continue;
|
||
|
|
||
|
sprintf(filePath, "%s%s", serverRoot, buf);
|
||
|
|
||
|
fFileGrabber->MakeProperPath(filePath);
|
||
|
|
||
|
manifestStream.Reset();
|
||
|
fFileGrabber->FileToStream(filePath, &manifestStream);
|
||
|
|
||
|
plFileUtils::StripFile(filePath);
|
||
|
|
||
|
plManifest* manifest = new plManifest(ILog);
|
||
|
manifest->Read(&manifestStream, filePath, buf);
|
||
|
fManifests.push_back(manifest);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
void plPlasmaUpdate::IUpdateServer()
|
||
|
{
|
||
|
char buf[256];
|
||
|
|
||
|
IEnableCtrls(false);
|
||
|
|
||
|
SetDlgItemText(fDlg, IDC_DL_TEXT, "Checking for updates...");
|
||
|
|
||
|
//
|
||
|
// Figure out what server we're checking
|
||
|
//
|
||
|
bool external = false;
|
||
|
char serverRoot[MAX_PATH];
|
||
|
|
||
|
{
|
||
|
HWND hCombo = GetDlgItem(fDlg, IDC_BUILD_COMBO);
|
||
|
int idx = ComboBox_GetCurSel(hCombo);
|
||
|
LPARAM data = ComboBox_GetItemData(hCombo, idx);
|
||
|
int server = LOWORD(data);
|
||
|
external = (HIWORD(data) != 0);
|
||
|
|
||
|
sprintf(serverRoot, "/%s/", fServers.GetServerCurrentDir(server).c_str());
|
||
|
const char* serverName = fServers.GetServerAddress(server).c_str();
|
||
|
|
||
|
ILog("===== Server set to %s %s =====", serverName, external ? "external" : "internal");
|
||
|
|
||
|
WritePrivateProfileString("PlasmaUpdate", "ServerAddress", serverName, fIniPath);
|
||
|
WritePrivateProfileString("PlasmaUpdate", "External", external ? "1" : "0", fIniPath);
|
||
|
|
||
|
fFileGrabber->SetServer(serverName);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Get the latest publish notes
|
||
|
//
|
||
|
{
|
||
|
HWND hList = GetDlgItem(fDlg, IDC_STATUS_LIST);
|
||
|
ListBox_ResetContent(hList);
|
||
|
|
||
|
char updateFile[MAX_PATH];
|
||
|
if (external)
|
||
|
sprintf(updateFile, "%sUpdates-External.txt", serverRoot);
|
||
|
else
|
||
|
sprintf(updateFile, "%sUpdates-Internal.txt", serverRoot);
|
||
|
|
||
|
hsRAMStream updates;
|
||
|
fFileGrabber->MakeProperPath(updateFile);
|
||
|
if (fFileGrabber->FileToStream(updateFile, &updates))
|
||
|
{
|
||
|
while (updates.ReadLn(buf, sizeof(buf)))
|
||
|
ListBox_InsertString(hList, 0, buf);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Get the manifests
|
||
|
//
|
||
|
bool gotManifests = IGetManifests(serverRoot, external);
|
||
|
UInt32 dlSize = 0;
|
||
|
|
||
|
fProgressType = kValidating;
|
||
|
|
||
|
if (gotManifests)
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
UInt32 numFiles = 0;
|
||
|
for (i = 0; i < fManifests.size(); i++)
|
||
|
numFiles += fManifests[i]->NumFiles();
|
||
|
|
||
|
HWND hProgress = GetDlgItem(fDlg, IDC_PROGRESS);
|
||
|
SendMessage(hProgress, PBM_SETRANGE32, 0, numFiles);
|
||
|
|
||
|
for (i = 0; i < fManifests.size(); i++)
|
||
|
{
|
||
|
fManifests[i]->ValidateFiles(ProgressFunc);
|
||
|
dlSize += fManifests[i]->DownloadSize();
|
||
|
}
|
||
|
|
||
|
SendMessage(hProgress, PBM_SETPOS, 0, 0);
|
||
|
}
|
||
|
|
||
|
// Print how many megs there are to download
|
||
|
if (dlSize == 0)
|
||
|
{
|
||
|
strcpy(buf, "No updates to download");
|
||
|
IDeleteManifests();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
float dlMegs = float(dlSize) / (1024.f*1024.f);
|
||
|
if (dlMegs < .1)
|
||
|
dlMegs = .1;
|
||
|
sprintf(buf, "%.1f MB of updates to download", dlMegs);
|
||
|
}
|
||
|
SetDlgItemText(fDlg, IDC_DL_TEXT, buf);
|
||
|
|
||
|
IEnableCtrls(true);
|
||
|
|
||
|
if (fAutoDownload)
|
||
|
PostMessage(fDlg, WM_COMMAND, MAKEWPARAM(IDC_DL_BUTTON, BN_CLICKED), LPARAM(GetDlgItem(fDlg, IDC_DL_BUTTON)));
|
||
|
}
|
||
|
|
||
|
void plPlasmaUpdate::IDownloadUpdates()
|
||
|
{
|
||
|
fProgressType = kDownloading;
|
||
|
|
||
|
IEnableCtrls(false);
|
||
|
|
||
|
int i;
|
||
|
|
||
|
UInt32 dlSize = 0;
|
||
|
for (i = 0; i < fManifests.size(); i++)
|
||
|
dlSize += fManifests[i]->DownloadSize();
|
||
|
|
||
|
HWND hProgress = GetDlgItem(fDlg, IDC_PROGRESS);
|
||
|
SendMessage(hProgress, PBM_SETRANGE32, 0, dlSize);
|
||
|
|
||
|
for (i = 0; i < fManifests.size(); i++)
|
||
|
fManifests[i]->DownloadUpdates(ProgressFunc, fFileGrabber);
|
||
|
|
||
|
SendMessage(hProgress, PBM_SETPOS, 0, 0);
|
||
|
|
||
|
EnableWindow(GetDlgItem(fDlg, IDC_DL_BUTTON), false);
|
||
|
SetDlgItemText(fDlg, IDC_DL_TEXT, "No updates to download");
|
||
|
|
||
|
IDeleteManifests();
|
||
|
|
||
|
IEnableCtrls(true);
|
||
|
|
||
|
if (fAutoDownload)
|
||
|
PostMessage(fDlg, WM_COMMAND, MAKEWPARAM(IDC_DL_BUTTON, BN_CLICKED), LPARAM(GetDlgItem(fDlg, IDC_DL_BUTTON)));
|
||
|
}
|
||
|
|
||
|
void plPlasmaUpdate::ProgressFunc(const char* name, int delta)
|
||
|
{
|
||
|
static const char* lastName = nil;
|
||
|
if (lastName != name)
|
||
|
{
|
||
|
lastName = name;
|
||
|
|
||
|
char buf[256];
|
||
|
if (gInst->fProgressType == kValidating)
|
||
|
strcpy(buf, "Checking ");
|
||
|
else
|
||
|
strcpy(buf, "Downloading ");
|
||
|
strcat(buf, name);
|
||
|
|
||
|
SetDlgItemText(gInst->fDlg, IDC_DL_TEXT, buf);
|
||
|
}
|
||
|
|
||
|
SendDlgItemMessage(gInst->fDlg, IDC_PROGRESS, PBM_DELTAPOS, delta, 0);
|
||
|
|
||
|
jvBaseDlg::PumpQueue();
|
||
|
}
|
||
|
|
||
|
void plPlasmaUpdate::ILog(const char* format, ...)
|
||
|
{
|
||
|
static plStatusLog* log = nil;
|
||
|
|
||
|
if (!log)
|
||
|
log = plStatusLogMgr::GetInstance().CreateStatusLog(0, "PlasmaUpdate.log");
|
||
|
|
||
|
va_list args;
|
||
|
va_start(args, format);
|
||
|
log->AddLineV(format, args);
|
||
|
va_end(args);
|
||
|
}
|
||
|
|
||
|
BOOL plPlasmaUpdate::IDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
||
|
{
|
||
|
switch (msg)
|
||
|
{
|
||
|
case WM_INITDIALOG:
|
||
|
IInit();
|
||
|
SetFocus(GetDlgItem(fDlg, IDC_DL_BUTTON));
|
||
|
return FALSE;
|
||
|
|
||
|
case WM_CLOSE:
|
||
|
if (fCanExit)
|
||
|
DestroyWindow(hDlg);
|
||
|
return TRUE;
|
||
|
|
||
|
case WM_DESTROY:
|
||
|
IShutdown();
|
||
|
PostQuitMessage(0);
|
||
|
return TRUE;
|
||
|
|
||
|
case WM_COMMAND:
|
||
|
if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_DL_BUTTON)
|
||
|
{
|
||
|
if (fManifests.empty())
|
||
|
SendMessage(fDlg, WM_CLOSE, 0, 0);
|
||
|
else
|
||
|
IDownloadUpdates();
|
||
|
return TRUE;
|
||
|
}
|
||
|
else if (HIWORD(wParam) == CBN_SELCHANGE && LOWORD(wParam) == IDC_BUILD_COMBO)
|
||
|
{
|
||
|
IUpdateServer();
|
||
|
return TRUE;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case WM_UPDATE_SERVER:
|
||
|
IUpdateServer();
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|