Browse Source

Implement pfPatcher backend

Adam Johnson 11 years ago
parent
commit
346b6f8ac8
  1. 1
      Sources/Plasma/CoreLib/hsThread.h
  2. 1
      Sources/Plasma/CoreLib/hsThread_Unix.cpp
  3. 1
      Sources/Plasma/CoreLib/hsThread_Win.cpp
  4. 24
      Sources/Plasma/CoreLib/plFileSystem.cpp
  5. 3
      Sources/Plasma/CoreLib/plFileSystem.h
  6. 1
      Sources/Plasma/FeatureLib/CMakeLists.txt
  7. 19
      Sources/Plasma/FeatureLib/pfPatcher/CMakeLists.txt
  8. 450
      Sources/Plasma/FeatureLib/pfPatcher/pfPatcher.cpp
  9. 112
      Sources/Plasma/FeatureLib/pfPatcher/pfPatcher.h
  10. 90
      Sources/Plasma/FeatureLib/pfPatcher/plManifests.cpp
  11. 73
      Sources/Plasma/FeatureLib/pfPatcher/plManifests.h

1
Sources/Plasma/CoreLib/hsThread.h

@ -96,6 +96,7 @@ public:
virtual hsError Run() = 0; // override this to do your work
virtual void Start(); // initializes stuff and calls your Run() method
virtual void Stop(); // sets fQuit = true and the waits for the thread to stop
virtual void OnQuit() { }
// Static functions
static void* Alloc(size_t size); // does not call operator::new(), may return nil

1
Sources/Plasma/CoreLib/hsThread_Unix.cpp

@ -76,6 +76,7 @@ extern "C" {
pthread_mutex_lock(((hsThread*)param)->GetStartupMutex());
void* ret = (void*)(uintptr_t)((hsThread*)param)->Run();
pthread_mutex_unlock(((hsThread*)param)->GetStartupMutex());
((hsThread*)param)->OnQuit();
pthread_exit(ret);
return ret;
}

1
Sources/Plasma/CoreLib/hsThread_Win.cpp

@ -68,6 +68,7 @@ static unsigned int __stdcall gEntryPointBT(void* param)
WinThreadParam* wtp = (WinThreadParam*)param;
unsigned int result = wtp->fThread->Run();
::ReleaseSemaphore(wtp->fQuitSemaH, 1, nil); // signal that we've quit
wtp->fThread->OnQuit();
delete param;
return result;
}

24
Sources/Plasma/CoreLib/plFileSystem.cpp

@ -570,3 +570,27 @@ plFileName plFileSystem::GetTempFilename(const char *prefix, const plFileName &p
return result;
#endif
}
plString plFileSystem::ConvertFileSize(uint64_t size)
{
const char* labels[] = { "KiB", "MiB", "GiB", "TiB", "PiB", "EiB" };
if (size < 1024)
return plString::Format("%i B");
uint64_t last_div = size;
for (size_t i = 0; i < arrsize(labels); ++i) {
uint64_t my_div = last_div / 1024;
if (my_div < 1024) {
float decimal = static_cast<float>(last_div) / 1024.f;
// Kilobytes are so small that we only care about whole numbers
if (i < 1)
return plString::Format("%.0f %s", decimal, labels[i]);
else
return plString::Format("%.2f %s", decimal, labels[i]);
}
last_div = my_div;
}
// this should never happen
return plString::Format("%i %s", last_div, labels[arrsize(labels) - 1]);
}

3
Sources/Plasma/CoreLib/plFileSystem.h

@ -338,6 +338,9 @@ namespace plFileSystem
* system temp path is used.
*/
plFileName GetTempFilename(const char *prefix = "tmp", const plFileName &path = "");
/** Convert a file size from bytes to a human readable size. */
plString ConvertFileSize(uint64_t size);
}
#endif // plFileSystem_Defined

1
Sources/Plasma/FeatureLib/CMakeLists.txt

@ -17,6 +17,7 @@ add_subdirectory(pfJournalBook)
# add_subdirectory(pfKI)
add_subdirectory(pfLocalizationMgr)
add_subdirectory(pfMessage)
add_subdirectory(pfPatcher)
add_subdirectory(pfPython)
add_subdirectory(pfSecurePreloader)
add_subdirectory(pfSurface)

19
Sources/Plasma/FeatureLib/pfPatcher/CMakeLists.txt

@ -0,0 +1,19 @@
include_directories("../../CoreLib")
include_directories("../../NucleusLib")
include_directories("../../NucleusLib/inc")
include_directories("../../PubUtilLib")
set(pfPatcher_SOURCES
plManifests.cpp
pfPatcher.cpp
)
set(pfPatcher_HEADERS
plManifests.h
pfPatcher.h
)
add_library(pfPatcher STATIC ${pfPatcher_SOURCES} ${pfPatcher_HEADERS})
source_group("Source Files" FILES ${pfPatcher_SOURCES})
source_group("Header Files" FILES ${pfPatcher_HEADERS})

450
Sources/Plasma/FeatureLib/pfPatcher/pfPatcher.cpp

@ -0,0 +1,450 @@
/*==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 <algorithm>
#include <deque>
#include "pfPatcher.h"
#include "HeadSpin.h"
#include "plCompression/plZlibStream.h"
#include "pnEncryption/plChecksum.h"
#include "plFileSystem.h"
#include "pnNetBase/pnNbError.h"
#include "plNetGameLib/plNetGameLib.h"
#include "plStatusLog/plStatusLog.h"
#include "hsStream.h"
#include "hsThread.h"
#include "hsTimer.h"
// Some log helper defines
#define PatcherLogGreen(...) pfPatcher::GetLog()->AddLineF(plStatusLog::kGreen, __VA_ARGS__)
#define PatcherLogRed(...) pfPatcher::GetLog()->AddLineF(plStatusLog::kRed, __VA_ARGS__)
#define PatcherLogWhite(...) pfPatcher::GetLog()->AddLineF(plStatusLog::kWhite, __VA_ARGS__)
#define PatcherLogYellow(...) pfPatcher::GetLog()->AddLineF(plStatusLog::kYellow, __VA_ARGS__)
/** Patcher grunt work thread */
struct pfPatcherWorker : public hsThread
{
/** Represents a File/Auth download request */
struct Request
{
enum { kFile, kManifest };
plString fName;
uint8_t fType;
class pfPatcherStream* fStream;
Request(const plString& name, uint8_t type, class pfPatcherStream* s=nullptr) :
fName(name), fType(type), fStream(s)
{ }
};
/** Human readable file flags */
enum FileFlags
{
// Sound files only
kSndFlagCacheSplit = 1<<0,
kSndFlagStreamCompressed = 1<<1,
kSndFlagCacheStereo = 1<<2,
// Any file
kFlagZipped = 1<<3,
};
std::deque<Request> fRequests;
std::deque<NetCliFileManifestEntry> fQueuedFiles;
hsMutex fRequestMut;
hsMutex fFileMut;
hsSemaphore fFileSignal;
pfPatcher::CompletionFunc fOnComplete;
pfPatcher::FileDownloadFunc fFileBeginDownload;
pfPatcher::FileDownloadFunc fFileDownloaded;
pfPatcher::ProgressTickFunc fProgressTick;
pfPatcher* fParent;
volatile bool fStarted;
volatile bool fRequestActive;
uint64_t fCurrBytes;
uint64_t fTotalBytes;
pfPatcherWorker();
~pfPatcherWorker();
void OnQuit();
void EndPatch(ENetError result, const plString& msg=plString::Null);
bool IssueRequest();
virtual hsError Run();
void ProcessFile();
};
// ===================================================
class pfPatcherStream : public plZlibStream
{
pfPatcherWorker* fParent;
plFileName fFilename;
uint32_t fFlags;
uint64_t fBytesWritten;
float fDLStartTime;
plString IMakeStatusMsg() const
{
float secs = hsTimer::GetSysSeconds() - fDLStartTime;
float bytesPerSec = fBytesWritten / secs;
return plFileSystem::ConvertFileSize(bytesPerSec) + "/s";
}
void IUpdateProgress(uint32_t count)
{
fBytesWritten += count; // just this file
fParent->fCurrBytes += count; // the entire everything
// tick-tick-tick, tick-tick-tock
if (fParent->fProgressTick)
fParent->fProgressTick(fParent->fCurrBytes, fParent->fTotalBytes, IMakeStatusMsg());
}
public:
pfPatcherStream(pfPatcherWorker* parent, const plFileName& filename, const NetCliFileManifestEntry& entry)
: fParent(parent), fFlags(entry.flags), fBytesWritten(0)
{
// ugh. eap removed the compressed flag in his fail manifests
if (filename.GetFileExt().CompareI("gz") == 0) {
fFlags |= pfPatcherWorker::kFlagZipped;
parent->fTotalBytes += entry.zipSize;
} else
parent->fTotalBytes += entry.fileSize;
}
virtual bool Open(const plFileName& filename, const char* mode)
{
fFilename = filename;
return plZlibStream::Open(filename, mode);
}
virtual uint32_t Write(uint32_t count, const void* buf)
{
// tick whatever progress bar we have
IUpdateProgress(count);
// write the appropriate blargs
if (hsCheckBits(fFlags, pfPatcherWorker::kFlagZipped))
return plZlibStream::Write(count, buf);
else
return fOutput->Write(count, buf);
}
void Begin() { fDLStartTime = hsTimer::GetSysSeconds(); }
plFileName GetFileName() const { return fFilename; }
void Unlink() const { plFileSystem::Unlink(fFilename); }
};
// ===================================================
static void IFileManifestDownloadCB(ENetError result, void* param, const wchar_t group[], const NetCliFileManifestEntry manifest[], unsigned entryCount)
{
pfPatcherWorker* patcher = static_cast<pfPatcherWorker*>(param);
if (IS_NET_SUCCESS(result)) {
PatcherLogGreen("\tDownloaded Manifest '%S'", group);
{
hsTempMutexLock lock(patcher->fFileMut);
for (unsigned i = 0; i < entryCount; ++i)
patcher->fQueuedFiles.push_back(manifest[i]);
patcher->fFileSignal.Signal();
}
patcher->IssueRequest();
} else {
PatcherLogRed("\tDownload Failed: Manifest '%S'", group);
patcher->EndPatch(result, plString::FromWchar(group));
}
}
static void IFileThingDownloadCB(ENetError result, void* param, const plFileName& filename, hsStream* writer)
{
pfPatcherWorker* patcher = static_cast<pfPatcherWorker*>(param);
pfPatcherStream* stream = static_cast<pfPatcherStream*>(writer);
stream->Close();
if (IS_NET_SUCCESS(result)) {
PatcherLogGreen("\tDownloaded File '%s'", stream->GetFileName().AsString().c_str());
if (patcher->fFileDownloaded)
patcher->fFileDownloaded(stream->GetFileName());
patcher->IssueRequest();
} else {
PatcherLogRed("\tDownloaded Failed: File '%s'", stream->GetFileName().AsString().c_str());
stream->Unlink();
patcher->EndPatch(result, filename.AsString());
}
delete stream;
}
// ===================================================
pfPatcherWorker::pfPatcherWorker() :
fStarted(false), fCurrBytes(0), fTotalBytes(0), fRequestActive(true)
{ }
pfPatcherWorker::~pfPatcherWorker()
{
{
hsTempMutexLock lock(fRequestMut);
std::for_each(fRequests.begin(), fRequests.end(),
[] (const Request& req) {
if (req.fStream) req.fStream->Close();
delete req.fStream;
}
);
fRequests.clear();
}
{
hsTempMutexLock lock(fFileMut);
fQueuedFiles.clear();
}
}
void pfPatcherWorker::OnQuit()
{
// the thread's Run() has exited sanely... now we can commit hara-kiri
delete fParent;
}
void pfPatcherWorker::EndPatch(ENetError result, const plString& msg)
{
// Guard against multiple calls
if (fStarted) {
// Send end status
if (fOnComplete)
fOnComplete(result, msg);
// yay log hax
if (IS_NET_SUCCESS(result))
PatcherLogWhite("--- Patch Complete ---");
else {
PatcherLogRed("\tNetwork Error: %S", NetErrorToString(result));
PatcherLogWhite("--- Patch Killed by Error ---");
}
}
fStarted = false;
fFileSignal.Signal();
}
bool pfPatcherWorker::IssueRequest()
{
hsTempMutexLock lock(fRequestMut);
if (fRequests.empty()) {
fRequestActive = false;
fFileSignal.Signal(); // make sure the patch thread doesn't deadlock!
return false;
} else
fRequestActive = true;
const Request& req = fRequests.front();
switch (req.fType) {
case Request::kFile:
req.fStream->Begin();
if (fFileBeginDownload)
fFileBeginDownload(req.fStream->GetFileName());
NetCliFileDownloadRequest(req.fName, req.fStream, IFileThingDownloadCB, this);
break;
case Request::kManifest:
NetCliFileManifestRequest(IFileManifestDownloadCB, this, req.fName.ToWchar());
break;
DEFAULT_FATAL(req.fType);
}
fRequests.pop_front();
return true;
}
hsError pfPatcherWorker::Run()
{
// So here's the rub:
// We have one or many manifests in the fRequests deque. We begin issuing those requests one-by one, starting here.
// As we receive the answer, the NetCli thread populates fQueuedFiles and pings the fFileSignal semaphore, then issues the next request...
// In this non-UI/non-Net thread, we do the stutter-prone/time-consuming IO/hashing operations. (Typically, the UI thread == Net thread)
// As we find files that need updating, we add them to fRequests.
// If there is no net request from ME when we find a file, we issue the request
// Once a file is downloaded, the next request is issued.
// When there are no files in my deque and no requests in my deque, we exit without errors.
PatcherLogWhite("--- Patch Started (%i requests) ---", fRequests.size());
fStarted = true;
IssueRequest();
// Now, work until we're done processing files
do {
fFileSignal.Wait();
hsTempMutexLock fileLock(fFileMut);
if (!fQueuedFiles.empty()) {
ProcessFile();
continue;
}
// This makes sure both queues are empty before exiting.
if (!fRequestActive)
if(!IssueRequest())
break;
} while (fStarted);
EndPatch(kNetSuccess);
return hsOK;
}
void pfPatcherWorker::ProcessFile()
{
do {
const NetCliFileManifestEntry& entry = fQueuedFiles.front();
// eap sucks
plString clName = plString::FromWchar(entry.clientName);
plString dlName = plString::FromWchar(entry.downloadName);
// Check to see if ours matches
plFileInfo mine(clName);
if (mine.FileSize() == entry.fileSize) {
plMD5Checksum cliMD5(clName);
plMD5Checksum srvMD5;
srvMD5.SetFromHexString(plString::FromWchar(entry.md5, 32).c_str());
if (cliMD5 == srvMD5) {
fQueuedFiles.pop_front();
continue;
}
}
// If you got here, they're different.
PatcherLogYellow("\tEnqueuing '%S'", entry.clientName);
plFileSystem::CreateDir(plFileName(clName).StripFileName());
pfPatcherStream* s = new pfPatcherStream(this, dlName, entry);
s->Open(clName, "wb");
hsTempMutexLock lock(fRequestMut);
fRequests.push_back(Request(dlName, Request::kFile, s));
fQueuedFiles.pop_front();
if (!fRequestActive)
IssueRequest();
} while (!fQueuedFiles.empty());
}
// ===================================================
plStatusLog* pfPatcher::GetLog()
{
static plStatusLog* log = nullptr;
if (!log)
{
log = plStatusLogMgr::GetInstance().CreateStatusLog(
20,
"patcher.log",
plStatusLog::kFilledBackground | plStatusLog::kAlignToTop | plStatusLog::kDeleteForMe);
}
return log;
}
pfPatcher::pfPatcher() : fWorker(new pfPatcherWorker) { }
pfPatcher::~pfPatcher() { }
// ===================================================
void pfPatcher::OnCompletion(CompletionFunc cb)
{
fWorker->fOnComplete = cb;
}
void pfPatcher::OnFileDownloadBegin(FileDownloadFunc cb)
{
fWorker->fFileBeginDownload = cb;
}
void pfPatcher::OnFileDownloaded(FileDownloadFunc cb)
{
fWorker->fFileDownloaded = cb;
}
void pfPatcher::OnProgressTick(ProgressTickFunc cb)
{
fWorker->fProgressTick = cb;
}
// ===================================================
void pfPatcher::RequestManifest(const plString& mfs)
{
hsTempMutexLock lock(fWorker->fRequestMut);
fWorker->fRequests.push_back(pfPatcherWorker::Request(mfs, pfPatcherWorker::Request::kManifest));
}
void pfPatcher::RequestManifest(const std::vector<plString>& mfs)
{
hsTempMutexLock lock(fWorker->fRequestMut);
std::for_each(mfs.begin(), mfs.end(),
[&] (const plString& name) {
fWorker->fRequests.push_back(pfPatcherWorker::Request(name, pfPatcherWorker::Request::kManifest));
}
);
}
bool pfPatcher::Start()
{
hsAssert(!fWorker->fStarted, "pfPatcher is one-use only. kthx.");
if (!fWorker->fStarted) {
fWorker->fParent = this; // wheeeee circular
fWorker->Start();
return true;
}
return false;
}

112
Sources/Plasma/FeatureLib/pfPatcher/pfPatcher.h

@ -0,0 +1,112 @@
/*==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 _pfPatcher_inc_
#define _pfPatcher_inc_
#include <functional>
#include <memory>
#include <vector>
#include "plString.h"
#include "pnNetBase/pnNbError.h"
class plFileName;
class plStatusLog;
/** Plasma File Patcher
* This is used to patch the client with one or many manifests at once. It assumes that
* we have permission to modify the game files, so be sure that you do! We memory manage
* ourselves, so allocate a new pfPatcher, add your manifests, and Start!
*/
class pfPatcher
{
std::unique_ptr<struct pfPatcherWorker> fWorker;
public:
static plStatusLog* GetLog();
public:
/** Represents a function that takes the status and an optional message on completion. */
typedef std::function<void(ENetError, const plString&)> CompletionFunc;
/** Represents a function that takes (const plFileName&) on an interesting file operation. */
typedef std::function<void(const plFileName&)> FileDownloadFunc;
/** Represents a function that takes (bytesDLed, totalBytes, statsStr) as a progress indicator. */
typedef std::function<void(uint64_t, uint64_t, const plString&)> ProgressTickFunc;
pfPatcher();
~pfPatcher();
/** Set a callback that will be fired when the patcher finishes its dirty work.
* \remarks This may be called from any thread, so make sure your callback is
* thread safe!
*/
void OnCompletion(CompletionFunc cb);
/** Set a callback that will be fired when the patcher issues a download request to the server.
* \remarks This will be called from the network thread.
*/
void OnFileDownloadBegin(FileDownloadFunc cb);
/** Set a callback that will be fired when the patcher has finished downloading a file from the server.
* \remarks This will be called from the network thread.
*/
void OnFileDownloaded(FileDownloadFunc cb);
/** Set a callback that will be fired when the patcher receives a chunk from the server. The status string
* will contain the current download speed.
* \remarks This will be called from the network thread.
*/
void OnProgressTick(ProgressTickFunc cb);
void RequestManifest(const plString& mfs);
void RequestManifest(const std::vector<plString>& mfs);
/** Start patching the requested manifests. Please note that after calling this, you should
* discard your pointer to this object as it will memory-manage itself.
*/
bool Start();
};
#endif // _pfPatcher_inc_

90
Sources/Plasma/FeatureLib/pfPatcher/plManifests.cpp

@ -0,0 +1,90 @@
/*==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 "plManifests.h"
#include "plFileSystem.h"
// Helper that returns the appropriate string per build
#ifdef PLASMA_EXTERNAL_RELEASE
# define MANIFEST(in, ex) ex
#else
# define MANIFEST(in, ex) in
#endif // PLASMA_EXTERNAL_RELEASE
plFileName plManifest::ClientExecutable()
{
return MANIFEST("plClient.exe", "UruExplorer.exe");
}
plFileName plManifest::PatcherExecutable()
{
return MANIFEST("plUruLauncher.exe", "UruLauncher.exe");
}
plString plManifest::ClientManifest()
{
return MANIFEST("ThinInternal", "ThinExternal");
}
plString plManifest::ClientImageManifest()
{
return MANIFEST("Internal", "External");
}
plString plManifest::PatcherManifest()
{
return MANIFEST("InternalPatcher", "ExternalPatcher");
}
std::vector<plString> plManifest::EssentialGameManifests()
{
std::vector<plString> mfs;
mfs.push_back("CustomAvatars");
mfs.push_back("GlobalAnimations");
mfs.push_back("GlobalAvatars");
mfs.push_back("GlobalClothing");
mfs.push_back("GlobalMarkers");
mfs.push_back("GUI");
return mfs;
}

73
Sources/Plasma/FeatureLib/pfPatcher/plManifests.h

@ -0,0 +1,73 @@
/*==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 _plManifests_inc_
#define _plManifests_inc_
#include <vector>
class plFileName;
class plString;
namespace plManifest
{
/** Get the name of the client executable for this build type.*/
plFileName ClientExecutable();
/** Get the name of the patcher executable for this build type.*/
plFileName PatcherExecutable();
/** Get the name of the baseline client manifest for this build type. */
plString ClientManifest();
/** Get the name of the full game manifest for this build type. */
plString ClientImageManifest();
/** Get the name of the patcher manifest for this build type. */
plString PatcherManifest();
/** Get a vector containing all manifests the game requires to initialize. */
std::vector<plString> EssentialGameManifests();
}
#endif // _plManifests_inc_
Loading…
Cancel
Save