mirror of
https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git
synced 2025-07-14 02:27:40 -04:00
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.
This commit is contained in:
@ -161,6 +161,11 @@ plClientLauncher::~plClientLauncher() { }
|
|||||||
|
|
||||||
plString plClientLauncher::GetAppArgs() const
|
plString plClientLauncher::GetAppArgs() const
|
||||||
{
|
{
|
||||||
|
// If -Repair was specified, there are no args for the next call...
|
||||||
|
if (hsCheckBits(fFlags, kRepairGame)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
plStringStream ss;
|
plStringStream ss;
|
||||||
ss << "-ServerIni=";
|
ss << "-ServerIni=";
|
||||||
ss << fServerIni.AsString();
|
ss << fServerIni.AsString();
|
||||||
@ -190,16 +195,33 @@ void plClientLauncher::IOnPatchComplete(ENetError result, const plString& msg)
|
|||||||
s_errorProc(result, 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()
|
void plClientLauncher::PatchClient()
|
||||||
{
|
{
|
||||||
if (fStatusFunc)
|
if (fStatusFunc) {
|
||||||
fStatusFunc("Checking for updates...");
|
if (hsCheckBits(fFlags, kGameDataOnly))
|
||||||
|
fStatusFunc("Verifying game data...");
|
||||||
|
else
|
||||||
|
fStatusFunc("Checking for updates...");
|
||||||
|
}
|
||||||
hsAssert(fPatcherFactory, "why is the patcher factory nil?");
|
hsAssert(fPatcherFactory, "why is the patcher factory nil?");
|
||||||
|
|
||||||
pfPatcher* patcher = fPatcherFactory();
|
pfPatcher* patcher = fPatcherFactory();
|
||||||
patcher->OnCompletion(std::bind(&plClientLauncher::IOnPatchComplete, this, std::placeholders::_1, std::placeholders::_2));
|
patcher->OnCompletion(std::bind(&plClientLauncher::IOnPatchComplete, this, std::placeholders::_1, std::placeholders::_2));
|
||||||
patcher->OnSelfPatch([&](const plFileName& file) { fClientExecutable = file; });
|
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, kHaveSelfPatched)) {
|
||||||
if (hsCheckBits(fFlags, kClientImage))
|
if (hsCheckBits(fFlags, kClientImage))
|
||||||
patcher->RequestManifest(plManifest::ClientImageManifest());
|
patcher->RequestManifest(plManifest::ClientImageManifest());
|
||||||
@ -336,11 +358,12 @@ void plClientLauncher::ParseArguments()
|
|||||||
if (cmdParser.GetBool(arg)) \
|
if (cmdParser.GetBool(arg)) \
|
||||||
fFlags |= flag;
|
fFlags |= flag;
|
||||||
|
|
||||||
enum { kArgServerIni, kArgNoSelfPatch, kArgImage };
|
enum { kArgServerIni, kArgNoSelfPatch, kArgImage, kArgRepairGame };
|
||||||
const CmdArgDef cmdLineArgs[] = {
|
const CmdArgDef cmdLineArgs[] = {
|
||||||
{ kCmdArgFlagged | kCmdTypeString, L"ServerIni", kArgServerIni },
|
{ kCmdArgFlagged | kCmdTypeString, L"ServerIni", kArgServerIni },
|
||||||
{ kCmdArgFlagged | kCmdTypeBool, L"NoSelfPatch", kArgNoSelfPatch },
|
{ kCmdArgFlagged | kCmdTypeBool, L"NoSelfPatch", kArgNoSelfPatch },
|
||||||
{ kCmdArgFlagged | kCmdTypeBool, L"Image", kArgImage },
|
{ kCmdArgFlagged | kCmdTypeBool, L"Image", kArgImage },
|
||||||
|
{ kCmdArgFlagged | kCmdTypeBool, L"Repair", kArgRepairGame },
|
||||||
};
|
};
|
||||||
|
|
||||||
CCmdParser cmdParser(cmdLineArgs, arrsize(cmdLineArgs));
|
CCmdParser cmdParser(cmdLineArgs, arrsize(cmdLineArgs));
|
||||||
@ -351,6 +374,11 @@ void plClientLauncher::ParseArguments()
|
|||||||
fServerIni = plString::FromWchar(cmdParser.GetString(kArgServerIni));
|
fServerIni = plString::FromWchar(cmdParser.GetString(kArgServerIni));
|
||||||
APPLY_FLAG(kArgNoSelfPatch, kHaveSelfPatched);
|
APPLY_FLAG(kArgNoSelfPatch, kHaveSelfPatched);
|
||||||
APPLY_FLAG(kArgImage, kClientImage);
|
APPLY_FLAG(kArgImage, kClientImage);
|
||||||
|
APPLY_FLAG(kArgRepairGame, kRepairGame);
|
||||||
|
|
||||||
|
// last chance setup
|
||||||
|
if (hsCheckBits(fFlags, kRepairGame))
|
||||||
|
fClientExecutable = plManifest::PatcherExecutable();
|
||||||
|
|
||||||
#undef APPLY_FLAG
|
#undef APPLY_FLAG
|
||||||
}
|
}
|
||||||
|
@ -62,6 +62,9 @@ private:
|
|||||||
{
|
{
|
||||||
kHaveSelfPatched = 1<<0,
|
kHaveSelfPatched = 1<<0,
|
||||||
kClientImage = 1<<1,
|
kClientImage = 1<<1,
|
||||||
|
kGameDataOnly = (1<<2),
|
||||||
|
|
||||||
|
kRepairGame = kHaveSelfPatched | kClientImage | kGameDataOnly,
|
||||||
};
|
};
|
||||||
|
|
||||||
uint32_t fFlags;
|
uint32_t fFlags;
|
||||||
@ -77,6 +80,7 @@ private:
|
|||||||
plString GetAppArgs() const;
|
plString GetAppArgs() const;
|
||||||
|
|
||||||
void IOnPatchComplete(ENetError result, const plString& msg);
|
void IOnPatchComplete(ENetError result, const plString& msg);
|
||||||
|
bool IApproveDownload(const plFileName& file);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
plClientLauncher();
|
plClientLauncher();
|
||||||
|
@ -104,6 +104,7 @@ struct pfPatcherWorker : public hsThread
|
|||||||
|
|
||||||
pfPatcher::CompletionFunc fOnComplete;
|
pfPatcher::CompletionFunc fOnComplete;
|
||||||
pfPatcher::FileDownloadFunc fFileBeginDownload;
|
pfPatcher::FileDownloadFunc fFileBeginDownload;
|
||||||
|
pfPatcher::FileDesiredFunc fFileDownloadDesired;
|
||||||
pfPatcher::FileDownloadFunc fFileDownloaded;
|
pfPatcher::FileDownloadFunc fFileDownloaded;
|
||||||
pfPatcher::GameCodeDiscoverFunc fGameCodeDiscovered;
|
pfPatcher::GameCodeDiscoverFunc fGameCodeDiscovered;
|
||||||
pfPatcher::ProgressTickFunc fProgressTick;
|
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);
|
PatcherLogYellow("\tEnqueuing '%S'", entry.clientName);
|
||||||
plFileSystem::CreateDir(plFileName(clName).StripFileName());
|
plFileSystem::CreateDir(plFileName(clName).StripFileName());
|
||||||
|
|
||||||
@ -564,6 +574,11 @@ void pfPatcher::OnFileDownloadBegin(FileDownloadFunc cb)
|
|||||||
fWorker->fFileBeginDownload = cb;
|
fWorker->fFileBeginDownload = cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pfPatcher::OnFileDownloadDesired(FileDesiredFunc cb)
|
||||||
|
{
|
||||||
|
fWorker->fFileDownloadDesired = cb;
|
||||||
|
}
|
||||||
|
|
||||||
void pfPatcher::OnFileDownloaded(FileDownloadFunc cb)
|
void pfPatcher::OnFileDownloaded(FileDownloadFunc cb)
|
||||||
{
|
{
|
||||||
fWorker->fFileDownloaded = cb;
|
fWorker->fFileDownloaded = cb;
|
||||||
|
@ -70,6 +70,9 @@ public:
|
|||||||
/** Represents a function that takes the status and an optional message on completion. */
|
/** Represents a function that takes the status and an optional message on completion. */
|
||||||
typedef std::function<void(ENetError, const plString&)> CompletionFunc;
|
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. */
|
/** Represents a function that takes (const plFileName&) on an interesting file operation. */
|
||||||
typedef std::function<void(const plFileName&)> FileDownloadFunc;
|
typedef std::function<void(const plFileName&)> FileDownloadFunc;
|
||||||
|
|
||||||
@ -95,6 +98,12 @@ public:
|
|||||||
*/
|
*/
|
||||||
void OnFileDownloadBegin(FileDownloadFunc cb);
|
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.
|
/** 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.
|
* \remarks This will be called from the network thread.
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user