Branan Purvine-Riley
13 years ago
19 changed files with 294 additions and 1205 deletions
@ -1,545 +0,0 @@ |
|||||||
/*==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/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7 |
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or |
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, |
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent |
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK |
|
||||||
(or a modified version of those libraries), |
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, |
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG |
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the |
|
||||||
licensors of this Program grant you additional |
|
||||||
permission to convey the resulting work. Corresponding Source for a |
|
||||||
non-source form of such a combination shall include the source code for |
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered |
|
||||||
work. |
|
||||||
|
|
||||||
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 "plBackgroundDownloader.h" |
|
||||||
|
|
||||||
#include <process.h> |
|
||||||
|
|
||||||
#include "pnUtils/pnUtils.h" |
|
||||||
#include "pnNetBase/pnNetBase.h" |
|
||||||
#include "plEncryption/plChecksum.h" |
|
||||||
|
|
||||||
#include "hsResMgr.h" |
|
||||||
|
|
||||||
#include "plAgeDescription/plAgeManifest.h" |
|
||||||
#include "plResMgr/plResManager.h" |
|
||||||
#include "plFile/plFileUtils.h" |
|
||||||
#include "plFile/plEncryptedStream.h" |
|
||||||
#include "plCompression/plZlibStream.h" |
|
||||||
#include "plAudioCore/plAudioFileReader.h" |
|
||||||
#include "plProgressMgr/plProgressMgr.h" |
|
||||||
|
|
||||||
#include "pnAsyncCore/pnAsyncCore.h" |
|
||||||
#include "pnNetCli/pnNetCli.h" |
|
||||||
#include "plNetGameLib/plNetGameLib.h" |
|
||||||
|
|
||||||
#include "pnDispatch/plDispatch.h" |
|
||||||
#include "plStatusLog/plStatusLog.h" |
|
||||||
|
|
||||||
static const unsigned kMaxDownloadTries = 10; |
|
||||||
static const wchar s_manifest[] = L"AllAges"; |
|
||||||
|
|
||||||
plBackgroundDownloader* plBackgroundDownloader::fInstance = NULL; |
|
||||||
|
|
||||||
hsBool gUseBackgroundDownloader = false; |
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
enum DownloaderLogType |
|
||||||
{ |
|
||||||
kHeader, |
|
||||||
kInfo, |
|
||||||
kMajorStatus, |
|
||||||
kStatus, |
|
||||||
kError, |
|
||||||
}; |
|
||||||
void BackgroundDownloaderLog(DownloaderLogType type, const char* format, ...) |
|
||||||
{ |
|
||||||
UInt32 color = 0; |
|
||||||
switch (type) |
|
||||||
{ |
|
||||||
case kHeader: color = plStatusLog::kWhite; break; |
|
||||||
case kInfo: color = plStatusLog::kBlue; break; |
|
||||||
case kMajorStatus: color = plStatusLog::kYellow; break; |
|
||||||
case kStatus: color = plStatusLog::kGreen; break; |
|
||||||
case kError: color = plStatusLog::kRed; break; |
|
||||||
} |
|
||||||
|
|
||||||
static plStatusLog* gStatusLog = nil; |
|
||||||
if (!gStatusLog) |
|
||||||
{ |
|
||||||
gStatusLog = plStatusLogMgr::GetInstance().CreateStatusLog( |
|
||||||
20, |
|
||||||
"bgdownload.log", |
|
||||||
plStatusLog::kFilledBackground | plStatusLog::kAlignToTop | plStatusLog::kDeleteForMe); |
|
||||||
} |
|
||||||
|
|
||||||
va_list args; |
|
||||||
va_start(args, format); |
|
||||||
|
|
||||||
gStatusLog->AddLineV(color, format, args); |
|
||||||
|
|
||||||
va_end(args); |
|
||||||
} |
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
class plBGDownloadStream : public plZlibStream |
|
||||||
{ |
|
||||||
public: |
|
||||||
plBGDownloadStream() : plZlibStream() {} |
|
||||||
virtual ~plBGDownloadStream() {} |
|
||||||
|
|
||||||
virtual UInt32 Write(UInt32 byteCount, const void* buffer); |
|
||||||
}; |
|
||||||
|
|
||||||
UInt32 plBGDownloadStream::Write(UInt32 byteCount, const void* buffer) |
|
||||||
{ |
|
||||||
return plZlibStream::Write(byteCount, buffer); |
|
||||||
} |
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
static void DownloadFileCallback(ENetError result, void* param, const wchar filename[], hsStream* writer) |
|
||||||
{ |
|
||||||
plBackgroundDownloader* bgdownloader = (plBackgroundDownloader*)param; |
|
||||||
|
|
||||||
// Retry download unless shutting down or file not found
|
|
||||||
switch (result) { |
|
||||||
case kNetSuccess: |
|
||||||
writer->Close(); |
|
||||||
bgdownloader->DoneWithFile(true); |
|
||||||
break; |
|
||||||
|
|
||||||
case kNetErrFileNotFound: |
|
||||||
case kNetErrRemoteShutdown: |
|
||||||
writer->Close(); |
|
||||||
bgdownloader->DoneWithFile(false); |
|
||||||
break; |
|
||||||
|
|
||||||
default: |
|
||||||
writer->Rewind(); |
|
||||||
NetCliFileDownloadRequest( |
|
||||||
filename, |
|
||||||
writer, |
|
||||||
DownloadFileCallback, |
|
||||||
param |
|
||||||
); |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void ManifestCallback(ENetError result, void* param, const wchar group[], const NetCliFileManifestEntry manifest[], unsigned entryCount) |
|
||||||
{ |
|
||||||
plBackgroundDownloader* bgdownloader = (plBackgroundDownloader*)param; |
|
||||||
bgdownloader->DoneWithManifest(result == kNetSuccess, manifest, entryCount); |
|
||||||
} |
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
plBackgroundDownloader* plBackgroundDownloader::GetInstance() |
|
||||||
{ |
|
||||||
return fInstance; |
|
||||||
} |
|
||||||
|
|
||||||
void plBackgroundDownloader::ThreadMain(void * param) |
|
||||||
{ |
|
||||||
Init(); |
|
||||||
|
|
||||||
plBackgroundDownloader::GetInstance()->Run(); |
|
||||||
plBackgroundDownloader::GetInstance()->CleanUp(); |
|
||||||
|
|
||||||
Shutdown(); |
|
||||||
} |
|
||||||
|
|
||||||
void plBackgroundDownloader::StartThread() |
|
||||||
{ |
|
||||||
_beginthread(plBackgroundDownloader::ThreadMain, 0, NULL); |
|
||||||
} |
|
||||||
|
|
||||||
void plBackgroundDownloader::Init() |
|
||||||
{ |
|
||||||
fInstance = TRACKED_NEW plBackgroundDownloader(); |
|
||||||
} |
|
||||||
|
|
||||||
void plBackgroundDownloader::Shutdown() |
|
||||||
{ |
|
||||||
delete fInstance; |
|
||||||
fInstance = NULL; |
|
||||||
} |
|
||||||
|
|
||||||
plBackgroundDownloader::plBackgroundDownloader() |
|
||||||
{ |
|
||||||
BackgroundDownloaderLog(kHeader, "--- Starting background download ---"); |
|
||||||
|
|
||||||
fBGDownloaderRun = CreateEvent( |
|
||||||
NULL, // default security attributes
|
|
||||||
TRUE, // manual-reset event
|
|
||||||
FALSE, // initial state is signaled
|
|
||||||
NULL // unnamed
|
|
||||||
); |
|
||||||
|
|
||||||
fBGDownloaderIsPaused = CreateEvent( |
|
||||||
NULL, // default security attributes
|
|
||||||
FALSE, // manual-reset event
|
|
||||||
TRUE, // initial state is signaled
|
|
||||||
NULL // unnamed
|
|
||||||
); |
|
||||||
} |
|
||||||
|
|
||||||
plBackgroundDownloader::~plBackgroundDownloader() |
|
||||||
{ |
|
||||||
HANDLE runHandle = fBGDownloaderRun; |
|
||||||
fBGDownloaderRun = NULL; |
|
||||||
CloseHandle(runHandle); |
|
||||||
|
|
||||||
HANDLE pausedHandle = fBGDownloaderIsPaused; |
|
||||||
fBGDownloaderIsPaused = NULL; |
|
||||||
CloseHandle(pausedHandle); |
|
||||||
|
|
||||||
BackgroundDownloaderLog(kHeader, "--- Background download done ---"); |
|
||||||
} |
|
||||||
|
|
||||||
UInt32 plBackgroundDownloader::IGetDownloadSize() |
|
||||||
{ |
|
||||||
if (!IGetDataManifest()) |
|
||||||
return 0; |
|
||||||
|
|
||||||
UInt32 downloadSize = 0; |
|
||||||
UInt32 downloadFiles = 0; |
|
||||||
for (MfsFileVec::iterator i = fMfsVec.begin(); i != fMfsVec.end(); ++i) |
|
||||||
{ |
|
||||||
plManifestFile* mfsFile = (*i); |
|
||||||
|
|
||||||
if (!mfsFile->IsLocalUpToDate()) |
|
||||||
{ |
|
||||||
downloadFiles++; |
|
||||||
downloadSize += mfsFile->GetDownloadSize(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
BackgroundDownloaderLog(kInfo, "Got download stats, %d files, %d bytes", downloadFiles, downloadSize); |
|
||||||
|
|
||||||
return downloadSize; |
|
||||||
} |
|
||||||
|
|
||||||
bool plBackgroundDownloader::CheckFreeSpace(UInt32 bytesNeeded) |
|
||||||
{ |
|
||||||
#ifdef HS_BUILD_FOR_WIN32 |
|
||||||
ULARGE_INTEGER freeBytesAvailable, totalNumberOfBytes, neededBytes; |
|
||||||
if (GetDiskFreeSpaceEx(NULL, &freeBytesAvailable, &totalNumberOfBytes, NULL)) |
|
||||||
{ |
|
||||||
neededBytes.HighPart = 0; |
|
||||||
neededBytes.LowPart = bytesNeeded; |
|
||||||
|
|
||||||
if (neededBytes.QuadPart > freeBytesAvailable.QuadPart) |
|
||||||
{ |
|
||||||
BackgroundDownloaderLog(kInfo, "Not enough disk space (asked for %d bytes)", bytesNeeded); |
|
||||||
return false; |
|
||||||
} |
|
||||||
} |
|
||||||
#endif // HS_BUILD_FOR_WIN32
|
|
||||||
|
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
bool plBackgroundDownloader::IDecompressSound(plManifestFile* mfsFile, bool noOverwrite) |
|
||||||
{ |
|
||||||
UInt32 flags = mfsFile->GetFlags(); |
|
||||||
|
|
||||||
if ( (hsCheckBits(flags, plManifestFile::kSndFlagCacheSplit) || hsCheckBits(flags, plManifestFile::kSndFlagCacheStereo)) && stricmp(plFileUtils::GetFileExt(mfsFile->GetName()), "ogg") == 0) |
|
||||||
{ |
|
||||||
plAudioFileReader* reader = plAudioFileReader::CreateReader(mfsFile->GetName(), plAudioCore::kAll, plAudioFileReader::kStreamNative); |
|
||||||
if (!reader) |
|
||||||
{ |
|
||||||
BackgroundDownloaderLog(kInfo, "Unable to create audio file reader for %s", mfsFile->GetName()); |
|
||||||
return false; |
|
||||||
} |
|
||||||
|
|
||||||
UInt32 size = reader->GetDataSize(); |
|
||||||
delete reader; |
|
||||||
|
|
||||||
// Make sure we have enough free space
|
|
||||||
if (!CheckFreeSpace(size)) |
|
||||||
return false; |
|
||||||
|
|
||||||
if (hsCheckBits(flags, plManifestFile::kSndFlagCacheSplit)) |
|
||||||
plAudioFileReader::CacheFile(mfsFile->GetName(), true, noOverwrite); |
|
||||||
if (hsCheckBits(flags, plManifestFile::kSndFlagCacheStereo)) |
|
||||||
plAudioFileReader::CacheFile(mfsFile->GetName(), false, noOverwrite); |
|
||||||
} |
|
||||||
|
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
bool plBackgroundDownloader::Run() |
|
||||||
{ |
|
||||||
// Wait to be signaled that we've gotten at least as far as the startup age
|
|
||||||
WaitForSingleObject(fBGDownloaderRun, INFINITE); |
|
||||||
|
|
||||||
IGetDataManifest(); |
|
||||||
|
|
||||||
plFileUtils::CreateDir("dat"); |
|
||||||
plFileUtils::CreateDir("sfx"); |
|
||||||
|
|
||||||
bool result = true; |
|
||||||
plResManager* resMgr = ((plResManager*)hsgResMgr::ResMgr()); |
|
||||||
|
|
||||||
for (MfsFileVec::iterator i = fMfsVec.begin(); i != fMfsVec.end(); ++i) |
|
||||||
{ |
|
||||||
plManifestFile* mfsFile = (*i); |
|
||||||
|
|
||||||
if (!mfsFile->IsLocalUpToDate()) |
|
||||||
{ |
|
||||||
if (!CheckFreeSpace(mfsFile->GetDiskSize())) |
|
||||||
return false; |
|
||||||
|
|
||||||
FileType type = IGetFile(mfsFile); |
|
||||||
if (type == kPrp) |
|
||||||
{ |
|
||||||
// Checks for existence before attempting to remove
|
|
||||||
resMgr->RemoveSinglePage(mfsFile->GetName()); |
|
||||||
if (!resMgr->FindSinglePage(mfsFile->GetName())) |
|
||||||
{ |
|
||||||
resMgr->AddSinglePage(mfsFile->GetName()); |
|
||||||
} |
|
||||||
} |
|
||||||
else if (type == kOther) |
|
||||||
{ |
|
||||||
if (!IDecompressSound(mfsFile, false)) |
|
||||||
{ |
|
||||||
char text[MAX_PATH]; |
|
||||||
StrPrintf(text, arrsize(text), "%s could not be decompressed", mfsFile->GetName()); |
|
||||||
BackgroundDownloaderLog(kInfo, text ); |
|
||||||
hsAssert(false, text); |
|
||||||
result = false; |
|
||||||
} |
|
||||||
} |
|
||||||
else |
|
||||||
{ |
|
||||||
char text[MAX_PATH]; |
|
||||||
StrPrintf(text, arrsize(text), "Failed downloading file: %s", mfsFile->GetName()); |
|
||||||
BackgroundDownloaderLog(kInfo, text ); |
|
||||||
hsAssert(false, text); |
|
||||||
result = false; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
return result; |
|
||||||
} |
|
||||||
|
|
||||||
void plBackgroundDownloader::CleanUp() |
|
||||||
{ |
|
||||||
BackgroundDownloaderLog(kMajorStatus, "Cleaning up background downloader..." ); |
|
||||||
|
|
||||||
for (MfsFileVec::iterator i = fMfsVec.begin(); i != fMfsVec.end(); ++i) |
|
||||||
{ |
|
||||||
plManifestFile* file = (*i); |
|
||||||
delete file; |
|
||||||
} |
|
||||||
fMfsVec.clear(); |
|
||||||
} |
|
||||||
|
|
||||||
void plBackgroundDownloader::Pause() |
|
||||||
{ |
|
||||||
if (fBGDownloaderRun != NULL && fBGDownloaderIsPaused != NULL) |
|
||||||
{ |
|
||||||
ResetEvent(fBGDownloaderRun); |
|
||||||
WaitForSingleObject(fBGDownloaderIsPaused, INFINITE); |
|
||||||
|
|
||||||
BackgroundDownloaderLog(kStatus, "--- Background download paused ---"); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void plBackgroundDownloader::UnPause() |
|
||||||
{ |
|
||||||
if (fBGDownloaderRun != NULL && fBGDownloaderIsPaused != NULL) |
|
||||||
{ |
|
||||||
SetEvent(fBGDownloaderRun); |
|
||||||
|
|
||||||
BackgroundDownloaderLog(kStatus, "--- Background download resumed ---"); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
plBackgroundDownloader::FileType plBackgroundDownloader::IGetFile(const plManifestFile* mfsFile) |
|
||||||
{ |
|
||||||
BackgroundDownloaderLog(kInfo, " Setting up to download file %s", mfsFile->GetName()); |
|
||||||
|
|
||||||
bool downloadDone = false; |
|
||||||
wchar* wServerPath = hsStringToWString(mfsFile->GetServerPath()); |
|
||||||
int numTries = 0; |
|
||||||
|
|
||||||
while (!downloadDone) |
|
||||||
{ |
|
||||||
if (WaitForSingleObject(fBGDownloaderRun, 0) == WAIT_TIMEOUT) |
|
||||||
SignalObjectAndWait(fBGDownloaderIsPaused, fBGDownloaderRun, INFINITE, FALSE); |
|
||||||
|
|
||||||
if (numTries >= kMaxDownloadTries) |
|
||||||
{ |
|
||||||
BackgroundDownloaderLog(kInfo, " Max download tries exceeded (%d). Aborting download...", kMaxDownloadTries); |
|
||||||
return kFail; |
|
||||||
} |
|
||||||
|
|
||||||
plBGDownloadStream* downloadStream = TRACKED_NEW plBGDownloadStream(); |
|
||||||
if (!downloadStream->Open(mfsFile->GetName(), "wb")) |
|
||||||
{ |
|
||||||
BackgroundDownloaderLog(kInfo, " Unable to create file. Aborting download..."); |
|
||||||
return kFail; |
|
||||||
} |
|
||||||
|
|
||||||
BackgroundDownloaderLog(kInfo, " Downloading file %s...", mfsFile->GetName()); |
|
||||||
|
|
||||||
fSuccess = false;
|
|
||||||
fDoneWithFile = false; |
|
||||||
NetCliFileDownloadRequest( |
|
||||||
wServerPath, |
|
||||||
downloadStream, |
|
||||||
DownloadFileCallback, |
|
||||||
this |
|
||||||
); |
|
||||||
|
|
||||||
while (!fDoneWithFile) { |
|
||||||
AsyncSleep(100); |
|
||||||
} |
|
||||||
|
|
||||||
if (!fSuccess) { |
|
||||||
// remove partial file and die (server didn't have the file or server is shutting down)
|
|
||||||
plFileUtils::RemoveFile(mfsFile->GetName(), true); |
|
||||||
BackgroundDownloaderLog(kError, " File %s failed to download.", mfsFile->GetName()); |
|
||||||
} |
|
||||||
else { |
|
||||||
AsyncSleep(100); |
|
||||||
if (downloadStream->DecompressedOk()) { |
|
||||||
BackgroundDownloaderLog(kInfo, " Decompress successful." ); |
|
||||||
// download and decompress successful, do a md5 check on the resulting file
|
|
||||||
plMD5Checksum localMD5(mfsFile->GetName()); |
|
||||||
if (localMD5 != mfsFile->GetChecksum()) { |
|
||||||
plFileUtils::RemoveFile(mfsFile->GetName(), true); |
|
||||||
BackgroundDownloaderLog(kError, " File %s MD5 check FAILED.", mfsFile->GetName()); |
|
||||||
// don't set downloadDone so we attempt to re-download from the server
|
|
||||||
} |
|
||||||
else { |
|
||||||
BackgroundDownloaderLog(kInfo, " MD5 check succeeded."); |
|
||||||
downloadDone = true; |
|
||||||
} |
|
||||||
} |
|
||||||
else { |
|
||||||
plFileUtils::RemoveFile(mfsFile->GetName(), true); |
|
||||||
BackgroundDownloaderLog(kError, " File %s failed to decompress.", mfsFile->GetName()); |
|
||||||
// don't set downloadDone so we attempt to re-download from the server
|
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
delete downloadStream; |
|
||||||
|
|
||||||
++numTries; |
|
||||||
} |
|
||||||
delete [] wServerPath; |
|
||||||
|
|
||||||
if (!fSuccess)
|
|
||||||
return kFail; |
|
||||||
|
|
||||||
if (stricmp(plFileUtils::GetFileExt(mfsFile->GetName()), "prp") == 0) |
|
||||||
return kPrp; |
|
||||||
|
|
||||||
return kOther; |
|
||||||
} |
|
||||||
|
|
||||||
bool plBackgroundDownloader::IGetDataManifest() |
|
||||||
{ |
|
||||||
if (fMfsVec.size() > 0) |
|
||||||
return true; |
|
||||||
|
|
||||||
BackgroundDownloaderLog(kMajorStatus, "Downloading new manifest from data server..." ); |
|
||||||
|
|
||||||
fSuccess = false; |
|
||||||
unsigned numTries = 0; |
|
||||||
while (!fSuccess) |
|
||||||
{ |
|
||||||
numTries++; |
|
||||||
fDoneWithFile = false; |
|
||||||
NetCliFileManifestRequest(ManifestCallback, this, s_manifest); |
|
||||||
while (!fDoneWithFile) |
|
||||||
{ |
|
||||||
NetClientUpdate(); |
|
||||||
plgDispatch::Dispatch()->MsgQueueProcess(); |
|
||||||
AsyncSleep(10); |
|
||||||
} |
|
||||||
|
|
||||||
if (!fSuccess) |
|
||||||
{ |
|
||||||
fMfsVec.clear(); // clear out any bad data
|
|
||||||
if (numTries > kMaxDownloadTries) |
|
||||||
break; // abort
|
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
if (fSuccess) |
|
||||||
BackgroundDownloaderLog(kStatus, "New manifest read; number of files: %d", fMfsVec.size() ); |
|
||||||
else |
|
||||||
BackgroundDownloaderLog(kStatus, "Failed to download manifest after trying %d times", kMaxDownloadTries); |
|
||||||
|
|
||||||
return fSuccess; |
|
||||||
} |
|
||||||
|
|
||||||
void plBackgroundDownloader::DoneWithFile(bool success) |
|
||||||
{ |
|
||||||
fDoneWithFile = true; |
|
||||||
fSuccess = success; |
|
||||||
} |
|
||||||
|
|
||||||
void plBackgroundDownloader::DoneWithManifest(bool success, const NetCliFileManifestEntry manifestEntires[], unsigned entryCount) |
|
||||||
{ |
|
||||||
BackgroundDownloaderLog(kStatus, "New age manifest received. Reading..."); |
|
||||||
|
|
||||||
if (success) |
|
||||||
{ |
|
||||||
for (unsigned i = 0; i < entryCount; i++) |
|
||||||
{ |
|
||||||
char* name = hsWStringToString(manifestEntires[i].clientName); |
|
||||||
char* serverPath = hsWStringToString(manifestEntires[i].downloadName); |
|
||||||
char* md5Str = hsWStringToString(manifestEntires[i].md5); |
|
||||||
int size = manifestEntires[i].fileSize; |
|
||||||
int zipsize = manifestEntires[i].zipSize; |
|
||||||
int flags = manifestEntires[i].flags; |
|
||||||
if (stricmp(plFileUtils::GetFileExt(name), "gz")) |
|
||||||
flags |= plManifestFile::kFlagZipped; // add zipped flag if necessary
|
|
||||||
|
|
||||||
plMD5Checksum sum; |
|
||||||
sum.SetFromHexString(md5Str); |
|
||||||
fMfsVec.push_back(TRACKED_NEW plManifestFile(name, serverPath, sum, size, zipsize, flags, false)); |
|
||||||
|
|
||||||
delete [] name; |
|
||||||
delete [] serverPath; |
|
||||||
delete [] md5Str; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fDoneWithFile = true; |
|
||||||
fSuccess = success; |
|
||||||
} |
|
@ -1,98 +0,0 @@ |
|||||||
/*==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/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7 |
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or |
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, |
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent |
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK |
|
||||||
(or a modified version of those libraries), |
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, |
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG |
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the |
|
||||||
licensors of this Program grant you additional |
|
||||||
permission to convey the resulting work. Corresponding Source for a |
|
||||||
non-source form of such a combination shall include the source code for |
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered |
|
||||||
work. |
|
||||||
|
|
||||||
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==*/ |
|
||||||
#ifndef plBackgroundDownloader_h_inc |
|
||||||
#define plBackgroundDownloader_h_inc |
|
||||||
|
|
||||||
#include <vector> |
|
||||||
|
|
||||||
#include "hsTypes.h" |
|
||||||
|
|
||||||
class plManifestFile; |
|
||||||
struct NetCliFileManifestEntry; |
|
||||||
|
|
||||||
class plBackgroundDownloader |
|
||||||
{ |
|
||||||
protected: |
|
||||||
static plBackgroundDownloader* fInstance; |
|
||||||
static void Init(); |
|
||||||
static void Shutdown(); |
|
||||||
static void ThreadMain(void * param); |
|
||||||
|
|
||||||
plBackgroundDownloader(); |
|
||||||
~plBackgroundDownloader(); |
|
||||||
|
|
||||||
HANDLE fBGDownloaderRun; |
|
||||||
HANDLE fBGDownloaderIsPaused; |
|
||||||
|
|
||||||
enum FileType {kFail, kPrp, kOther}; |
|
||||||
|
|
||||||
typedef std::vector<plManifestFile*> MfsFileVec; |
|
||||||
MfsFileVec fMfsVec; |
|
||||||
|
|
||||||
public: |
|
||||||
|
|
||||||
bool fDoneWithFile; |
|
||||||
bool fSuccess; |
|
||||||
|
|
||||||
bool IGetDataManifest(); |
|
||||||
FileType IGetFile(const plManifestFile* mfsFile); |
|
||||||
UInt32 IGetDownloadSize(); |
|
||||||
bool IDecompressSound(plManifestFile* mfsFile, bool noOverwrite = false); |
|
||||||
|
|
||||||
public: |
|
||||||
static plBackgroundDownloader* GetInstance(); |
|
||||||
static void StartThread(); |
|
||||||
|
|
||||||
bool Run(); |
|
||||||
void CleanUp(); |
|
||||||
|
|
||||||
void Pause(); |
|
||||||
void UnPause(); |
|
||||||
|
|
||||||
static bool CheckFreeSpace(UInt32 bytesNeeded); |
|
||||||
|
|
||||||
// called by download callbacks to tell it we are done with the current file
|
|
||||||
void DoneWithFile(bool success); |
|
||||||
void DoneWithManifest(bool success, const NetCliFileManifestEntry manifestEntires[], unsigned entryCount); |
|
||||||
}; |
|
||||||
|
|
||||||
#endif //plBackgroundDownloader_h_inc
|
|
@ -1,48 +0,0 @@ |
|||||||
/*==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/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7 |
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or |
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, |
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent |
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK |
|
||||||
(or a modified version of those libraries), |
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, |
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG |
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the |
|
||||||
licensors of this Program grant you additional |
|
||||||
permission to convey the resulting work. Corresponding Source for a |
|
||||||
non-source form of such a combination shall include the source code for |
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered |
|
||||||
work. |
|
||||||
|
|
||||||
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==*/ |
|
||||||
/*****************************************************************************
|
|
||||||
* |
|
||||||
* $/Plasma20/Sources/Plasma/PubUtilLib/plMessage/plNCAgeJoinerMsg.cpp |
|
||||||
*
|
|
||||||
***/ |
|
||||||
|
|
||||||
#include "plNCAgeJoinerMsg.h" |
|
Loading…
Reference in new issue