Browse Source

Game Repair Mode

This adds a license-stopgap "feature" ... You can now update only the game
data by using the -Repair argument on the launcher. You'll need to specify
a stripped down MOULa server.ini with the GateKeeperSrv keys/host.
Adam Johnson 11 years ago
parent
commit
d855d86475
  1. 34
      Sources/Plasma/Apps/plUruLauncher/plClientLauncher.cpp
  2. 4
      Sources/Plasma/Apps/plUruLauncher/plClientLauncher.h
  3. 17
      Sources/Plasma/FeatureLib/pfPatcher/pfPatcher.cpp
  4. 9
      Sources/Plasma/FeatureLib/pfPatcher/pfPatcher.h

34
Sources/Plasma/Apps/plUruLauncher/plClientLauncher.cpp

@ -161,6 +161,11 @@ plClientLauncher::~plClientLauncher() { }
plString plClientLauncher::GetAppArgs() const
{
// If -Repair was specified, there are no args for the next call...
if (hsCheckBits(fFlags, kRepairGame)) {
return "";
}
plStringStream ss;
ss << "-ServerIni=";
ss << fServerIni.AsString();
@ -190,16 +195,33 @@ void plClientLauncher::IOnPatchComplete(ENetError result, const plString& msg)
s_errorProc(result, msg);
}
bool plClientLauncher::IApproveDownload(const plFileName& file)
{
// So, for a repair, what we want to do is quite simple.
// That is: download everything that is NOT in the root directory.
plFileName path = file.StripFileName();
return !path.AsString().IsEmpty();
}
void plClientLauncher::PatchClient()
{
if (fStatusFunc)
fStatusFunc("Checking for updates...");
if (fStatusFunc) {
if (hsCheckBits(fFlags, kGameDataOnly))
fStatusFunc("Verifying game data...");
else
fStatusFunc("Checking for updates...");
}
hsAssert(fPatcherFactory, "why is the patcher factory nil?");
pfPatcher* patcher = fPatcherFactory();
patcher->OnCompletion(std::bind(&plClientLauncher::IOnPatchComplete, this, std::placeholders::_1, std::placeholders::_2));
patcher->OnSelfPatch([&](const plFileName& file) { fClientExecutable = file; });
// If this is a repair, we need to approve the downloads...
if (hsCheckBits(fFlags, kGameDataOnly))
patcher->OnFileDownloadDesired(std::bind(&plClientLauncher::IApproveDownload, this, std::placeholders::_1));
// Let's get 'er done.
if (hsCheckBits(fFlags, kHaveSelfPatched)) {
if (hsCheckBits(fFlags, kClientImage))
patcher->RequestManifest(plManifest::ClientImageManifest());
@ -336,11 +358,12 @@ void plClientLauncher::ParseArguments()
if (cmdParser.GetBool(arg)) \
fFlags |= flag;
enum { kArgServerIni, kArgNoSelfPatch, kArgImage };
enum { kArgServerIni, kArgNoSelfPatch, kArgImage, kArgRepairGame };
const CmdArgDef cmdLineArgs[] = {
{ kCmdArgFlagged | kCmdTypeString, L"ServerIni", kArgServerIni },
{ kCmdArgFlagged | kCmdTypeBool, L"NoSelfPatch", kArgNoSelfPatch },
{ kCmdArgFlagged | kCmdTypeBool, L"Image", kArgImage },
{ kCmdArgFlagged | kCmdTypeBool, L"Repair", kArgRepairGame },
};
CCmdParser cmdParser(cmdLineArgs, arrsize(cmdLineArgs));
@ -351,6 +374,11 @@ void plClientLauncher::ParseArguments()
fServerIni = plString::FromWchar(cmdParser.GetString(kArgServerIni));
APPLY_FLAG(kArgNoSelfPatch, kHaveSelfPatched);
APPLY_FLAG(kArgImage, kClientImage);
APPLY_FLAG(kArgRepairGame, kRepairGame);
// last chance setup
if (hsCheckBits(fFlags, kRepairGame))
fClientExecutable = plManifest::PatcherExecutable();
#undef APPLY_FLAG
}

4
Sources/Plasma/Apps/plUruLauncher/plClientLauncher.h

@ -62,6 +62,9 @@ private:
{
kHaveSelfPatched = 1<<0,
kClientImage = 1<<1,
kGameDataOnly = (1<<2),
kRepairGame = kHaveSelfPatched | kClientImage | kGameDataOnly,
};
uint32_t fFlags;
@ -77,6 +80,7 @@ private:
plString GetAppArgs() const;
void IOnPatchComplete(ENetError result, const plString& msg);
bool IApproveDownload(const plFileName& file);
public:
plClientLauncher();

17
Sources/Plasma/FeatureLib/pfPatcher/pfPatcher.cpp

@ -104,6 +104,7 @@ struct pfPatcherWorker : public hsThread
pfPatcher::CompletionFunc fOnComplete;
pfPatcher::FileDownloadFunc fFileBeginDownload;
pfPatcher::FileDesiredFunc fFileDownloadDesired;
pfPatcher::FileDownloadFunc fFileDownloaded;
pfPatcher::GameCodeDiscoverFunc fGameCodeDiscovered;
pfPatcher::ProgressTickFunc fProgressTick;
@ -482,7 +483,16 @@ void pfPatcherWorker::ProcessFile()
}
}
// If you got here, they're different.
// It's different... but do we want it?
if (fFileDownloadDesired) {
if (!fFileDownloadDesired(clName)) {
PatcherLogRed("\tDeclined '%S'", entry.clientName);
fQueuedFiles.pop_front();
continue;
}
}
// If you got here, they're different and we want it.
PatcherLogYellow("\tEnqueuing '%S'", entry.clientName);
plFileSystem::CreateDir(plFileName(clName).StripFileName());
@ -564,6 +574,11 @@ void pfPatcher::OnFileDownloadBegin(FileDownloadFunc cb)
fWorker->fFileBeginDownload = cb;
}
void pfPatcher::OnFileDownloadDesired(FileDesiredFunc cb)
{
fWorker->fFileDownloadDesired = cb;
}
void pfPatcher::OnFileDownloaded(FileDownloadFunc cb)
{
fWorker->fFileDownloaded = cb;

9
Sources/Plasma/FeatureLib/pfPatcher/pfPatcher.h

@ -70,6 +70,9 @@ 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&) and approves it. */
typedef std::function<bool(const plFileName&)> FileDesiredFunc;
/** Represents a function that takes (const plFileName&) on an interesting file operation. */
typedef std::function<void(const plFileName&)> FileDownloadFunc;
@ -95,6 +98,12 @@ public:
*/
void OnFileDownloadBegin(FileDownloadFunc cb);
/** Set a callback that will be fired when the patcher wants to download a file. You are
* given the ability to approve or veto the download. With great power comes great responsibility...
* \remarks This will be called from the patcher thread.
*/
void OnFileDownloadDesired(FileDesiredFunc 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.
*/

Loading…
Cancel
Save