Merge with develop

This commit is contained in:
kervala 2016-02-02 19:31:12 +01:00
parent 4d29b54d0a
commit c85cbfc869
4 changed files with 139 additions and 231 deletions
code
nel/src/misc
ryzom
client/src
tools/client/client_patcher

View file

@ -732,8 +732,7 @@ bool launchProgram(const std::string &programName, const std::string &arguments,
SetEnvironmentVariable( SE_TRANSLATOR_IN_MAIN_MODULE, NULL );
}
string arg = " " + arguments;
BOOL res = CreateProcessA(programName.c_str(), (char*)arg.c_str(), NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE | CREATE_NO_WINDOW, NULL, NULL, &si, &pi);
BOOL res = CreateProcessA(programName.empty() ? NULL:programName.c_str(), (char*)arguments.c_str(), NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE | CREATE_NO_WINDOW, NULL, NULL, &si, &pi);
if (res)
{
@ -754,25 +753,13 @@ bool launchProgram(const std::string &programName, const std::string &arguments,
}
#elif defined(NL_OS_MAC)
std::string command;
// we need to open bundles with "open" command
std::string command = NLMISC::toString("open \"%s\"", programName.c_str());
if (CFile::getExtension(programName) == "app")
// append arguments if any
if (!arguments.empty())
{
// we need to open bundles with "open" command
command = NLMISC::toString("open \"%s\"", programName.c_str());
// append arguments if any
if (!arguments.empty())
{
command += NLMISC::toString(" --args %s", arguments.c_str());
}
}
else
{
command = programName;
// append arguments if any
if (!arguments.empty()) command += " " + arguments;
command += NLMISC::toString(" --args %s", arguments.c_str());
}
int res = system(command.c_str());

View file

@ -47,6 +47,7 @@
#include "nel/misc/sha1.h"
#include "nel/misc/big_file.h"
#include "nel/misc/i18n.h"
#include "nel/misc/cmd_args.h"
#include "game_share/bg_downloader_msg.h"
@ -89,6 +90,8 @@ extern string R2ServerVersion;
std::string TheTmpInstallDirectory = "patch/client_install";
#endif
extern NLMISC::CCmdArgs Args;
// ****************************************************************************
// ****************************************************************************
// ****************************************************************************
@ -120,8 +123,16 @@ CPatchManager::CPatchManager() : State("t_state"), DataScanState("t_data_scan_st
UpdateBatchFilename = "updt_nl.sh";
#endif
// use current directory by default
setClientRootPath("./");
// use application directory by default
std::string rootPath = Args.getProgramPath();
if (!CFile::fileExists(rootPath + "client_default.cfg"))
{
// use current directory
rootPath = CPath::getCurrentPath();
}
setClientRootPath(rootPath);
VerboseLog = true;
@ -716,29 +727,12 @@ void CPatchManager::createBatchFile(CProductDescriptionForClient &descFile, bool
{
uint nblab = 0;
FILE *fp = NULL;
if (useBatchFile)
{
deleteBatchFile();
fp = fopen (UpdateBatchFilename.c_str(), "wt");
if (fp == 0)
{
string err = toString("Can't open file '%s' for writing: code=%d %s (error code 29)", UpdateBatchFilename.c_str(), errno, strerror(errno));
throw Exception (err);
}
//use bat if windows if not use sh
#ifdef NL_OS_WINDOWS
fprintf(fp, "@echo off\n");
#else
fprintf(fp, "#!/bin/sh\n");
#endif
}
std::string content;
// Unpack files with category ExtractPath non empty
const CBNPCategorySet &rDescCats = descFile.getCategories();
OptionalCat.clear();
for (uint32 i = 0; i < rDescCats.categoryCount(); ++i)
{
// For all optional categories check if there is a 'file to patch' in it
@ -758,11 +752,6 @@ void CPatchManager::createBatchFile(CProductDescriptionForClient &descFile, bool
}
catch(...)
{
if (useBatchFile)
{
fclose(fp);
}
throw;
}
@ -771,11 +760,6 @@ void CPatchManager::createBatchFile(CProductDescriptionForClient &descFile, bool
// TODO: handle exception?
string err = toString("Error unpacking %s", rFilename.c_str());
if (useBatchFile)
{
fclose(fp);
}
throw Exception (err);
}
else
@ -787,39 +771,41 @@ void CPatchManager::createBatchFile(CProductDescriptionForClient &descFile, bool
NLMISC::CFile::createDirectoryTree(DstPath);
// this file must be moved
if (useBatchFile)
{
#ifdef NL_OS_WINDOWS
SrcPath = CPath::standardizeDosPath(SrcPath);
DstPath = CPath::standardizeDosPath(DstPath);
#else
SrcPath = CPath::standardizePath(SrcPath);
DstPath = CPath::standardizePath(DstPath);
SrcPath = CPath::standardizeDosPath(SrcPath);
DstPath = CPath::standardizeDosPath(DstPath);
#endif
}
std::string SrcName = SrcPath + vFilenames[fff];
std::string DstName = DstPath + vFilenames[fff];
if (useBatchFile)
bool succeeded = false;
if (!useBatchFile)
{
// don't check result, because it's possible the olk file doesn't exist
CFile::deleteFile(DstName);
// try to move it, if fails move it later in a script
if (CFile::moveFile(DstName, SrcName))
succeeded = true;
}
// if we didn't succeed to delete or move the file, create a batch file anyway
if (!succeeded)
{
// write windows .bat format else write sh format
#ifdef NL_OS_WINDOWS
fprintf(fp, ":loop%u\n", nblab);
fprintf(fp, "attrib -r -a -s -h %s\n", DstName.c_str());
fprintf(fp, "del %s\n", DstName.c_str());
fprintf(fp, "if exist %s goto loop%u\n", DstName.c_str(), nblab);
fprintf(fp, "move %s %s\n", SrcName.c_str(), DstPath.c_str());
content += toString(":loop%u\n", nblab);
content += toString("attrib -r -a -s -h \"%s\"\n", DstName.c_str());
content += toString("del \"%s\"\n", DstName.c_str());
content += toString("if exist \"%s\" goto loop%u\n", DstName.c_str(), nblab);
content += toString("move \"%s\" \"%s\"\n", SrcName.c_str(), DstPath.c_str());
#else
fprintf(fp, "rm -rf %s\n", DstName.c_str());
fprintf(fp, "mv %s %s\n", SrcName.c_str(), DstPath.c_str());
content += toString("rm -rf \"%s\"\n", DstName.c_str());
content += toString("mv %s \"%s\"\n", SrcName.c_str(), DstPath.c_str());
#endif
}
else
{
deleteFile(DstName);
CFile::moveFile(DstName, SrcName);
}
nblab++;
}
@ -827,58 +813,86 @@ void CPatchManager::createBatchFile(CProductDescriptionForClient &descFile, bool
}
}
std::string patchDirectory = CPath::standardizeDosPath(ClientRootPath + "patch");
// Finalize batch file
if (NLMISC::CFile::isExists("patch") && NLMISC::CFile::isDirectory("patch"))
if (NLMISC::CFile::isExists(patchDirectory) && NLMISC::CFile::isDirectory(patchDirectory))
{
#ifdef NL_OS_WINDOWS
if (useBatchFile)
{
fprintf(fp, ":looppatch\n");
}
#endif
std::string patchContent;
vector<string> vFileList;
CPath::getPathContent ("patch", false, false, true, vFileList, NULL, false);
CPath::getPathContent (patchDirectory, false, false, true, vFileList, NULL, false);
for(uint32 i = 0; i < vFileList.size(); ++i)
{
if (useBatchFile)
bool succeeded = false;
if (!useBatchFile)
{
if (CFile::deleteFile(vFileList[i]))
succeeded = true;
}
// if we didn't succeed to delete, create a batch file anyway
if (!succeeded)
{
#ifdef NL_OS_WINDOWS
fprintf(fp, "del %s\n", CPath::standardizeDosPath(vFileList[i]).c_str());
patchContent += toString("del \"%s\"\n", CPath::standardizeDosPath(vFileList[i]).c_str());
#else
fprintf(fp, "rm -f %s\n", CPath::standardizePath(vFileList[i]).c_str());
patchContent += toString("rm -f \"%s\"\n", CPath::standardizePath(vFileList[i]).c_str());
#endif
}
else
{
CFile::deleteFile(vFileList[i]);
}
}
if (useBatchFile)
if (!patchContent.empty())
{
#ifdef NL_OS_WINDOWS
fprintf(fp, "rd /Q /S patch\n");
fprintf(fp, "if exist patch goto looppatch\n");
content += toString(":looppatch\n");
content += patchContent;
content += toString("rd /Q /S \"" + patchDirectory + "\"\n");
content += toString("if exist \"" + patchDirectory + "\" goto looppatch\n");
#else
fprintf(fp, "rm -rf patch\n");
content += toString("rm -rf \"" + patchDirectory + "\"\n");
#endif
}
else
{
CFile::deleteDirectory("patch");
CFile::deleteDirectory(patchDirectory);
}
}
if (useBatchFile)
if (!content.empty())
{
deleteBatchFile();
std::string batchFilename = ClientRootPath + UpdateBatchFilename;
FILE *fp = fopen (batchFilename.c_str(), "wt");
if (fp == NULL)
{
string err = toString("Can't open file '%s' for writing: code=%d %s (error code 29)", batchFilename.c_str(), errno, strerror(errno));
throw Exception (err);
}
//use bat if windows if not use sh
#ifdef NL_OS_WINDOWS
fprintf(fp, "@echo off\n");
#else
fprintf(fp, "#!/bin/sh\n");
#endif
// append content of script
fprintf(fp, content.c_str());
if (wantRyzomRestart)
{
#ifdef NL_OS_WINDOWS
fprintf(fp, "start %s %%1 %%2 %%3\n", RyzomFilename.c_str());
fprintf(fp, "start \"\" \"%s\" %%1 %%2 %%3\n", CPath::standardizeDosPath(RyzomFilename).c_str());
#else
fprintf(fp, "%s $1 $2 $3\n", RyzomFilename.c_str());
fprintf(fp, "\"%s\" $1 $2 $3\n", RyzomFilename.c_str());
#endif
}
@ -887,11 +901,11 @@ void CPatchManager::createBatchFile(CProductDescriptionForClient &descFile, bool
fclose(fp);
if (diskFull)
{
throw NLMISC::EDiskFullError(UpdateBatchFilename.c_str());
throw NLMISC::EDiskFullError(batchFilename.c_str());
}
if (writeError)
{
throw NLMISC::EWriteError(UpdateBatchFilename.c_str());
throw NLMISC::EWriteError(batchFilename.c_str());
}
}
}
@ -903,93 +917,44 @@ void CPatchManager::executeBatchFile()
extern void quitCrashReport ();
quitCrashReport ();
#ifdef NL_OS_WINDOWS
// Launch the batch file
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof(si) );
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE; // SW_SHOW
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
// Start the child process.
string strCmdLine;
bool r2Mode = false;
#ifndef RY_BG_DOWNLOADER
r2Mode = ClientCfg.R2Mode;
#endif
if (r2Mode)
{
strCmdLine = UpdateBatchFilename + " " + LoginLogin + " " + LoginPassword;
}
else
{
strCmdLine = UpdateBatchFilename + " " + LoginLogin + " " + LoginPassword + " " + toString(LoginShardId);
}
if( !CreateProcess( NULL, // No module name (use command line).
(char*)strCmdLine.c_str(), // Command line.
NULL, // Process handle not inheritable.
NULL, // Thread handle not inheritable.
FALSE, // Set handle inheritance to FALSE.
0, // No creation flags.
NULL, // Use parent's environment block.
NULL, // Use parent's starting directory.
&si, // Pointer to STARTUPINFO structure.
&pi ) // Pointer to PROCESS_INFORMATION structure.
)
{
// error occurs during the launch
string str = toString("Can't execute '%s': code=%d %s (error code 30)", UpdateBatchFilename.c_str(), errno, strerror(errno));
throw Exception (str);
}
// Close process and thread handles.
// CloseHandle( pi.hProcess );
// CloseHandle( pi.hThread );
#else
// Start the child process.
bool r2Mode = false;
#ifndef RY_BG_DOWNLOADER
r2Mode = ClientCfg.R2Mode;
#endif
string strCmdLine;
std::string batchFilename;
strCmdLine = "./" + UpdateBatchFilename;
#ifdef NL_OS_WINDOWS
batchFilename = CPath::standardizeDosPath(ClientRootPath);
#else
batchFilename = ClientRootPath;
#endif
chmod(strCmdLine.c_str(), S_IRWXU);
if (r2Mode)
batchFilename += UpdateBatchFilename;
#ifdef NL_OS_UNIX
// make script executable under UNIX
chmod(batchFilename.c_str(), S_IRWXU);
#endif
std::string cmdLine = "\"" + batchFilename + "\" " + LoginLogin + " " + LoginPassword;
if (!r2Mode)
{
if (execl(strCmdLine.c_str(), strCmdLine.c_str(), LoginLogin.c_str(), LoginPassword.c_str(), (char *) NULL) == -1)
{
int errsv = errno;
nlerror("Execl Error: %d %s", errsv, strCmdLine.c_str());
}
else
{
nlinfo("Ran batch file r2Mode Success");
}
cmdLine += " " + toString(LoginShardId);
}
if (launchProgram("", cmdLine, false))
{
exit(0);
}
else
{
if (execl(strCmdLine.c_str(), strCmdLine.c_str(), LoginLogin.c_str(), LoginPassword.c_str(), toString(LoginShardId).c_str(), (char *) NULL) == -1)
{
int errsv = errno;
nlerror("Execl r2mode Error: %d %s", errsv, strCmdLine.c_str());
}
else
{
nlinfo("Ran batch file Success");
}
// error occurs during the launch
string str = toString("Can't execute '%s': code=%d %s (error code 30)", UpdateBatchFilename.c_str(), errno, strerror(errno));
throw Exception (str);
}
#endif
// exit(0);
}
// ****************************************************************************
@ -1156,9 +1121,9 @@ void CPatchManager::readDescFile(sint32 nVersion)
std::string unpackTo = category.getUnpackTo();
if (unpackTo.substr(0, 2) == "./")
if (unpackTo.substr(0, 1) == ".")
{
unpackTo = ClientRootPath + unpackTo.substr(2);
unpackTo = CPath::makePathAbsolute(unpackTo, ClientRootPath, true);
category.setUnpackTo(unpackTo);
}
}
@ -2356,7 +2321,6 @@ void CPatchThread::run()
ucstring sTranslate;
try
{
// First do all ref files
// ----------------------
@ -2429,7 +2393,6 @@ void CPatchThread::run()
pPM->deleteFile(pPM->UpdateBatchFilename, false, false);
}
if (!bErr)
{
sTranslate = CI18N::get("uiPatchEndNoErr");
@ -2439,6 +2402,7 @@ void CPatchThread::run()
// Set a more explicit error message
pPM->setErrorMessage(sTranslate);
}
PatchOk = !bErr;
Ended = true;
}

View file

@ -3,7 +3,6 @@ FILE(GLOB SRC main.cpp
${CMAKE_SOURCE_DIR}/ryzom/client/src/user_agent.cpp
${CMAKE_SOURCE_DIR}/ryzom/client/src/client_cfg.cpp
${CMAKE_SOURCE_DIR}/ryzom/client/src/login_patch.cpp
${CMAKE_SOURCE_DIR}/ryzom/client/src/login_patch_seven_zip.cpp
${CMAKE_SOURCE_DIR}/ryzom/client/src/login_xdelta.cpp
${CMAKE_SOURCE_DIR}/ryzom/client/src/stdpch.cpp
${CMAKE_SOURCE_DIR}/ryzom/client/src/stdpch.h

View file

@ -1,6 +1,10 @@
#include "stdpch.h"
#include "login_patch.h"
#include "client_cfg.h"
#include "user_agent.h"
#include "nel/misc/cmd_args.h"
#include <locale.h>
#ifdef NL_OS_WINDOWS
@ -28,6 +32,8 @@ string VersionName;
string LoginLogin, LoginPassword;
uint32 LoginShardId = 0xFFFFFFFF;
CCmdArgs Args;
bool useUtf8 = false;
bool useEsc = false;
@ -147,6 +153,12 @@ int main(int argc, char *argv[])
// init the Nel context
CApplicationContext appContext;
Args.setVersion(getDisplayVersion());
Args.setDescription("Ryzom client");
Args.addArg("c", "config", "id", "Use this configuration to determine what directory to use by default");
if (!Args.parse(argc, argv)) return 1;
// create logs in temporary directory
createDebug(CPath::getTemporaryDirectory().c_str(), true, true);
@ -209,59 +221,6 @@ int main(int argc, char *argv[])
return 1;
}
// set default paths
std::string dataPath = "./data/";
std::string rootPath = "./";
// use custom data path if specified
if (!ClientCfg.DataPath.empty())
{
dataPath = CPath::standardizePath(ClientCfg.DataPath.front());
string::size_type pos = dataPath.rfind('/', dataPath.length()-2);
if (pos != string::npos)
rootPath = dataPath.substr(0, pos+1);
}
std::string unpackPath = CPath::standardizePath(rootPath + "unpack");
// check if user can write in data directory
if (!CFile::isExists(unpackPath))
{
if (!CFile::createDirectoryTree(unpackPath))
{
printError("You don't have permission to create " + unpackPath);
return 1;
}
}
else
{
if (!CFile::createEmptyFile(unpackPath + "empty"))
{
printError("You don't have write permission in " + unpackPath);
return 1;
}
CFile::deleteFile(unpackPath + "empty");
}
// only use PreDataPath for looking paths
if (!ClientCfg.PreDataPath.empty())
{
for(uint i = 0; i < ClientCfg.PreDataPath.size(); ++i)
{
CPath::addSearchPath(NLMISC::expandEnvironmentVariables(ClientCfg.PreDataPath[i]), true, false);
}
}
// add more search paths if translation is not found
if (!CPath::exists(lang + ".uxt"))
{
CPath::addSearchPath("patcher", true, false);
#ifdef RYZOM_SHARE_PREFIX
CPath::addSearchPath(RYZOM_SHARE_PREFIX"/patcher", true, false);
#endif
}
// load translation
CI18N::load(lang);
@ -270,9 +229,6 @@ int main(int argc, char *argv[])
// initialize patch manager and set the ryzom full path, before it's used
CPatchManager *pPM = CPatchManager::getInstance();
// set the correct root path
pPM->setClientRootPath(rootPath);
// use PatchUrl
vector<string> patchURLs;
pPM->init(patchURLs, ClientCfg.PatchUrl, ClientCfg.PatchVersion);
@ -385,6 +341,8 @@ int main(int argc, char *argv[])
printError(convert(CI18N::get("uiErrPatchApply")) + " " + error);
return 1;
}
pPM->executeBatchFile();
}
/*