merge from compatibility-develop
This commit is contained in:
parent
3cd8969cd7
commit
f5459a1b9b
54 changed files with 2992 additions and 1742 deletions
|
@ -269,10 +269,6 @@ IF(WITH_QT5)
|
||||||
# Gui
|
# Gui
|
||||||
SET(QT_LIBRARIES ${QT_LIBRARIES} Qt5::Gui Qt5::OpenGL)
|
SET(QT_LIBRARIES ${QT_LIBRARIES} Qt5::Gui Qt5::OpenGL)
|
||||||
|
|
||||||
IF(WIN32)
|
|
||||||
SET(QT_LIBRARIES ${QT_LIBRARIES} Qt5::WinExtras)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
ADD_QT_LIBRARY(PrintSupport)
|
ADD_QT_LIBRARY(PrintSupport)
|
||||||
|
|
||||||
IF(WIN32)
|
IF(WIN32)
|
||||||
|
@ -390,10 +386,6 @@ IF(WITH_QT5)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
ELSE()
|
ELSE()
|
||||||
SET(QT_LIBRARIES Qt5::Widgets Qt5::Network Qt5::Xml Qt5::Gui Qt5::OpenGL Qt5::Core)
|
SET(QT_LIBRARIES Qt5::Widgets Qt5::Network Qt5::Xml Qt5::Gui Qt5::OpenGL Qt5::Core)
|
||||||
|
|
||||||
IF(WIN32)
|
|
||||||
SET(QT_LIBRARIES ${QT_LIBRARIES} Qt5::WinExtras)
|
|
||||||
ENDIF()
|
|
||||||
ENDIF()
|
ENDIF()
|
||||||
ELSE()
|
ELSE()
|
||||||
MESSAGE(WARNING "Unable to find Qt 5")
|
MESSAGE(WARNING "Unable to find Qt 5")
|
||||||
|
|
74
code/CMakeModules/FindSteam.cmake
Normal file
74
code/CMakeModules/FindSteam.cmake
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
# - Locate Steam API
|
||||||
|
# This module defines
|
||||||
|
# STEAM_LIBRARY, the library to link against
|
||||||
|
# VORBIS_FOUND, if false, do not try to link to VORBIS
|
||||||
|
# VORBIS_INCLUDE_DIR, where to find headers.
|
||||||
|
|
||||||
|
IF(STEAM_LIBRARY AND STEAM_INCLUDE_DIR)
|
||||||
|
# in cache already
|
||||||
|
SET(Steam_FIND_QUIETLY TRUE)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
|
||||||
|
FIND_PATH(STEAM_INCLUDE_DIR
|
||||||
|
steam_api.h
|
||||||
|
PATH_SUFFIXES steam
|
||||||
|
PATHS
|
||||||
|
$ENV{STEAM_DIR}/public
|
||||||
|
)
|
||||||
|
|
||||||
|
IF(WIN32)
|
||||||
|
IF(TARGET_X64)
|
||||||
|
SET(STEAM_LIBNAME steam_api64)
|
||||||
|
SET(STEAM_RUNTIMENAME steam_api64.dll)
|
||||||
|
SET(STEAM_PATHNAME redistributable_bin/win64)
|
||||||
|
ELSE()
|
||||||
|
SET(STEAM_LIBNAME steam_api)
|
||||||
|
SET(STEAM_RUNTIMENAME steam_api.dll)
|
||||||
|
SET(STEAM_PATHNAME redistributable_bin)
|
||||||
|
ENDIF()
|
||||||
|
ELSEIF(APPLE)
|
||||||
|
# universal binary
|
||||||
|
SET(STEAM_LIBNAME steam_api)
|
||||||
|
SET(STEAM_RUNTIMENAME libsteam_api.dylib)
|
||||||
|
SET(STEAM_PATHNAME redistributable_bin/osx32)
|
||||||
|
ELSE()
|
||||||
|
SET(STEAM_LIBNAME steam_api)
|
||||||
|
SET(STEAM_RUNTIMENAME libsteam_api.so)
|
||||||
|
IF(TARGET_X64)
|
||||||
|
SET(STEAM_PATHNAME redistributable_bin/linux64)
|
||||||
|
ELSE()
|
||||||
|
SET(STEAM_PATHNAME redistributable_bin/linux32)
|
||||||
|
ENDIF()
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
FIND_LIBRARY(STEAM_LIBRARY
|
||||||
|
NAMES ${STEAM_LIBNAME}
|
||||||
|
HINTS
|
||||||
|
$ENV{STEAM_DIR}/${STEAM_PATHNAME}
|
||||||
|
)
|
||||||
|
|
||||||
|
FIND_FILE(STEAM_RUNTIME
|
||||||
|
NAMES ${STEAM_RUNTIMENAME}
|
||||||
|
HINTS
|
||||||
|
$ENV{STEAM_DIR}/${STEAM_PATHNAME}
|
||||||
|
PATHS
|
||||||
|
${EXTERNAL_BINARY_PATH}
|
||||||
|
${CMAKE_LIBRARY_PATH}
|
||||||
|
/usr/local/lib
|
||||||
|
/usr/lib
|
||||||
|
)
|
||||||
|
|
||||||
|
# Don't need to check STEAM_LIBRARY because we're dynamically loading Steam DLL
|
||||||
|
IF(STEAM_INCLUDE_DIR)
|
||||||
|
SET(STEAM_FOUND ON)
|
||||||
|
SET(STEAM_LIBRARIES ${STEAM_LIBRARY})
|
||||||
|
SET(STEAM_INCLUDE_DIRS ${STEAM_INCLUDE_DIR})
|
||||||
|
IF(NOT Steam_FIND_QUIETLY)
|
||||||
|
MESSAGE(STATUS "Found Steam: ${STEAM_INCLUDE_DIR} and ${STEAM_RUNTIME}")
|
||||||
|
ENDIF()
|
||||||
|
ELSE()
|
||||||
|
IF(NOT Steam_FIND_QUIETLY)
|
||||||
|
MESSAGE(STATUS "Warning: Unable to find Steam!")
|
||||||
|
ENDIF()
|
||||||
|
ENDIF()
|
|
@ -258,6 +258,7 @@ MACRO(NL_SETUP_DEFAULT_OPTIONS)
|
||||||
OPTION(WITH_NELNS "Build NeL Network Services." OFF)
|
OPTION(WITH_NELNS "Build NeL Network Services." OFF)
|
||||||
OPTION(WITH_RYZOM "Build Ryzom Core." ON )
|
OPTION(WITH_RYZOM "Build Ryzom Core." ON )
|
||||||
OPTION(WITH_SNOWBALLS "Build Snowballs." OFF)
|
OPTION(WITH_SNOWBALLS "Build Snowballs." OFF)
|
||||||
|
OPTION(WITH_TOOLS "Build Tools" OFF)
|
||||||
ENDMACRO(NL_SETUP_DEFAULT_OPTIONS)
|
ENDMACRO(NL_SETUP_DEFAULT_OPTIONS)
|
||||||
|
|
||||||
MACRO(NL_SETUP_NEL_DEFAULT_OPTIONS)
|
MACRO(NL_SETUP_NEL_DEFAULT_OPTIONS)
|
||||||
|
@ -1083,15 +1084,15 @@ MACRO(SETUP_EXTERNAL)
|
||||||
IF(APPLE)
|
IF(APPLE)
|
||||||
IF(WITH_STATIC_EXTERNAL)
|
IF(WITH_STATIC_EXTERNAL)
|
||||||
SET(CMAKE_FIND_LIBRARY_SUFFIXES .a)
|
SET(CMAKE_FIND_LIBRARY_SUFFIXES .a)
|
||||||
ELSE(WITH_STATIC_EXTERNAL)
|
ELSE()
|
||||||
SET(CMAKE_FIND_LIBRARY_SUFFIXES .dylib .so .a)
|
SET(CMAKE_FIND_LIBRARY_SUFFIXES .dylib .so .a)
|
||||||
ENDIF(WITH_STATIC_EXTERNAL)
|
ENDIF()
|
||||||
ELSE(APPLE)
|
ELSE(APPLE)
|
||||||
IF(WITH_STATIC_EXTERNAL)
|
IF(WITH_STATIC_EXTERNAL)
|
||||||
SET(CMAKE_FIND_LIBRARY_SUFFIXES .a .so)
|
SET(CMAKE_FIND_LIBRARY_SUFFIXES .a .so)
|
||||||
ELSE(WITH_STATIC_EXTERNAL)
|
ELSE()
|
||||||
SET(CMAKE_FIND_LIBRARY_SUFFIXES .so .a)
|
SET(CMAKE_FIND_LIBRARY_SUFFIXES .so .a)
|
||||||
ENDIF(WITH_STATIC_EXTERNAL)
|
ENDIF()
|
||||||
ENDIF(APPLE)
|
ENDIF(APPLE)
|
||||||
ENDIF(WIN32)
|
ENDIF(WIN32)
|
||||||
|
|
||||||
|
|
|
@ -336,6 +336,10 @@ void itoaInt64 (sint64 number, char *str, sint64 base = 10);
|
||||||
std::string bytesToHumanReadable (const std::string &bytes);
|
std::string bytesToHumanReadable (const std::string &bytes);
|
||||||
std::string bytesToHumanReadable (uint64 bytes);
|
std::string bytesToHumanReadable (uint64 bytes);
|
||||||
|
|
||||||
|
/// Convert a number in bytes into a string that is easily readable by an human, for example 105123 -> "102kb"
|
||||||
|
/// Using units array as string: 0 => B, 1 => KiB, 2 => MiB, 3 => GiB, etc...
|
||||||
|
std::string bytesToHumanReadableUnits (uint64 bytes, const std::vector<std::string> &units);
|
||||||
|
|
||||||
/// Convert a human readable into a bytes, for example "102kb" -> 105123
|
/// Convert a human readable into a bytes, for example "102kb" -> 105123
|
||||||
uint32 humanReadableToBytes (const std::string &str);
|
uint32 humanReadableToBytes (const std::string &str);
|
||||||
|
|
||||||
|
|
|
@ -230,7 +230,7 @@ public:
|
||||||
/** Get application directory.
|
/** Get application directory.
|
||||||
* \return directory where applications should write files.
|
* \return directory where applications should write files.
|
||||||
*/
|
*/
|
||||||
std::string getApplicationDirectory(const std::string &appName = "");
|
std::string getApplicationDirectory(const std::string &appName = "", bool local = false);
|
||||||
|
|
||||||
/** Get a temporary directory.
|
/** Get a temporary directory.
|
||||||
* \return temporary directory where applications should write files.
|
* \return temporary directory where applications should write files.
|
||||||
|
@ -540,7 +540,7 @@ public:
|
||||||
/** Get application directory.
|
/** Get application directory.
|
||||||
* \return directory where applications should write files.
|
* \return directory where applications should write files.
|
||||||
*/
|
*/
|
||||||
static std::string getApplicationDirectory(const std::string &appName = "");
|
static std::string getApplicationDirectory(const std::string &appName = "", bool local = false);
|
||||||
|
|
||||||
/** Get a temporary directory.
|
/** Get a temporary directory.
|
||||||
* \return temporary directory where applications should write files.
|
* \return temporary directory where applications should write files.
|
||||||
|
|
|
@ -246,27 +246,38 @@ inline bool fromString(const std::string &str, bool &val)
|
||||||
{
|
{
|
||||||
if (str.length() == 1)
|
if (str.length() == 1)
|
||||||
{
|
{
|
||||||
if (str[0] == '1')
|
const char c = str[0];
|
||||||
|
|
||||||
|
switch(c)
|
||||||
{
|
{
|
||||||
|
case '1':
|
||||||
|
case 't':
|
||||||
|
case 'T':
|
||||||
|
case 'y':
|
||||||
|
case 'Y':
|
||||||
val = true;
|
val = true;
|
||||||
}
|
break;
|
||||||
else if (str[0] == '0')
|
|
||||||
{
|
case '0':
|
||||||
|
case 'f':
|
||||||
|
case 'F':
|
||||||
|
case 'n':
|
||||||
|
case 'N':
|
||||||
val = false;
|
val = false;
|
||||||
}
|
break;
|
||||||
else
|
|
||||||
{
|
default:
|
||||||
val = false;
|
val = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (str == "true")
|
if (str == "true" || str == "yes")
|
||||||
{
|
{
|
||||||
val = true;
|
val = true;
|
||||||
}
|
}
|
||||||
else if (str == "false")
|
else if (str == "false" || str == "no")
|
||||||
{
|
{
|
||||||
val = false;
|
val = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -715,7 +715,7 @@ SOURCE_GROUP(Stereo FILES
|
||||||
|
|
||||||
NL_TARGET_LIB(nel3d ${HEADERS} ${SRC})
|
NL_TARGET_LIB(nel3d ${HEADERS} ${SRC})
|
||||||
|
|
||||||
INCLUDE_DIRECTORIES(BEFORE ${FREETYPE_INCLUDE_DIRS})
|
INCLUDE_DIRECTORIES(${FREETYPE_INCLUDE_DIRS})
|
||||||
INCLUDE_DIRECTORIES(${LIBVR_INCLUDE_DIR})
|
INCLUDE_DIRECTORIES(${LIBVR_INCLUDE_DIR})
|
||||||
|
|
||||||
TARGET_LINK_LIBRARIES(nel3d nelmisc ${FREETYPE_LIBRARIES} ${LIBOVR_LIBRARIES} ${LIBVR_LIBRARY})
|
TARGET_LINK_LIBRARIES(nel3d nelmisc ${FREETYPE_LIBRARIES} ${LIBOVR_LIBRARIES} ${LIBVR_LIBRARY})
|
||||||
|
|
|
@ -380,7 +380,26 @@ string bytesToHumanReadable (uint64 bytes)
|
||||||
div++;
|
div++;
|
||||||
res = newres;
|
res = newres;
|
||||||
}
|
}
|
||||||
return toString ("%" NL_I64 "u%s", res, divTable[div]);
|
return toString ("%" NL_I64 "u %s", res, divTable[div]);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string bytesToHumanReadableUnits (uint64 bytes, const std::vector<std::string> &units)
|
||||||
|
{
|
||||||
|
if (units.empty()) return "";
|
||||||
|
|
||||||
|
uint div = 0;
|
||||||
|
uint last = units.size()-1;
|
||||||
|
uint64 res = bytes;
|
||||||
|
uint64 newres = res;
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
newres /= 1024;
|
||||||
|
if(newres < 8 || div > 3 || div == last)
|
||||||
|
break;
|
||||||
|
++div;
|
||||||
|
res = newres;
|
||||||
|
}
|
||||||
|
return toString ("%" NL_I64 "u %s", res, units[div].c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 humanReadableToBytes (const string &str)
|
uint32 humanReadableToBytes (const string &str)
|
||||||
|
@ -394,7 +413,8 @@ uint32 humanReadableToBytes (const string &str)
|
||||||
if(str[0]<'0' || str[0]>'9')
|
if(str[0]<'0' || str[0]>'9')
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
res = atoi (str.c_str());
|
if (!fromString(str, res))
|
||||||
|
return 0;
|
||||||
|
|
||||||
if(str[str.size()-1] == 'B')
|
if(str[str.size()-1] == 'B')
|
||||||
{
|
{
|
||||||
|
@ -404,12 +424,30 @@ uint32 humanReadableToBytes (const string &str)
|
||||||
// there's no break and it's **normal**
|
// there's no break and it's **normal**
|
||||||
switch (str[str.size()-2])
|
switch (str[str.size()-2])
|
||||||
{
|
{
|
||||||
|
// kB/KB, MB, GB and TB are 1000 multiples
|
||||||
|
case 'T': res *= 1000;
|
||||||
|
case 'G': res *= 1000;
|
||||||
|
case 'M': res *= 1000;
|
||||||
|
case 'k': res *= 1000; break; // kilo symbol should be a lowercase K
|
||||||
|
case 'K': res *= 1000; break;
|
||||||
|
case 'i':
|
||||||
|
{
|
||||||
|
// KiB, MiB, GiB and TiB are 1024 multiples
|
||||||
|
if (str.size()<4)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
switch (str[str.size()-3])
|
||||||
|
{
|
||||||
|
case 'T': res *= 1024;
|
||||||
case 'G': res *= 1024;
|
case 'G': res *= 1024;
|
||||||
case 'M': res *= 1024;
|
case 'M': res *= 1024;
|
||||||
case 'K': res *= 1024;
|
case 'K': res *= 1024;
|
||||||
default: ;
|
default: ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
default: ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -694,8 +732,22 @@ bool launchProgram(const std::string &programName, const std::string &arguments,
|
||||||
SetEnvironmentVariable( SE_TRANSLATOR_IN_MAIN_MODULE, NULL );
|
SetEnvironmentVariable( SE_TRANSLATOR_IN_MAIN_MODULE, NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
string arg = " " + arguments;
|
const char *sProgramName = programName.c_str();
|
||||||
BOOL res = CreateProcessA(programName.c_str(), (char*)arg.c_str(), NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE | CREATE_NO_WINDOW, NULL, NULL, &si, &pi);
|
|
||||||
|
std::string args;
|
||||||
|
|
||||||
|
// a .bat file must have first parameter to NULL and use 2nd parameter to pass filename
|
||||||
|
if (CFile::getExtension(programName) == "bat")
|
||||||
|
{
|
||||||
|
sProgramName = NULL;
|
||||||
|
args = "\"" + programName + "\" " + arguments;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
args = arguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL res = CreateProcessA(sProgramName, (char*)args.c_str(), NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE | CREATE_NO_WINDOW, NULL, NULL, &si, &pi);
|
||||||
|
|
||||||
if (res)
|
if (res)
|
||||||
{
|
{
|
||||||
|
@ -716,26 +768,14 @@ bool launchProgram(const std::string &programName, const std::string &arguments,
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(NL_OS_MAC)
|
#elif defined(NL_OS_MAC)
|
||||||
std::string command;
|
|
||||||
|
|
||||||
if (CFile::getExtension(programName) == "app")
|
|
||||||
{
|
|
||||||
// we need to open bundles with "open" command
|
// we need to open bundles with "open" command
|
||||||
command = NLMISC::toString("open \"%s\"", programName.c_str());
|
std::string command = NLMISC::toString("open \"%s\"", programName.c_str());
|
||||||
|
|
||||||
// append arguments if any
|
// append arguments if any
|
||||||
if (!arguments.empty())
|
if (!arguments.empty())
|
||||||
{
|
{
|
||||||
command += NLMISC::toString(" --args %s", arguments.c_str());
|
command += NLMISC::toString(" --args %s", arguments.c_str());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
command = programName;
|
|
||||||
|
|
||||||
// append arguments if any
|
|
||||||
if (!arguments.empty()) command += " " + arguments;
|
|
||||||
}
|
|
||||||
|
|
||||||
int res = system(command.c_str());
|
int res = system(command.c_str());
|
||||||
|
|
||||||
|
@ -838,8 +878,22 @@ sint launchProgramAndWaitForResult(const std::string &programName, const std::st
|
||||||
SetEnvironmentVariable( SE_TRANSLATOR_IN_MAIN_MODULE, NULL );
|
SetEnvironmentVariable( SE_TRANSLATOR_IN_MAIN_MODULE, NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
string arg = " " + arguments;
|
const char *sProgramName = programName.c_str();
|
||||||
BOOL ok = CreateProcessA(programName.c_str(), (char*)arg.c_str(), NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE | CREATE_NO_WINDOW, NULL, NULL, &si, &pi);
|
|
||||||
|
std::string args;
|
||||||
|
|
||||||
|
// a .bat file must have first parameter to NULL and use 2nd parameter to pass filename
|
||||||
|
if (CFile::getExtension(programName) == "bat")
|
||||||
|
{
|
||||||
|
sProgramName = NULL;
|
||||||
|
args = "\"" + programName + "\" " + arguments;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
args = arguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL ok = CreateProcessA(sProgramName, (char*)args.c_str(), NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE | CREATE_NO_WINDOW, NULL, NULL, &si, &pi);
|
||||||
|
|
||||||
if (ok)
|
if (ok)
|
||||||
{
|
{
|
||||||
|
|
|
@ -260,7 +260,7 @@ void CLog::displayString (const char *str)
|
||||||
TempArgs.FileName = _FileName;
|
TempArgs.FileName = _FileName;
|
||||||
TempArgs.Line = _Line;
|
TempArgs.Line = _Line;
|
||||||
TempArgs.FuncName = _FuncName;
|
TempArgs.FuncName = _FuncName;
|
||||||
TempArgs.CallstackAndLog = "";
|
TempArgs.CallstackAndLog.clear();
|
||||||
|
|
||||||
TempString = str;
|
TempString = str;
|
||||||
}
|
}
|
||||||
|
@ -281,7 +281,7 @@ void CLog::displayString (const char *str)
|
||||||
localargs.FileName = _FileName;
|
localargs.FileName = _FileName;
|
||||||
localargs.Line = _Line;
|
localargs.Line = _Line;
|
||||||
localargs.FuncName = _FuncName;
|
localargs.FuncName = _FuncName;
|
||||||
localargs.CallstackAndLog = "";
|
localargs.CallstackAndLog.clear();
|
||||||
|
|
||||||
disp = str;
|
disp = str;
|
||||||
args = &localargs;
|
args = &localargs;
|
||||||
|
@ -314,7 +314,7 @@ void CLog::displayString (const char *str)
|
||||||
(*idi)->display( *args, disp );
|
(*idi)->display( *args, disp );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TempString = "";
|
TempString.clear();
|
||||||
unsetPosition();
|
unsetPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1777,19 +1777,29 @@ std::string CFileContainer::getWindowsDirectory()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CPath::getApplicationDirectory(const std::string &appName)
|
std::string CPath::getApplicationDirectory(const std::string &appName, bool local)
|
||||||
{
|
{
|
||||||
return getInstance()->_FileContainer.getApplicationDirectory(appName);
|
return getInstance()->_FileContainer.getApplicationDirectory(appName, local);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CFileContainer::getApplicationDirectory(const std::string &appName)
|
std::string CFileContainer::getApplicationDirectory(const std::string &appName, bool local)
|
||||||
{
|
{
|
||||||
static std::string appPath;
|
static std::string appPaths[2];
|
||||||
|
std::string &appPath = appPaths[local ? 1 : 0];
|
||||||
if (appPath.empty())
|
if (appPath.empty())
|
||||||
{
|
{
|
||||||
#ifdef NL_OS_WINDOWS
|
#ifdef NL_OS_WINDOWS
|
||||||
wchar_t buffer[MAX_PATH];
|
wchar_t buffer[MAX_PATH];
|
||||||
|
#ifdef CSIDL_LOCAL_APPDATA
|
||||||
|
if (local)
|
||||||
|
{
|
||||||
|
SHGetSpecialFolderPathW(NULL, buffer, CSIDL_LOCAL_APPDATA, TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
SHGetSpecialFolderPathW(NULL, buffer, CSIDL_APPDATA, TRUE);
|
SHGetSpecialFolderPathW(NULL, buffer, CSIDL_APPDATA, TRUE);
|
||||||
|
}
|
||||||
appPath = CPath::standardizePath(ucstring((ucchar*)buffer).toUtf8());
|
appPath = CPath::standardizePath(ucstring((ucchar*)buffer).toUtf8());
|
||||||
#elif defined(NL_OS_MAC)
|
#elif defined(NL_OS_MAC)
|
||||||
appPath = CPath::standardizePath(getenv("HOME"));
|
appPath = CPath::standardizePath(getenv("HOME"));
|
||||||
|
@ -2568,13 +2578,13 @@ std::string CPath::makePathAbsolute( const std::string &relativePath, const std:
|
||||||
{
|
{
|
||||||
absolutePath = relativePath;
|
absolutePath = relativePath;
|
||||||
}
|
}
|
||||||
#else
|
else
|
||||||
// Unix filesystem absolute path
|
#endif
|
||||||
|
// Unix filesystem absolute path (works also under Windows)
|
||||||
if (relativePath[0] == '/')
|
if (relativePath[0] == '/')
|
||||||
{
|
{
|
||||||
absolutePath = relativePath;
|
absolutePath = relativePath;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Add a slash to the directory if necessary.
|
// Add a slash to the directory if necessary.
|
||||||
|
@ -2600,14 +2610,15 @@ std::string CPath::makePathAbsolute( const std::string &relativePath, const std:
|
||||||
|
|
||||||
// Now build the new absolute path
|
// Now build the new absolute path
|
||||||
absolutePath += relativePath;
|
absolutePath += relativePath;
|
||||||
absolutePath = standardizePath(absolutePath, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
absolutePath = standardizePath(absolutePath, true);
|
||||||
|
|
||||||
if (simplify)
|
if (simplify)
|
||||||
{
|
{
|
||||||
// split all components path to manage parent directories
|
// split all components path to manage parent directories
|
||||||
std::vector<std::string> tokens;
|
std::vector<std::string> tokens;
|
||||||
explode(absolutePath, std::string("/"), tokens, true);
|
explode(absolutePath, std::string("/"), tokens, false);
|
||||||
|
|
||||||
std::vector<std::string> directoryParts;
|
std::vector<std::string> directoryParts;
|
||||||
|
|
||||||
|
@ -2639,7 +2650,10 @@ std::string CPath::makePathAbsolute( const std::string &relativePath, const std:
|
||||||
|
|
||||||
// rebuild the whole absolute path
|
// rebuild the whole absolute path
|
||||||
for(uint i = 1, len = directoryParts.size(); i < len; ++i)
|
for(uint i = 1, len = directoryParts.size(); i < len; ++i)
|
||||||
|
{
|
||||||
|
if (!directoryParts[i].empty())
|
||||||
absolutePath += "/" + directoryParts[i];
|
absolutePath += "/" + directoryParts[i];
|
||||||
|
}
|
||||||
|
|
||||||
// add trailing slash
|
// add trailing slash
|
||||||
absolutePath += "/";
|
absolutePath += "/";
|
||||||
|
|
|
@ -555,7 +555,7 @@ string CSheetId::toString(bool ifNotFoundUseNumericId) const
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return NLMISC::toString( "<Sheet %d not found in sheet_id.bin>", _Id.Id );
|
return NLMISC::toString( "<Sheet %u not found in sheet_id.bin>", _Id.Id );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -136,7 +136,7 @@ else:
|
||||||
needUpdateBnp = needUpdateDirNoSubdirFile(log, sourcePath, targetBnp)
|
needUpdateBnp = needUpdateDirNoSubdirFile(log, sourcePath, targetBnp)
|
||||||
if (needUpdateBnp):
|
if (needUpdateBnp):
|
||||||
printLog(log, "BNP " + targetBnp)
|
printLog(log, "BNP " + targetBnp)
|
||||||
subprocess.call([ BnpMake, "/p", sourcePath, targetPath ] + package[1])
|
subprocess.call([ BnpMake, "-p", sourcePath, "-o", targetBnp ] + package[1][1:])
|
||||||
else:
|
else:
|
||||||
printLog(log, "SKIP " + targetBnp)
|
printLog(log, "SKIP " + targetBnp)
|
||||||
printLog(log, "")
|
printLog(log, "")
|
||||||
|
|
|
@ -134,8 +134,8 @@ int main(int argc, char **argv)
|
||||||
args.addArg("u", "unpack", "", "Unpack the BNP file to a directory");
|
args.addArg("u", "unpack", "", "Unpack the BNP file to a directory");
|
||||||
args.addArg("l", "list", "", "List the files contained in the BNP file");
|
args.addArg("l", "list", "", "List the files contained in the BNP file");
|
||||||
args.addArg("o", "output", "destination", "Output directory or file");
|
args.addArg("o", "output", "destination", "Output directory or file");
|
||||||
args.addArg("i", "if", "wildcard", "Add the file if it matches the wilcard (at least one 'if' conditions must be met for a file to be adding)");
|
args.addArg("i", "if", "wildcard", "Add the file if it matches the wilcard (at least one 'if' conditions must be met for a file to be adding)", false);
|
||||||
args.addArg("n", "ifnot", "wildcard", "Add the file if it doesn't match the wilcard (all the 'ifnot' conditions must be met for a file to be adding)");
|
args.addArg("n", "ifnot", "wildcard", "Add the file if it doesn't match the wilcard (all the 'ifnot' conditions must be met for a file to be adding)", false);
|
||||||
args.addAdditionalArg("input", "Input directory or BNP file depending on command");
|
args.addAdditionalArg("input", "Input directory or BNP file depending on command");
|
||||||
|
|
||||||
if (!args.parse(argc, argv)) return 1;
|
if (!args.parse(argc, argv)) return 1;
|
||||||
|
|
|
@ -114,6 +114,20 @@ int main(int argc, char *argv[])
|
||||||
// init Nel context
|
// init Nel context
|
||||||
new NLMISC::CApplicationContext;
|
new NLMISC::CApplicationContext;
|
||||||
|
|
||||||
|
// disable nldebug messages in logs in Release
|
||||||
|
#ifdef NL_RELEASE
|
||||||
|
NLMISC::DisableNLDebug = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
NLMISC::createDebug(NULL);
|
||||||
|
|
||||||
|
#ifndef NL_DEBUG
|
||||||
|
NLMISC::INelContext::getInstance().getDebugLog()->removeDisplayer("DEFAULT_SD");
|
||||||
|
NLMISC::INelContext::getInstance().getInfoLog()->removeDisplayer("DEFAULT_SD");
|
||||||
|
NLMISC::INelContext::getInstance().getWarningLog()->removeDisplayer("DEFAULT_SD");
|
||||||
|
NLMISC::INelContext::getInstance().getErrorLog()->removeDisplayer("DEFAULT_SD");
|
||||||
|
#endif // NL_DEBUG
|
||||||
|
|
||||||
bool noerrors = false;
|
bool noerrors = false;
|
||||||
|
|
||||||
try
|
try
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#include "ut_misc_co_task.h"
|
#include "ut_misc_co_task.h"
|
||||||
#include "ut_misc_command.h"
|
#include "ut_misc_command.h"
|
||||||
|
#include "ut_misc_common.h"
|
||||||
#include "ut_misc_config_file.h"
|
#include "ut_misc_config_file.h"
|
||||||
#include "ut_misc_debug.h"
|
#include "ut_misc_debug.h"
|
||||||
#include "ut_misc_dynlibload.h"
|
#include "ut_misc_dynlibload.h"
|
||||||
|
@ -38,6 +39,7 @@ struct CUTMisc : public Test::Suite
|
||||||
{
|
{
|
||||||
add(auto_ptr<Test::Suite>(new CUTMiscCoTask));
|
add(auto_ptr<Test::Suite>(new CUTMiscCoTask));
|
||||||
add(auto_ptr<Test::Suite>(new CUTMiscCommand));
|
add(auto_ptr<Test::Suite>(new CUTMiscCommand));
|
||||||
|
add(auto_ptr<Test::Suite>(new CUTMiscCommon));
|
||||||
add(auto_ptr<Test::Suite>(new CUTMiscConfigFile));
|
add(auto_ptr<Test::Suite>(new CUTMiscConfigFile));
|
||||||
add(auto_ptr<Test::Suite>(new CUTMiscDebug));
|
add(auto_ptr<Test::Suite>(new CUTMiscDebug));
|
||||||
add(auto_ptr<Test::Suite>(new CUTMiscDynLibLoad));
|
add(auto_ptr<Test::Suite>(new CUTMiscDynLibLoad));
|
||||||
|
|
171
code/nel/tools/nel_unit_test/ut_misc_common.h
Normal file
171
code/nel/tools/nel_unit_test/ut_misc_common.h
Normal file
|
@ -0,0 +1,171 @@
|
||||||
|
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
||||||
|
// Copyright (C) 2010 Winch Gate Property Limited
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef UT_MISC_COMMON
|
||||||
|
#define UT_MISC_COMMON
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
#include <nel/misc/common.h>
|
||||||
|
|
||||||
|
struct CUTMiscCommon : public Test::Suite
|
||||||
|
{
|
||||||
|
CUTMiscCommon()
|
||||||
|
{
|
||||||
|
TEST_ADD(CUTMiscCommon::bytesToHumanReadableUnits);
|
||||||
|
TEST_ADD(CUTMiscCommon::humanReadableToBytes);
|
||||||
|
|
||||||
|
// Add a line here when adding a new test METHOD
|
||||||
|
}
|
||||||
|
|
||||||
|
void bytesToHumanReadableUnits()
|
||||||
|
{
|
||||||
|
std::vector<std::string> units;
|
||||||
|
|
||||||
|
std::string res;
|
||||||
|
|
||||||
|
// no unit, returns an empty string
|
||||||
|
res = NLMISC::bytesToHumanReadableUnits(0, units);
|
||||||
|
TEST_ASSERT(res.empty());
|
||||||
|
|
||||||
|
// support bytes
|
||||||
|
units.push_back("B");
|
||||||
|
|
||||||
|
// 0 bytes
|
||||||
|
res = NLMISC::bytesToHumanReadableUnits(0, units);
|
||||||
|
TEST_ASSERT(res == "0 B");
|
||||||
|
|
||||||
|
// 1000 bytes in B
|
||||||
|
res = NLMISC::bytesToHumanReadableUnits(1000, units);
|
||||||
|
TEST_ASSERT(res == "1000 B");
|
||||||
|
|
||||||
|
// 1024 bytes in B
|
||||||
|
res = NLMISC::bytesToHumanReadableUnits(1024, units);
|
||||||
|
TEST_ASSERT(res == "1024 B");
|
||||||
|
|
||||||
|
// support kibibytes
|
||||||
|
units.push_back("KiB");
|
||||||
|
|
||||||
|
// 1000 bytes in B or KiB
|
||||||
|
res = NLMISC::bytesToHumanReadableUnits(1000, units);
|
||||||
|
TEST_ASSERT(res == "1000 B");
|
||||||
|
|
||||||
|
// 1024 bytes in B or KiB
|
||||||
|
res = NLMISC::bytesToHumanReadableUnits(1024, units);
|
||||||
|
TEST_ASSERT(res == "1024 B");
|
||||||
|
|
||||||
|
// 1 MB in B or KiB
|
||||||
|
res = NLMISC::bytesToHumanReadableUnits(1000 * 1000, units);
|
||||||
|
TEST_ASSERT(res == "976 KiB");
|
||||||
|
|
||||||
|
// 1 MiB in B or KiB
|
||||||
|
res = NLMISC::bytesToHumanReadableUnits(1024 * 1024, units);
|
||||||
|
TEST_ASSERT(res == "1024 KiB");
|
||||||
|
|
||||||
|
// 1 GB in B or KiB
|
||||||
|
res = NLMISC::bytesToHumanReadableUnits(1000 * 1000 * 1000, units);
|
||||||
|
TEST_ASSERT(res == "976562 KiB");
|
||||||
|
|
||||||
|
// 1 GiB in B or KiB
|
||||||
|
res = NLMISC::bytesToHumanReadableUnits(1024 * 1024 * 1024, units);
|
||||||
|
TEST_ASSERT(res == "1048576 KiB");
|
||||||
|
|
||||||
|
// support mebibytes
|
||||||
|
units.push_back("MiB");
|
||||||
|
|
||||||
|
// 1 GB in B, KiB or MiB
|
||||||
|
res = NLMISC::bytesToHumanReadableUnits(1000 * 1000 * 1000, units);
|
||||||
|
TEST_ASSERT(res == "953 MiB");
|
||||||
|
|
||||||
|
// 1 GiB in B, KiB or MiB
|
||||||
|
res = NLMISC::bytesToHumanReadableUnits(1024 * 1024 * 1024, units);
|
||||||
|
TEST_ASSERT(res == "1024 MiB");
|
||||||
|
}
|
||||||
|
|
||||||
|
void humanReadableToBytes()
|
||||||
|
{
|
||||||
|
uint64 bytes = 0;
|
||||||
|
|
||||||
|
// kiB is a wrong unit
|
||||||
|
bytes = NLMISC::humanReadableToBytes("1kiB");
|
||||||
|
TEST_ASSERT(bytes == 1);
|
||||||
|
|
||||||
|
// 1 kibibyte
|
||||||
|
bytes = NLMISC::humanReadableToBytes("1KiB");
|
||||||
|
TEST_ASSERT(bytes == 1024);
|
||||||
|
|
||||||
|
// 1 mebibyte
|
||||||
|
bytes = NLMISC::humanReadableToBytes("1MiB");
|
||||||
|
TEST_ASSERT(bytes == 1024*1024);
|
||||||
|
|
||||||
|
// 1 kilobyte
|
||||||
|
bytes = NLMISC::humanReadableToBytes("1KB");
|
||||||
|
TEST_ASSERT(bytes == 1000);
|
||||||
|
|
||||||
|
// 1 kilobyte
|
||||||
|
bytes = NLMISC::humanReadableToBytes("1kB");
|
||||||
|
TEST_ASSERT(bytes == 1000);
|
||||||
|
|
||||||
|
// 1 megabyte
|
||||||
|
bytes = NLMISC::humanReadableToBytes("1MB");
|
||||||
|
TEST_ASSERT(bytes == 1000*1000);
|
||||||
|
|
||||||
|
// 1 byte
|
||||||
|
bytes = NLMISC::humanReadableToBytes("1B");
|
||||||
|
TEST_ASSERT(bytes == 1);
|
||||||
|
|
||||||
|
// 1 byte
|
||||||
|
bytes = NLMISC::humanReadableToBytes("1");
|
||||||
|
TEST_ASSERT(bytes == 1);
|
||||||
|
|
||||||
|
// kiB is a wrong unit
|
||||||
|
bytes = NLMISC::humanReadableToBytes("1 kiB");
|
||||||
|
TEST_ASSERT(bytes == 1);
|
||||||
|
|
||||||
|
// 1 kibibyte
|
||||||
|
bytes = NLMISC::humanReadableToBytes("1 KiB");
|
||||||
|
TEST_ASSERT(bytes == 1024);
|
||||||
|
|
||||||
|
// 1 mebibyte
|
||||||
|
bytes = NLMISC::humanReadableToBytes("1 MiB");
|
||||||
|
TEST_ASSERT(bytes == 1024*1024);
|
||||||
|
|
||||||
|
// 1 kilobyte
|
||||||
|
bytes = NLMISC::humanReadableToBytes("1 KB");
|
||||||
|
TEST_ASSERT(bytes == 1000);
|
||||||
|
|
||||||
|
// 1 kilobyte
|
||||||
|
bytes = NLMISC::humanReadableToBytes("1 kB");
|
||||||
|
TEST_ASSERT(bytes == 1000);
|
||||||
|
|
||||||
|
// 1 megabyte
|
||||||
|
bytes = NLMISC::humanReadableToBytes("1 MB");
|
||||||
|
TEST_ASSERT(bytes == 1000*1000);
|
||||||
|
|
||||||
|
// 1 byte
|
||||||
|
bytes = NLMISC::humanReadableToBytes("1 B");
|
||||||
|
TEST_ASSERT(bytes == 1);
|
||||||
|
|
||||||
|
// not a number
|
||||||
|
bytes = NLMISC::humanReadableToBytes("AB");
|
||||||
|
TEST_ASSERT(bytes == 0);
|
||||||
|
|
||||||
|
// not a positive number
|
||||||
|
bytes = NLMISC::humanReadableToBytes("-1 B");
|
||||||
|
TEST_ASSERT(bytes == 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -444,11 +444,13 @@ struct CUTMiscStringCommon : public Test::Suite
|
||||||
|
|
||||||
// min limit -1, unable to compare with minimum value because no lower type
|
// min limit -1, unable to compare with minimum value because no lower type
|
||||||
ret = NLMISC::fromString("-9223372036854775809", val);
|
ret = NLMISC::fromString("-9223372036854775809", val);
|
||||||
TEST_ASSERT(ret && val == std::numeric_limits<sint64>::max());
|
// with GCC, it returns min, with VC++ it returns max
|
||||||
|
TEST_ASSERT(ret && (val == std::numeric_limits<sint64>::max() || std::numeric_limits<sint64>::min()));
|
||||||
|
|
||||||
// max limit +1, unable to compare with maximum value because no higher type
|
// max limit +1, unable to compare with maximum value because no higher type
|
||||||
ret = NLMISC::fromString("9223372036854775808", val);
|
ret = NLMISC::fromString("9223372036854775808", val);
|
||||||
TEST_ASSERT(ret && val == std::numeric_limits<sint64>::min());
|
// with GCC, it returns max with VC++ it returns min
|
||||||
|
TEST_ASSERT(ret && (val == std::numeric_limits<sint64>::min() || std::numeric_limits<sint64>::max()));
|
||||||
|
|
||||||
// with period
|
// with period
|
||||||
ret = NLMISC::fromString("1.2", val);
|
ret = NLMISC::fromString("1.2", val);
|
||||||
|
@ -508,7 +510,8 @@ struct CUTMiscStringCommon : public Test::Suite
|
||||||
|
|
||||||
// max limit +1, unable to compare with maximum value because no higher type
|
// max limit +1, unable to compare with maximum value because no higher type
|
||||||
ret = NLMISC::fromString("18446744073709551616", val);
|
ret = NLMISC::fromString("18446744073709551616", val);
|
||||||
TEST_ASSERT(ret && val == std::numeric_limits<uint64>::min());
|
// with GCC, it returns max with VC++ it returns min
|
||||||
|
TEST_ASSERT(ret && (val == std::numeric_limits<uint64>::min() || val == std::numeric_limits<uint64>::max()));
|
||||||
|
|
||||||
// with period
|
// with period
|
||||||
ret = NLMISC::fromString("1.2", val);
|
ret = NLMISC::fromString("1.2", val);
|
||||||
|
@ -682,60 +685,59 @@ struct CUTMiscStringCommon : public Test::Suite
|
||||||
// tests for bool
|
// tests for bool
|
||||||
bool val;
|
bool val;
|
||||||
|
|
||||||
// true value
|
// true values
|
||||||
val = false;
|
|
||||||
ret = NLMISC::fromString("1", val);
|
ret = NLMISC::fromString("1", val);
|
||||||
TEST_ASSERT(val);
|
TEST_ASSERT(ret && val);
|
||||||
TEST_ASSERT_MSG(ret, "should succeed");
|
|
||||||
|
|
||||||
val = false;
|
ret = NLMISC::fromString("t", val);
|
||||||
NLMISC::fromString("t", val);
|
TEST_ASSERT(ret && val);
|
||||||
TEST_ASSERT(val);
|
|
||||||
|
|
||||||
val = false;
|
ret = NLMISC::fromString("y", val);
|
||||||
NLMISC::fromString("y", val);
|
TEST_ASSERT(ret && val);
|
||||||
TEST_ASSERT(val);
|
|
||||||
|
|
||||||
val = false;
|
ret = NLMISC::fromString("T", val);
|
||||||
NLMISC::fromString("T", val);
|
TEST_ASSERT(ret && val);
|
||||||
TEST_ASSERT(val);
|
|
||||||
|
|
||||||
val = false;
|
ret = NLMISC::fromString("Y", val);
|
||||||
NLMISC::fromString("Y", val);
|
TEST_ASSERT(ret && val);
|
||||||
TEST_ASSERT(val);
|
|
||||||
|
|
||||||
val = true;
|
ret = NLMISC::fromString("true", val);
|
||||||
|
TEST_ASSERT(ret && val);
|
||||||
|
|
||||||
|
ret = NLMISC::fromString("yes", val);
|
||||||
|
TEST_ASSERT(ret && val);
|
||||||
|
|
||||||
|
// false values
|
||||||
ret = NLMISC::fromString("0", val);
|
ret = NLMISC::fromString("0", val);
|
||||||
TEST_ASSERT(!val);
|
TEST_ASSERT(ret && !val);
|
||||||
TEST_ASSERT_MSG(ret, "should succeed");
|
|
||||||
|
|
||||||
val = true;
|
ret = NLMISC::fromString("f", val);
|
||||||
NLMISC::fromString("f", val);
|
TEST_ASSERT(ret && !val);
|
||||||
TEST_ASSERT(!val);
|
|
||||||
|
|
||||||
val = true;
|
ret = NLMISC::fromString("n", val);
|
||||||
NLMISC::fromString("n", val);
|
TEST_ASSERT(ret && !val);
|
||||||
TEST_ASSERT(!val);
|
|
||||||
|
|
||||||
val = true;
|
ret = NLMISC::fromString("F", val);
|
||||||
NLMISC::fromString("F", val);
|
TEST_ASSERT(ret && !val);
|
||||||
TEST_ASSERT(!val);
|
|
||||||
|
|
||||||
val = true;
|
ret = NLMISC::fromString("N", val);
|
||||||
NLMISC::fromString("N", val);
|
TEST_ASSERT(ret && !val);
|
||||||
TEST_ASSERT(!val);
|
|
||||||
|
ret = NLMISC::fromString("false", val);
|
||||||
|
TEST_ASSERT(ret && !val);
|
||||||
|
|
||||||
|
ret = NLMISC::fromString("no", val);
|
||||||
|
TEST_ASSERT(ret && !val);
|
||||||
|
|
||||||
|
// wrong values
|
||||||
|
ret = NLMISC::fromString("YES", val);
|
||||||
|
TEST_ASSERT(!ret && !val);
|
||||||
|
|
||||||
|
ret = NLMISC::fromString("foo", val);
|
||||||
|
TEST_ASSERT(!ret && !val);
|
||||||
|
|
||||||
// bad character
|
|
||||||
ret = NLMISC::fromString("a", val);
|
ret = NLMISC::fromString("a", val);
|
||||||
TEST_ASSERT_MSG(!ret, "should not succeed");
|
TEST_ASSERT(!ret && !val);
|
||||||
|
|
||||||
val = true;
|
|
||||||
NLMISC::fromString("a", val);
|
|
||||||
TEST_ASSERT_MSG(val, "should not modify the value");
|
|
||||||
|
|
||||||
val = false;
|
|
||||||
NLMISC::fromString("a", val);
|
|
||||||
TEST_ASSERT_MSG(!val, "should not modify the value");
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ ADD_SUBDIRECTORY(src)
|
||||||
|
|
||||||
IF(WITH_RYZOM_CLIENT)
|
IF(WITH_RYZOM_CLIENT)
|
||||||
#ADD_SUBDIRECTORY(data)
|
#ADD_SUBDIRECTORY(data)
|
||||||
#ADD_SUBDIRECTORY(patcher)
|
|
||||||
|
|
||||||
IF(UNIX AND NOT APPLE)
|
IF(UNIX AND NOT APPLE)
|
||||||
ADD_SUBDIRECTORY(unix)
|
ADD_SUBDIRECTORY(unix)
|
||||||
|
|
|
@ -265,7 +265,7 @@
|
||||||
fontsize="10"
|
fontsize="10"
|
||||||
line_maxw="182"
|
line_maxw="182"
|
||||||
shadow="true"
|
shadow="true"
|
||||||
hardtext="No File..." />
|
hardtext="uiNoFiles" />
|
||||||
</group>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
<tree node="mp3_player" />
|
<tree node="mp3_player" />
|
||||||
|
|
|
@ -183,7 +183,7 @@
|
||||||
posref="BL BL"
|
posref="BL BL"
|
||||||
scale="true"
|
scale="true"
|
||||||
y="4"
|
y="4"
|
||||||
w="110"
|
w="130"
|
||||||
h="2"
|
h="2"
|
||||||
texture="W_line_hor2.tga" />
|
texture="W_line_hor2.tga" />
|
||||||
<view type="text"
|
<view type="text"
|
||||||
|
@ -202,7 +202,7 @@
|
||||||
posref="MM MM"
|
posref="MM MM"
|
||||||
x="0"
|
x="0"
|
||||||
y="-1"
|
y="-1"
|
||||||
w="110"
|
w="130"
|
||||||
h="8"
|
h="8"
|
||||||
vertical="false"
|
vertical="false"
|
||||||
align="L"
|
align="L"
|
||||||
|
@ -246,7 +246,7 @@
|
||||||
posref="BL BL"
|
posref="BL BL"
|
||||||
scale="true"
|
scale="true"
|
||||||
y="4"
|
y="4"
|
||||||
w="110"
|
w="130"
|
||||||
h="2"
|
h="2"
|
||||||
texture="W_line_hor2.tga" />
|
texture="W_line_hor2.tga" />
|
||||||
<view type="text"
|
<view type="text"
|
||||||
|
@ -265,7 +265,7 @@
|
||||||
posref="MM MM"
|
posref="MM MM"
|
||||||
x="0"
|
x="0"
|
||||||
y="-1"
|
y="-1"
|
||||||
w="110"
|
w="130"
|
||||||
h="8"
|
h="8"
|
||||||
vertical="false"
|
vertical="false"
|
||||||
align="L"
|
align="L"
|
||||||
|
@ -3441,7 +3441,7 @@
|
||||||
widget="sbint"
|
widget="sbint"
|
||||||
link="UI:SAVE:CHAT:FONT_SIZE"
|
link="UI:SAVE:CHAT:FONT_SIZE"
|
||||||
min="9"
|
min="9"
|
||||||
max="14"
|
max="20"
|
||||||
realtime="true" />
|
realtime="true" />
|
||||||
<param ui="entity_colors:cc_user:c"
|
<param ui="entity_colors:cc_user:c"
|
||||||
type="db"
|
type="db"
|
||||||
|
|
|
@ -361,11 +361,11 @@ on_enter="leave_modal" options="no_bordure" mouse_pos="false" exit_key_pushed="t
|
||||||
fontsize="10" shadow="true" hardtext="uiOnPatchOpt" />
|
fontsize="10" shadow="true" hardtext="uiOnPatchOpt" />
|
||||||
|
|
||||||
<group id="global_patch" w="382" h="22" posparent="global_win" posref="MM MM" >
|
<group id="global_patch" w="382" h="22" posparent="global_win" posref="MM MM" >
|
||||||
<view type="text" id="name" posref="BL BL" fontsize="12" x="2" y="0" color="135 243 28 255" shadow="true" hardtext="TOTAL PATCH" />
|
<view type="text" id="name" posref="BL BL" fontsize="12" x="2" y="0" color="135 243 28 255" shadow="true" hardtext="uiTotalPatch" />
|
||||||
<view type="text" id="size" posref="BR BR" fontsize="12" x="-8" y="0" color="135 243 28 255" shadow="true" hardtext="...Kbs" />
|
<view type="text" id="size" posref="BR BR" fontsize="12" x="-8" y="0" color="135 243 28 255" shadow="true" hardtext="...Kbs" />
|
||||||
</group>
|
</group>
|
||||||
<group id="nonopt_patch" w="382" h="22" posparent="nonopt_win" posref="MM MM" >
|
<group id="nonopt_patch" w="382" h="22" posparent="nonopt_win" posref="MM MM" >
|
||||||
<view type="text" id="name" posref="BL BL" fontsize="12" x="2" y="0" color="135 243 28 255" shadow="true" hardtext="NON OPTIONAL FILES" />
|
<view type="text" id="name" posref="BL BL" fontsize="12" x="2" y="0" color="135 243 28 255" shadow="true" hardtext="uiRequiredFiles" />
|
||||||
<view type="text" id="size" posref="BR BR" fontsize="12" x="-8" y="0" color="135 243 28 255" shadow="true" hardtext="...Kbs" />
|
<view type="text" id="size" posref="BR BR" fontsize="12" x="-8" y="0" color="135 243 28 255" shadow="true" hardtext="...Kbs" />
|
||||||
</group>
|
</group>
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
# Need clientsheets lib for sheets packer tool
|
# Need clientsheets lib for sheets packer tool
|
||||||
ADD_SUBDIRECTORY(client_sheets)
|
ADD_SUBDIRECTORY(client_sheets)
|
||||||
|
|
||||||
|
# Need seven_zip lib for patch_gen tool
|
||||||
|
ADD_SUBDIRECTORY(seven_zip)
|
||||||
|
|
||||||
IF(WITH_RYZOM_CLIENT)
|
IF(WITH_RYZOM_CLIENT)
|
||||||
# These are Windows/MFC apps
|
|
||||||
SET(SEVENZIP_LIBRARY "ryzom_sevenzip")
|
|
||||||
|
|
||||||
ADD_SUBDIRECTORY(seven_zip)
|
|
||||||
|
|
||||||
# Patch should never be enabled on Steam
|
# Patch should never be enabled on Steam
|
||||||
IF(WITH_RYZOM_PATCH AND NOT WITH_RYZOM_STEAM)
|
IF(WITH_RYZOM_STEAM)
|
||||||
|
ADD_DEFINITIONS(-DRZ_USE_STEAM)
|
||||||
|
FIND_PACKAGE(Steam)
|
||||||
|
ELSEIF(WITH_RYZOM_PATCH)
|
||||||
ADD_DEFINITIONS(-DRZ_USE_PATCH)
|
ADD_DEFINITIONS(-DRZ_USE_PATCH)
|
||||||
|
|
||||||
IF(WITH_RYZOM_CUSTOM_PATCH_SERVER)
|
IF(WITH_RYZOM_CUSTOM_PATCH_SERVER)
|
||||||
|
@ -115,6 +116,15 @@ IF(WITH_RYZOM_CLIENT)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
|
||||||
|
IF(WITH_RYZOM_STEAM AND STEAM_RUNTIME)
|
||||||
|
ADD_CUSTOM_COMMAND(TARGET ryzom_client POST_BUILD COMMAND cp -p ${STEAM_RUNTIME} ${RYZOM_CONTENTS_DIR}/MacOS)
|
||||||
|
|
||||||
|
IF(CODESIGN_ALLOCATE AND APPLE_CERTIFICATE)
|
||||||
|
ADD_CUSTOM_COMMAND(TARGET ryzom_client POST_BUILD COMMAND CODESIGN_ALLOCATE=${CODESIGN_ALLOCATE} codesign --no-strict -fs "${APPLE_CERTIFICATE}" "${RYZOM_CONTENTS_DIR}/MacOS/${STEAM_RUNTIMENAME}" COMMENT "Signing Steam client runtime...")
|
||||||
|
ENDIF()
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
IF(CODESIGN_ALLOCATE AND APPLE_CERTIFICATE)
|
IF(CODESIGN_ALLOCATE AND APPLE_CERTIFICATE)
|
||||||
ADD_CUSTOM_COMMAND(TARGET khanat_client POST_BUILD COMMAND CODESIGN_ALLOCATE=${CODESIGN_ALLOCATE} codesign -fs "${APPLE_CERTIFICATE}" "${RYZOM_OUTPUT_DIR}" COMMENT "Signing Ryzom bundle...")
|
ADD_CUSTOM_COMMAND(TARGET khanat_client POST_BUILD COMMAND CODESIGN_ALLOCATE=${CODESIGN_ALLOCATE} codesign -fs "${APPLE_CERTIFICATE}" "${RYZOM_OUTPUT_DIR}" COMMENT "Signing Ryzom bundle...")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
@ -129,6 +139,10 @@ IF(WITH_RYZOM_CLIENT)
|
||||||
${ZLIB_INCLUDE_DIR}
|
${ZLIB_INCLUDE_DIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
IF(STEAM_FOUND)
|
||||||
|
INCLUDE_DIRECTORIES(${STEAM_INCLUDE_DIRS})
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
TARGET_LINK_LIBRARIES(khanat_client
|
TARGET_LINK_LIBRARIES(khanat_client
|
||||||
nelmisc
|
nelmisc
|
||||||
nelnet
|
nelnet
|
||||||
|
@ -137,13 +151,13 @@ IF(WITH_RYZOM_CLIENT)
|
||||||
nel3d
|
nel3d
|
||||||
nelgui
|
nelgui
|
||||||
nelsound
|
nelsound
|
||||||
|
ryzom_sevenzip
|
||||||
ryzom_clientsheets
|
ryzom_clientsheets
|
||||||
ryzom_gameshare
|
ryzom_gameshare
|
||||||
nelpacs
|
nelpacs
|
||||||
${LUA_LIBRARIES}
|
${LUA_LIBRARIES}
|
||||||
${LUABIND_LIBRARIES}
|
${LUABIND_LIBRARIES}
|
||||||
${CURL_LIBRARIES}
|
${CURL_LIBRARIES}
|
||||||
${SEVENZIP_LIBRARY}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
ADD_DEFINITIONS(${LIBXML2_DEFINITIONS})
|
ADD_DEFINITIONS(${LIBXML2_DEFINITIONS})
|
||||||
|
|
|
@ -62,6 +62,10 @@
|
||||||
#include "client_cfg.h"
|
#include "client_cfg.h"
|
||||||
#include "far_tp.h"
|
#include "far_tp.h"
|
||||||
|
|
||||||
|
#ifdef RZ_USE_STEAM
|
||||||
|
#include "steam_client.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
///////////
|
///////////
|
||||||
// USING //
|
// USING //
|
||||||
///////////
|
///////////
|
||||||
|
@ -319,6 +323,13 @@ int main(int argc, char **argv)
|
||||||
prelogInit();
|
prelogInit();
|
||||||
RYZOM_CATCH("Pre-Login Init")
|
RYZOM_CATCH("Pre-Login Init")
|
||||||
|
|
||||||
|
#ifdef RZ_USE_STEAM
|
||||||
|
CSteamClient steamClient;
|
||||||
|
|
||||||
|
if (steamClient.init())
|
||||||
|
LoginCustomParameters = "&steam_auth_session_ticket=" + steamClient.getAuthSessionTicket();
|
||||||
|
#endif
|
||||||
|
|
||||||
// Log the client and choose from shard
|
// Log the client and choose from shard
|
||||||
RYZOM_TRY("Login")
|
RYZOM_TRY("Login")
|
||||||
if (!ClientCfg.Local && (ClientCfg.TestBrowser || ClientCfg.FSHost.empty()))
|
if (!ClientCfg.Local && (ClientCfg.TestBrowser || ClientCfg.FSHost.empty()))
|
||||||
|
|
|
@ -659,7 +659,7 @@ static void addPaths(IProgressCallback &progress, const std::vector<std::string>
|
||||||
std::vector<std::string> directoryPrefixes;
|
std::vector<std::string> directoryPrefixes;
|
||||||
|
|
||||||
// current directory has priority everywhere
|
// current directory has priority everywhere
|
||||||
directoryPrefixes.push_back("");
|
directoryPrefixes.push_back(CPath::standardizePath(CPath::getCurrentPath()));
|
||||||
|
|
||||||
#if defined(NL_OS_WINDOWS)
|
#if defined(NL_OS_WINDOWS)
|
||||||
// check in same directory as executable
|
// check in same directory as executable
|
||||||
|
@ -678,12 +678,9 @@ static void addPaths(IProgressCallback &progress, const std::vector<std::string>
|
||||||
if (CFile::isDirectory(getRyzomSharePrefix())) directoryPrefixes.push_back(CPath::standardizePath(getRyzomSharePrefix()));
|
if (CFile::isDirectory(getRyzomSharePrefix())) directoryPrefixes.push_back(CPath::standardizePath(getRyzomSharePrefix()));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::vector<std::string> directoriesToProcess;
|
std::map<std::string, sint> directoriesToProcess;
|
||||||
|
|
||||||
// reserve maximum memory space for all combinations
|
// first pass, build a map with all existing directories to process in second pass
|
||||||
directoriesToProcess.reserve(directoryPrefixes.size() * paths.size());
|
|
||||||
|
|
||||||
// first pass, build a vector with all existing directories to process in second pass
|
|
||||||
for (uint j = 0; j < directoryPrefixes.size(); j++)
|
for (uint j = 0; j < directoryPrefixes.size(); j++)
|
||||||
{
|
{
|
||||||
std::string directoryPrefix = directoryPrefixes[j];
|
std::string directoryPrefix = directoryPrefixes[j];
|
||||||
|
@ -698,15 +695,17 @@ static void addPaths(IProgressCallback &progress, const std::vector<std::string>
|
||||||
|
|
||||||
// only process existing directories
|
// only process existing directories
|
||||||
if (CFile::isExists(directory))
|
if (CFile::isExists(directory))
|
||||||
directoriesToProcess.push_back(directory);
|
directoriesToProcess[directory] = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint total = (uint)directoriesToProcess.size();
|
uint total = (uint)directoriesToProcess.size();
|
||||||
uint current = 0, next = 0;
|
uint current = 0, next = 0;
|
||||||
|
|
||||||
|
std::map<std::string, sint>::const_iterator it = directoriesToProcess.begin(), iend = directoriesToProcess.end();
|
||||||
|
|
||||||
// second pass, add search paths
|
// second pass, add search paths
|
||||||
for (uint i = 0, len = directoriesToProcess.size(); i < len; ++i)
|
while (it != iend)
|
||||||
{
|
{
|
||||||
// update next progress value
|
// update next progress value
|
||||||
++next;
|
++next;
|
||||||
|
@ -717,9 +716,11 @@ static void addPaths(IProgressCallback &progress, const std::vector<std::string>
|
||||||
// next is current value
|
// next is current value
|
||||||
current = next;
|
current = next;
|
||||||
|
|
||||||
CPath::addSearchPath(directoriesToProcess[i], recurse, false, &progress);
|
CPath::addSearchPath(it->first, recurse, false, &progress);
|
||||||
|
|
||||||
progress.popCropedValues();
|
progress.popCropedValues();
|
||||||
|
|
||||||
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -112,7 +112,7 @@ bool InitMouseWithCursor (bool hardware)
|
||||||
}
|
}
|
||||||
else if (width != 0 && height != 0)
|
else if (width != 0 && height != 0)
|
||||||
{
|
{
|
||||||
nlwarning("mouse pos %u, %u", x, y);
|
nlwarning("Mouse pos %f, %f", x, y);
|
||||||
Driver->setMousePos(x / width, y / height);
|
Driver->setMousePos(x / width, y / height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@ extern bool SetMousePosFirstTime;
|
||||||
|
|
||||||
vector<CShard> Shards;
|
vector<CShard> Shards;
|
||||||
|
|
||||||
string LoginLogin, LoginPassword, ClientApp, Salt;
|
string LoginLogin, LoginPassword, ClientApp, Salt, LoginCustomParameters;
|
||||||
uint32 LoginShardId = 0xFFFFFFFF;
|
uint32 LoginShardId = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
|
||||||
|
@ -1169,7 +1169,7 @@ void onlogin(bool vanishScreen = true)
|
||||||
// Check the login/pass
|
// Check the login/pass
|
||||||
|
|
||||||
// main menu page for r2mode
|
// main menu page for r2mode
|
||||||
string res = checkLogin(LoginLogin, LoginPassword, ClientApp);
|
string res = checkLogin(LoginLogin, LoginPassword, ClientApp, LoginCustomParameters);
|
||||||
if (res.empty())
|
if (res.empty())
|
||||||
{
|
{
|
||||||
// if not in auto login, push login ok event
|
// if not in auto login, push login ok event
|
||||||
|
@ -2738,7 +2738,7 @@ REGISTER_ACTION_HANDLER (CAHOnBackToLogin, "on_back_to_login");
|
||||||
|
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
string checkLogin(const string &login, const string &password, const string &clientApp)
|
string checkLogin(const string &login, const string &password, const string &clientApp, const std::string &customParameters)
|
||||||
{
|
{
|
||||||
CPatchManager *pPM = CPatchManager::getInstance();
|
CPatchManager *pPM = CPatchManager::getInstance();
|
||||||
Shards.clear();
|
Shards.clear();
|
||||||
|
@ -2795,7 +2795,7 @@ string checkLogin(const string &login, const string &password, const string &cli
|
||||||
{
|
{
|
||||||
// R2 login sequence
|
// R2 login sequence
|
||||||
std::string cryptedPassword = CCrypt::crypt(password, Salt);
|
std::string cryptedPassword = CCrypt::crypt(password, Salt);
|
||||||
if(!HttpClient.sendGet(ClientCfg.ConfigFile.getVar("StartupPage").asString()+"?cmd=login&login="+login+"&password="+cryptedPassword+"&clientApplication="+clientApp+"&cp=1"+"&lg="+ClientCfg.LanguageCode))
|
if(!HttpClient.sendGet(ClientCfg.ConfigFile.getVar("StartupPage").asString()+"?cmd=login&login="+login+"&password="+cryptedPassword+"&clientApplication="+clientApp+"&cp=1"+"&lg="+ClientCfg.LanguageCode+customParameters))
|
||||||
return "Can't send (error code 2)";
|
return "Can't send (error code 2)";
|
||||||
|
|
||||||
// the response should contains the result code and the cookie value
|
// the response should contains the result code and the cookie value
|
||||||
|
|
|
@ -46,7 +46,7 @@ struct CShard
|
||||||
std::string EmergencyPatchURL;
|
std::string EmergencyPatchURL;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern std::string LoginLogin, LoginPassword;
|
extern std::string LoginLogin, LoginPassword, LoginCustomParameters;
|
||||||
extern uint32 LoginShardId;
|
extern uint32 LoginShardId;
|
||||||
|
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ extern uint32 AvailablePatchs;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::string checkLogin(const std::string &login, const std::string &password, const std::string &clientApp);
|
std::string checkLogin(const std::string &login, const std::string &password, const std::string &clientApp, const std::string &customParameters = "");
|
||||||
std::string selectShard(uint32 shardId, std::string &cookie, std::string &addr);
|
std::string selectShard(uint32 shardId, std::string &cookie, std::string &addr);
|
||||||
std::string getBGDownloaderCommandLine();
|
std::string getBGDownloaderCommandLine();
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,7 @@
|
||||||
#include "nel/misc/sha1.h"
|
#include "nel/misc/sha1.h"
|
||||||
#include "nel/misc/big_file.h"
|
#include "nel/misc/big_file.h"
|
||||||
#include "nel/misc/i18n.h"
|
#include "nel/misc/i18n.h"
|
||||||
|
#include "nel/misc/cmd_args.h"
|
||||||
|
|
||||||
#include "game_share/bg_downloader_msg.h"
|
#include "game_share/bg_downloader_msg.h"
|
||||||
|
|
||||||
|
@ -54,6 +55,7 @@
|
||||||
#include "login.h"
|
#include "login.h"
|
||||||
#include "user_agent.h"
|
#include "user_agent.h"
|
||||||
|
|
||||||
|
#include "seven_zip/seven_zip.h"
|
||||||
|
|
||||||
#ifndef RY_BG_DOWNLOADER
|
#ifndef RY_BG_DOWNLOADER
|
||||||
#include "client_cfg.h"
|
#include "client_cfg.h"
|
||||||
|
@ -88,6 +90,8 @@ extern string R2ServerVersion;
|
||||||
std::string TheTmpInstallDirectory = "patch/client_install";
|
std::string TheTmpInstallDirectory = "patch/client_install";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern NLMISC::CCmdArgs Args;
|
||||||
|
|
||||||
// ****************************************************************************
|
// ****************************************************************************
|
||||||
// ****************************************************************************
|
// ****************************************************************************
|
||||||
// ****************************************************************************
|
// ****************************************************************************
|
||||||
|
@ -119,8 +123,16 @@ CPatchManager::CPatchManager() : State("t_state"), DataScanState("t_data_scan_st
|
||||||
UpdateBatchFilename = "updt_nl.sh";
|
UpdateBatchFilename = "updt_nl.sh";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// use current directory by default
|
// use application directory by default
|
||||||
setClientRootPath("./");
|
std::string rootPath = Args.getProgramPath();
|
||||||
|
|
||||||
|
if (!CFile::fileExists(rootPath + "client_default.cfg"))
|
||||||
|
{
|
||||||
|
// use current directory
|
||||||
|
rootPath = CPath::getCurrentPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
setClientRootPath(rootPath);
|
||||||
|
|
||||||
VerboseLog = true;
|
VerboseLog = true;
|
||||||
|
|
||||||
|
@ -707,7 +719,7 @@ void CPatchManager::stopPatchThread()
|
||||||
// ****************************************************************************
|
// ****************************************************************************
|
||||||
void CPatchManager::deleteBatchFile()
|
void CPatchManager::deleteBatchFile()
|
||||||
{
|
{
|
||||||
deleteFile(UpdateBatchFilename, false, false);
|
deleteFile(ClientRootPath + UpdateBatchFilename, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ****************************************************************************
|
// ****************************************************************************
|
||||||
|
@ -715,29 +727,12 @@ void CPatchManager::createBatchFile(CProductDescriptionForClient &descFile, bool
|
||||||
{
|
{
|
||||||
uint nblab = 0;
|
uint nblab = 0;
|
||||||
|
|
||||||
FILE *fp = NULL;
|
std::string content;
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unpack files with category ExtractPath non empty
|
// Unpack files with category ExtractPath non empty
|
||||||
const CBNPCategorySet &rDescCats = descFile.getCategories();
|
const CBNPCategorySet &rDescCats = descFile.getCategories();
|
||||||
OptionalCat.clear();
|
OptionalCat.clear();
|
||||||
|
|
||||||
for (uint32 i = 0; i < rDescCats.categoryCount(); ++i)
|
for (uint32 i = 0; i < rDescCats.categoryCount(); ++i)
|
||||||
{
|
{
|
||||||
// For all optional categories check if there is a 'file to patch' in it
|
// For all optional categories check if there is a 'file to patch' in it
|
||||||
|
@ -757,11 +752,6 @@ void CPatchManager::createBatchFile(CProductDescriptionForClient &descFile, bool
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
if (useBatchFile)
|
|
||||||
{
|
|
||||||
fclose(fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -770,11 +760,6 @@ void CPatchManager::createBatchFile(CProductDescriptionForClient &descFile, bool
|
||||||
// TODO: handle exception?
|
// TODO: handle exception?
|
||||||
string err = toString("Error unpacking %s", rFilename.c_str());
|
string err = toString("Error unpacking %s", rFilename.c_str());
|
||||||
|
|
||||||
if (useBatchFile)
|
|
||||||
{
|
|
||||||
fclose(fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw Exception (err);
|
throw Exception (err);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -786,39 +771,41 @@ void CPatchManager::createBatchFile(CProductDescriptionForClient &descFile, bool
|
||||||
NLMISC::CFile::createDirectoryTree(DstPath);
|
NLMISC::CFile::createDirectoryTree(DstPath);
|
||||||
|
|
||||||
// this file must be moved
|
// this file must be moved
|
||||||
if (useBatchFile)
|
|
||||||
{
|
|
||||||
#ifdef NL_OS_WINDOWS
|
#ifdef NL_OS_WINDOWS
|
||||||
SrcPath = CPath::standardizeDosPath(SrcPath);
|
SrcPath = CPath::standardizeDosPath(SrcPath);
|
||||||
DstPath = CPath::standardizeDosPath(DstPath);
|
DstPath = CPath::standardizeDosPath(DstPath);
|
||||||
#else
|
|
||||||
SrcPath = CPath::standardizePath(SrcPath);
|
|
||||||
DstPath = CPath::standardizePath(DstPath);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
std::string SrcName = SrcPath + vFilenames[fff];
|
std::string SrcName = SrcPath + vFilenames[fff];
|
||||||
std::string DstName = DstPath + 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
|
// write windows .bat format else write sh format
|
||||||
#ifdef NL_OS_WINDOWS
|
#ifdef NL_OS_WINDOWS
|
||||||
fprintf(fp, ":loop%u\n", nblab);
|
content += toString(":loop%u\n", nblab);
|
||||||
fprintf(fp, "attrib -r -a -s -h %s\n", DstName.c_str());
|
content += toString("attrib -r -a -s -h \"%s\"\n", DstName.c_str());
|
||||||
fprintf(fp, "del %s\n", DstName.c_str());
|
content += toString("del \"%s\"\n", DstName.c_str());
|
||||||
fprintf(fp, "if exist %s goto loop%u\n", DstName.c_str(), nblab);
|
content += toString("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("move \"%s\" \"%s\"\n", SrcName.c_str(), DstPath.c_str());
|
||||||
#else
|
#else
|
||||||
fprintf(fp, "rm -rf %s\n", DstName.c_str());
|
content += toString("rm -rf \"%s\"\n", DstName.c_str());
|
||||||
fprintf(fp, "mv %s %s\n", SrcName.c_str(), DstPath.c_str());
|
content += toString("mv %s \"%s\"\n", SrcName.c_str(), DstPath.c_str());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
deleteFile(DstName);
|
|
||||||
CFile::moveFile(DstName, SrcName);
|
|
||||||
}
|
|
||||||
|
|
||||||
nblab++;
|
nblab++;
|
||||||
}
|
}
|
||||||
|
@ -826,58 +813,86 @@ void CPatchManager::createBatchFile(CProductDescriptionForClient &descFile, bool
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string patchDirectory = CPath::standardizeDosPath(ClientRootPath + "patch");
|
||||||
|
|
||||||
// Finalize batch file
|
// 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
|
std::string patchContent;
|
||||||
if (useBatchFile)
|
|
||||||
{
|
|
||||||
fprintf(fp, ":looppatch\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
vector<string> vFileList;
|
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)
|
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
|
#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
|
#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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!patchContent.empty())
|
||||||
|
{
|
||||||
|
#ifdef NL_OS_WINDOWS
|
||||||
|
content += toString(":looppatch\n");
|
||||||
|
|
||||||
|
content += patchContent;
|
||||||
|
|
||||||
|
content += toString("rd /Q /S \"" + patchDirectory + "\"\n");
|
||||||
|
content += toString("if exist \"" + patchDirectory + "\" goto looppatch\n");
|
||||||
|
#else
|
||||||
|
content += toString("rm -rf \"" + patchDirectory + "\"\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CFile::deleteFile(vFileList[i]);
|
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
|
#ifdef NL_OS_WINDOWS
|
||||||
fprintf(fp, "rd /Q /S patch\n");
|
fprintf(fp, "@echo off\n");
|
||||||
fprintf(fp, "if exist patch goto looppatch\n");
|
|
||||||
#else
|
#else
|
||||||
fprintf(fp, "rm -rf patch\n");
|
fprintf(fp, "#!/bin/sh\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CFile::deleteDirectory("patch");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (useBatchFile)
|
// append content of script
|
||||||
{
|
fprintf(fp, content.c_str());
|
||||||
|
|
||||||
if (wantRyzomRestart)
|
if (wantRyzomRestart)
|
||||||
{
|
{
|
||||||
#ifdef NL_OS_WINDOWS
|
#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
|
#else
|
||||||
fprintf(fp, "%s $1 $2 $3\n", RyzomFilename.c_str());
|
fprintf(fp, "\"%s\" $1 $2 $3\n", RyzomFilename.c_str());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -886,11 +901,11 @@ void CPatchManager::createBatchFile(CProductDescriptionForClient &descFile, bool
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
if (diskFull)
|
if (diskFull)
|
||||||
{
|
{
|
||||||
throw NLMISC::EDiskFullError(UpdateBatchFilename.c_str());
|
throw NLMISC::EDiskFullError(batchFilename.c_str());
|
||||||
}
|
}
|
||||||
if (writeError)
|
if (writeError)
|
||||||
{
|
{
|
||||||
throw NLMISC::EWriteError(UpdateBatchFilename.c_str());
|
throw NLMISC::EWriteError(batchFilename.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -902,93 +917,44 @@ void CPatchManager::executeBatchFile()
|
||||||
extern void quitCrashReport ();
|
extern void quitCrashReport ();
|
||||||
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;
|
bool r2Mode = false;
|
||||||
|
|
||||||
#ifndef RY_BG_DOWNLOADER
|
#ifndef RY_BG_DOWNLOADER
|
||||||
r2Mode = ClientCfg.R2Mode;
|
r2Mode = ClientCfg.R2Mode;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
string strCmdLine;
|
std::string batchFilename;
|
||||||
|
|
||||||
strCmdLine = "./" + UpdateBatchFilename;
|
#ifdef NL_OS_WINDOWS
|
||||||
|
batchFilename = CPath::standardizeDosPath(ClientRootPath);
|
||||||
chmod(strCmdLine.c_str(), S_IRWXU);
|
#else
|
||||||
if (r2Mode)
|
batchFilename = ClientRootPath;
|
||||||
{
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// exit(0);
|
batchFilename += UpdateBatchFilename;
|
||||||
|
|
||||||
|
#ifdef NL_OS_UNIX
|
||||||
|
// make script executable under UNIX
|
||||||
|
chmod(batchFilename.c_str(), S_IRWXU);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::string arguments = LoginLogin + " " + LoginPassword;
|
||||||
|
|
||||||
|
if (!r2Mode)
|
||||||
|
{
|
||||||
|
arguments += " " + toString(LoginShardId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (launchProgram(batchFilename, arguments, false))
|
||||||
|
{
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// error occurs during the launch
|
||||||
|
string str = toString("Can't execute '%s': code=%d %s (error code 30)", batchFilename.c_str(), errno, strerror(errno));
|
||||||
|
throw Exception (str);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ****************************************************************************
|
// ****************************************************************************
|
||||||
|
@ -1155,9 +1121,9 @@ void CPatchManager::readDescFile(sint32 nVersion)
|
||||||
|
|
||||||
std::string unpackTo = category.getUnpackTo();
|
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);
|
category.setUnpackTo(unpackTo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1827,7 +1793,7 @@ void CPatchManager::MyPatchingCB::progress(float f)
|
||||||
{
|
{
|
||||||
CPatchManager *pPM = CPatchManager::getInstance();
|
CPatchManager *pPM = CPatchManager::getInstance();
|
||||||
double p = 100.0*f;
|
double p = 100.0*f;
|
||||||
ucstring sTranslate = CI18N::get("uiApplyingDelta") + toString(" %s (%5.02f %%)", patchFilename.c_str(), p);
|
ucstring sTranslate = CI18N::get("uiApplyingDelta") + toString(" %s (%5.02f %%)", CFile::getFilename(patchFilename).c_str(), p);
|
||||||
pPM->setState(false, sTranslate);
|
pPM->setState(false, sTranslate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2355,7 +2321,6 @@ void CPatchThread::run()
|
||||||
ucstring sTranslate;
|
ucstring sTranslate;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
// First do all ref files
|
// First do all ref files
|
||||||
// ----------------------
|
// ----------------------
|
||||||
|
|
||||||
|
@ -2428,7 +2393,6 @@ void CPatchThread::run()
|
||||||
pPM->deleteFile(pPM->UpdateBatchFilename, false, false);
|
pPM->deleteFile(pPM->UpdateBatchFilename, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!bErr)
|
if (!bErr)
|
||||||
{
|
{
|
||||||
sTranslate = CI18N::get("uiPatchEndNoErr");
|
sTranslate = CI18N::get("uiPatchEndNoErr");
|
||||||
|
@ -2438,6 +2402,7 @@ void CPatchThread::run()
|
||||||
// Set a more explicit error message
|
// Set a more explicit error message
|
||||||
pPM->setErrorMessage(sTranslate);
|
pPM->setErrorMessage(sTranslate);
|
||||||
}
|
}
|
||||||
|
|
||||||
PatchOk = !bErr;
|
PatchOk = !bErr;
|
||||||
Ended = true;
|
Ended = true;
|
||||||
}
|
}
|
||||||
|
@ -2625,7 +2590,7 @@ void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP)
|
||||||
// try to unpack the file
|
// try to unpack the file
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!CPatchManager::unpackLZMA(pPM->ClientPatchPath+lzmaFile, OutFilename+".tmp"))
|
if (!unpackLZMA(pPM->ClientPatchPath+lzmaFile, OutFilename+".tmp"))
|
||||||
{
|
{
|
||||||
// fallback to standard patch method
|
// fallback to standard patch method
|
||||||
usePatchFile = true;
|
usePatchFile = true;
|
||||||
|
@ -2746,7 +2711,7 @@ void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP)
|
||||||
|
|
||||||
string OutFilename = pPM->ClientPatchPath + rFTP.FileName + ".tmp__" + toString(j);
|
string OutFilename = pPM->ClientPatchPath + rFTP.FileName + ".tmp__" + toString(j);
|
||||||
|
|
||||||
sTranslate = CI18N::get("uiApplyingDelta") + " " + PatchName;
|
sTranslate = CI18N::get("uiApplyingDelta") + " " + CFile::getFilename(PatchName);
|
||||||
pPM->setState(true, sTranslate);
|
pPM->setState(true, sTranslate);
|
||||||
|
|
||||||
xDeltaPatch(PatchName, SourceNameXD, OutFilename);
|
xDeltaPatch(PatchName, SourceNameXD, OutFilename);
|
||||||
|
@ -3087,7 +3052,7 @@ bool CPatchManager::download(const std::string& patchFullname, const std::string
|
||||||
&& patchName.substr(patchName.size() - zsStrLength) == zsStr)
|
&& patchName.substr(patchName.size() - zsStrLength) == zsStr)
|
||||||
{
|
{
|
||||||
std::string outFilename = patchName.substr(0, patchName.size() - zsStrLength);
|
std::string outFilename = patchName.substr(0, patchName.size() - zsStrLength);
|
||||||
CPatchManager::unpack7Zip(patchName, outFilename);
|
unpack7Zip(patchName, outFilename);
|
||||||
pPM->deleteFile(patchName);
|
pPM->deleteFile(patchName);
|
||||||
pPM->renameFile(outFilename, sourceFullname);
|
pPM->renameFile(outFilename, sourceFullname);
|
||||||
}
|
}
|
||||||
|
@ -3449,7 +3414,7 @@ void CInstallThread::run()
|
||||||
std::string outFilename = patchName.substr(0, patchName.size() - zsStrLength);
|
std::string outFilename = patchName.substr(0, patchName.size() - zsStrLength);
|
||||||
std::string localOutFilename = CPath::standardizeDosPath(outFilename);
|
std::string localOutFilename = CPath::standardizeDosPath(outFilename);
|
||||||
|
|
||||||
if ( CPatchManager::unpackLZMA(patchName, localOutFilename) )
|
if ( unpackLZMA(patchName, localOutFilename) )
|
||||||
{
|
{
|
||||||
pPM->deleteFile(patchName);
|
pPM->deleteFile(patchName);
|
||||||
pPM->renameFile(outFilename, sourceName);
|
pPM->renameFile(outFilename, sourceName);
|
||||||
|
|
|
@ -331,10 +331,6 @@ private:
|
||||||
void clearDataScanLog();
|
void clearDataScanLog();
|
||||||
static void getCorruptedFileInfo(const SFileToPatch &ftp, ucstring &sTranslate);
|
static void getCorruptedFileInfo(const SFileToPatch &ftp, ucstring &sTranslate);
|
||||||
|
|
||||||
// utility func to decompress a monofile 7zip archive
|
|
||||||
static bool unpack7Zip(const std::string &sevenZipFile, const std::string &destFileName);
|
|
||||||
// utility func to decompress a single LZMA packed file
|
|
||||||
static bool unpackLZMA(const std::string &sevenZipFile, const std::string &destFileName);
|
|
||||||
static bool downloadAndUnpack(const std::string& patchPath, const std::string& sourceFilename, const std::string& extractPath, const std::string& tmpDirectory, uint32 timestamp);
|
static bool downloadAndUnpack(const std::string& patchPath, const std::string& sourceFilename, const std::string& extractPath, const std::string& tmpDirectory, uint32 timestamp);
|
||||||
// Forward message to Installation Software
|
// Forward message to Installation Software
|
||||||
void onFileInstallFinished();
|
void onFileInstallFinished();
|
||||||
|
|
|
@ -5,7 +5,7 @@ FILE(GLOB LIB_SRC *.cpp *.h)
|
||||||
LIST(REMOVE_ITEM LIB_SRC ${CMAKE_CURRENT_SOURCE_DIR}/7zMain.cpp)
|
LIST(REMOVE_ITEM LIB_SRC ${CMAKE_CURRENT_SOURCE_DIR}/7zMain.cpp)
|
||||||
|
|
||||||
NL_TARGET_LIB(ryzom_sevenzip ${LIB_SRC})
|
NL_TARGET_LIB(ryzom_sevenzip ${LIB_SRC})
|
||||||
# TARGET_LINK_LIBRARIES(ryzom_sevenzip ${PLATFORM_LINKFLAGS})
|
TARGET_LINK_LIBRARIES(ryzom_sevenzip nelmisc)
|
||||||
NL_DEFAULT_PROPS(ryzom_sevenzip "Ryzom, Library: Seven Zip")
|
NL_DEFAULT_PROPS(ryzom_sevenzip "Ryzom, Library: Seven Zip")
|
||||||
NL_ADD_RUNTIME_FLAGS(ryzom_sevenzip)
|
NL_ADD_RUNTIME_FLAGS(ryzom_sevenzip)
|
||||||
NL_ADD_LIB_SUFFIX(ryzom_sevenzip)
|
NL_ADD_LIB_SUFFIX(ryzom_sevenzip)
|
||||||
|
@ -14,11 +14,11 @@ ADD_DEFINITIONS(-DUNICODE -D_UNICODE -D_7ZIP_PPMD_SUPPPORT)
|
||||||
|
|
||||||
IF(WITH_PCH)
|
IF(WITH_PCH)
|
||||||
ADD_NATIVE_PRECOMPILED_HEADER(ryzom_sevenzip ${CMAKE_CURRENT_SOURCE_DIR}/Precomp.h ${CMAKE_CURRENT_SOURCE_DIR}/Precomp.cpp)
|
ADD_NATIVE_PRECOMPILED_HEADER(ryzom_sevenzip ${CMAKE_CURRENT_SOURCE_DIR}/Precomp.h ${CMAKE_CURRENT_SOURCE_DIR}/Precomp.cpp)
|
||||||
ENDIF(WITH_PCH)
|
ENDIF()
|
||||||
|
|
||||||
IF((WITH_INSTALL_LIBRARIES AND WITH_STATIC) OR NOT WITH_STATIC)
|
IF((WITH_INSTALL_LIBRARIES AND WITH_STATIC) OR NOT WITH_STATIC)
|
||||||
INSTALL(TARGETS ryzom_sevenzip LIBRARY DESTINATION ${RYZOM_LIB_PREFIX} ARCHIVE DESTINATION ${RYZOM_LIB_PREFIX} COMPONENT libraries)
|
INSTALL(TARGETS ryzom_sevenzip LIBRARY DESTINATION ${RYZOM_LIB_PREFIX} ARCHIVE DESTINATION ${RYZOM_LIB_PREFIX} COMPONENT libraries)
|
||||||
ENDIF((WITH_INSTALL_LIBRARIES AND WITH_STATIC) OR NOT WITH_STATIC)
|
ENDIF()
|
||||||
|
|
||||||
IF(WITH_RYZOM_TOOLS)
|
IF(WITH_RYZOM_TOOLS)
|
||||||
ADD_EXECUTABLE(7zDec ${CMAKE_CURRENT_SOURCE_DIR}/7zMain.cpp)
|
ADD_EXECUTABLE(7zDec ${CMAKE_CURRENT_SOURCE_DIR}/7zMain.cpp)
|
||||||
|
@ -28,4 +28,4 @@ IF(WITH_RYZOM_TOOLS)
|
||||||
NL_ADD_RUNTIME_FLAGS(7zDec)
|
NL_ADD_RUNTIME_FLAGS(7zDec)
|
||||||
|
|
||||||
INSTALL(TARGETS 7zDec RUNTIME DESTINATION ${RYZOM_BIN_PREFIX} COMPONENT tools)
|
INSTALL(TARGETS 7zDec RUNTIME DESTINATION ${RYZOM_BIN_PREFIX} COMPONENT tools)
|
||||||
ENDIF(WITH_RYZOM_TOOLS)
|
ENDIF()
|
||||||
|
|
357
code/ryzom/client/src/seven_zip/seven_zip.cpp
Normal file
357
code/ryzom/client/src/seven_zip/seven_zip.cpp
Normal file
|
@ -0,0 +1,357 @@
|
||||||
|
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2010 Winch Gate Property Limited
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include "seven_zip.h"
|
||||||
|
|
||||||
|
#include "nel/misc/types_nl.h"
|
||||||
|
#include "nel/misc/file.h"
|
||||||
|
#include "nel/misc/path.h"
|
||||||
|
|
||||||
|
#include "7z.h"
|
||||||
|
#include "7zAlloc.h"
|
||||||
|
#include "7zCrc.h"
|
||||||
|
#include "7zVersion.h"
|
||||||
|
#include "LzmaLib.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
//
|
||||||
|
// Namespaces
|
||||||
|
//
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace NLMISC;
|
||||||
|
|
||||||
|
|
||||||
|
/// Input stream class for 7zip archive
|
||||||
|
class CNel7ZipInStream : public ISeekInStream
|
||||||
|
{
|
||||||
|
NLMISC::IStream *_Stream;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// Constructor, only allow file stream because 7zip will 'seek' in the stream
|
||||||
|
CNel7ZipInStream(NLMISC::IStream *s)
|
||||||
|
: _Stream(s)
|
||||||
|
{
|
||||||
|
Read = readFunc;
|
||||||
|
Seek = seekFunc;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the read function called by 7zip to read data
|
||||||
|
static SRes readFunc(void *object, void *buffer, size_t *size)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
CNel7ZipInStream *me = (CNel7ZipInStream*)object;
|
||||||
|
uint len = (uint)*size;
|
||||||
|
me->_Stream->serialBuffer((uint8*)buffer, len);
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
return SZ_ERROR_READ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// the seek function called by seven zip to seek inside stream
|
||||||
|
static SRes seekFunc(void *object, Int64 *pos, ESzSeek origin)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
CNel7ZipInStream *me = (CNel7ZipInStream*)object;
|
||||||
|
sint32 offset = (sint32)*pos;
|
||||||
|
bool ret = me->_Stream->seek(offset, (NLMISC::IStream::TSeekOrigin)origin);
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
*pos = (Int64)me->_Stream->getPos();
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
return SZ_ERROR_READ;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
bool unpack7Zip(const std::string &sevenZipFile, const std::string &destFileName)
|
||||||
|
{
|
||||||
|
nlinfo("Uncompressing 7zip archive '%s' to '%s'", sevenZipFile.c_str(), destFileName.c_str());
|
||||||
|
|
||||||
|
// init seven zip
|
||||||
|
ISzAlloc allocImp;
|
||||||
|
allocImp.Alloc = SzAlloc;
|
||||||
|
allocImp.Free = SzFree;
|
||||||
|
|
||||||
|
ISzAlloc allocTempImp;
|
||||||
|
allocTempImp.Alloc = SzAllocTemp;
|
||||||
|
allocTempImp.Free = SzFreeTemp;
|
||||||
|
|
||||||
|
// wrap file in a CIFile
|
||||||
|
CIFile input(sevenZipFile);
|
||||||
|
CNel7ZipInStream inStr(&input);
|
||||||
|
|
||||||
|
CLookToRead lookStream;
|
||||||
|
lookStream.realStream = &inStr;
|
||||||
|
LookToRead_CreateVTable(&lookStream, False);
|
||||||
|
LookToRead_Init(&lookStream);
|
||||||
|
|
||||||
|
CrcGenerateTable();
|
||||||
|
|
||||||
|
CSzArEx db;
|
||||||
|
SzArEx_Init(&db);
|
||||||
|
|
||||||
|
// unpack the file using the 7zip API
|
||||||
|
SRes res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);
|
||||||
|
|
||||||
|
if (res != SZ_OK)
|
||||||
|
{
|
||||||
|
nlerror("Failed to open archive file %s", sevenZipFile.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (db.NumFiles != 1)
|
||||||
|
{
|
||||||
|
nlerror("Seven zip archive with more than 1 file are unsupported");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */
|
||||||
|
Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */
|
||||||
|
size_t outBufferSize = 0; /* it can have any value before first call (if outBuffer = 0) */
|
||||||
|
|
||||||
|
size_t offset;
|
||||||
|
size_t outSizeProcessed = 0;
|
||||||
|
|
||||||
|
// get the first file
|
||||||
|
res = SzArEx_Extract(&db, &lookStream.s, 0,
|
||||||
|
&blockIndex, &outBuffer, &outBufferSize,
|
||||||
|
&offset, &outSizeProcessed,
|
||||||
|
&allocImp, &allocTempImp);
|
||||||
|
|
||||||
|
// get the length of first file
|
||||||
|
size_t nameLen = SzArEx_GetFileNameUtf16(&db, 0, NULL);
|
||||||
|
|
||||||
|
ucstring filename;
|
||||||
|
filename.resize(nameLen);
|
||||||
|
|
||||||
|
// write filename into ucstring
|
||||||
|
SzArEx_GetFileNameUtf16(&db, 0, &filename[0]);
|
||||||
|
|
||||||
|
// write the extracted file
|
||||||
|
FILE *outputHandle = fopen(destFileName.c_str(), "wb+");
|
||||||
|
|
||||||
|
if (outputHandle == 0)
|
||||||
|
{
|
||||||
|
nlerror("Can not open output file '%s'", destFileName.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt32 processedSize = (UInt32)fwrite(outBuffer + offset, 1, outSizeProcessed, outputHandle);
|
||||||
|
|
||||||
|
if (processedSize != outSizeProcessed)
|
||||||
|
{
|
||||||
|
nlerror("Failed to write %u char to output file '%s'", outSizeProcessed-processedSize, destFileName.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(outputHandle);
|
||||||
|
|
||||||
|
IAlloc_Free(&allocImp, outBuffer);
|
||||||
|
|
||||||
|
// free 7z context
|
||||||
|
SzArEx_Free(&db, &allocImp);
|
||||||
|
|
||||||
|
// ok, all is fine, file is unpacked
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool unpackLZMA(const std::string &lzmaFile, const std::string &destFileName)
|
||||||
|
{
|
||||||
|
nldebug("unpackLZMA: decompress LZMA file '%s' to '%s", lzmaFile.c_str(), destFileName.c_str());
|
||||||
|
|
||||||
|
// open input file
|
||||||
|
CIFile inStream(lzmaFile);
|
||||||
|
uint32 inSize = inStream.getFileSize();
|
||||||
|
|
||||||
|
if (inSize < LZMA_PROPS_SIZE + 8)
|
||||||
|
{
|
||||||
|
nlwarning("unpackLZMA: Invalid file size, too small file '%s'", lzmaFile.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// allocate input buffer for props
|
||||||
|
auto_ptr<uint8> propsBuffer = auto_ptr<uint8>(new uint8[LZMA_PROPS_SIZE]);
|
||||||
|
|
||||||
|
// size of LZMA content
|
||||||
|
inSize -= LZMA_PROPS_SIZE + 8;
|
||||||
|
|
||||||
|
// allocate input buffer for lzma data
|
||||||
|
auto_ptr<uint8> inBuffer = auto_ptr<uint8>(new uint8[inSize]);
|
||||||
|
|
||||||
|
uint64 fileSize = 0;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// read props
|
||||||
|
inStream.serialBuffer(propsBuffer.get(), LZMA_PROPS_SIZE);
|
||||||
|
|
||||||
|
// read uncompressed size
|
||||||
|
inStream.serial(fileSize);
|
||||||
|
|
||||||
|
// read lzma content
|
||||||
|
inStream.serialBuffer(inBuffer.get(), inSize);
|
||||||
|
}
|
||||||
|
catch(const EReadError &e)
|
||||||
|
{
|
||||||
|
nlwarning("unpackLZMA: Error while reading '%s': %s", lzmaFile.c_str(), e.what());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// allocate the output buffer
|
||||||
|
auto_ptr<uint8> outBuffer = auto_ptr<uint8>(new uint8[fileSize]);
|
||||||
|
|
||||||
|
// in and out file sizes
|
||||||
|
SizeT outProcessed = (SizeT)fileSize;
|
||||||
|
SizeT inProcessed = (SizeT)inSize;
|
||||||
|
|
||||||
|
// decompress the file in memory
|
||||||
|
sint res = LzmaUncompress(outBuffer.get(), &outProcessed, inBuffer.get(), &inProcessed, propsBuffer.get(), LZMA_PROPS_SIZE);
|
||||||
|
|
||||||
|
if (res != 0 || outProcessed != fileSize)
|
||||||
|
{
|
||||||
|
nlwarning("unpackLZMA: Failed to decode lzma file '%s' with status %d", lzmaFile.c_str(), res);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// store on output buffer
|
||||||
|
COFile outStream(destFileName);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// write content
|
||||||
|
outStream.serialBuffer(outBuffer.get(), (uint)fileSize);
|
||||||
|
}
|
||||||
|
catch(const EFile &e)
|
||||||
|
{
|
||||||
|
nlwarning("unpackLZMA: Error while writing '%s': %s", destFileName.c_str(), e.what());
|
||||||
|
CFile::deleteFile(destFileName);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool packLZMA(const std::string &srcFileName, const std::string &lzmaFileName)
|
||||||
|
{
|
||||||
|
nldebug("packLZMA: compress '%s' to LZMA file '%s", srcFileName.c_str(), lzmaFileName.c_str());
|
||||||
|
|
||||||
|
// open file
|
||||||
|
CIFile inStream(srcFileName);
|
||||||
|
size_t inSize = inStream.getFileSize();
|
||||||
|
|
||||||
|
// file empty
|
||||||
|
if (!inSize)
|
||||||
|
{
|
||||||
|
nlwarning("packLZMA: File '%s' not found or empty", srcFileName.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// allocate input buffer
|
||||||
|
auto_ptr<uint8> inBuffer = auto_ptr<uint8>(new uint8[inSize]);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// read file in buffer
|
||||||
|
inStream.serialBuffer(inBuffer.get(), inSize);
|
||||||
|
}
|
||||||
|
catch(const EReadError &e)
|
||||||
|
{
|
||||||
|
nlwarning("packLZMA: Error while reading '%s': %s", srcFileName.c_str(), e.what());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// allocate output buffer
|
||||||
|
size_t outSize = (11 * inSize / 10) + 65536; // worst case = 1.1 * size + 64K
|
||||||
|
auto_ptr<uint8> outBuffer = auto_ptr<uint8>(new uint8[outSize]);
|
||||||
|
|
||||||
|
// allocate buffer for props
|
||||||
|
size_t outPropsSize = LZMA_PROPS_SIZE;
|
||||||
|
auto_ptr<uint8> outProps = auto_ptr<uint8>(new uint8[outPropsSize]);
|
||||||
|
|
||||||
|
// compress with best compression and other default settings
|
||||||
|
sint res = LzmaCompress(outBuffer.get(), &outSize, inBuffer.get(), inSize, outProps.get(), &outPropsSize, 9, 1 << 24, 3, 0, 2, 32, 1);
|
||||||
|
|
||||||
|
switch(res)
|
||||||
|
{
|
||||||
|
case SZ_OK:
|
||||||
|
{
|
||||||
|
// store on output buffer
|
||||||
|
COFile outStream(lzmaFileName);
|
||||||
|
|
||||||
|
// unable to create file
|
||||||
|
if (!outStream.isOpen())
|
||||||
|
{
|
||||||
|
nlwarning("packLZMA: Unable to create '%s'", srcFileName.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// write props
|
||||||
|
outStream.serialBuffer(outProps.get(), (uint)outPropsSize);
|
||||||
|
|
||||||
|
// write uncompressed size
|
||||||
|
uint64 uncompressSize = inSize;
|
||||||
|
outStream.serial(uncompressSize);
|
||||||
|
|
||||||
|
// write content
|
||||||
|
outStream.serialBuffer(outBuffer.get(), (uint)outSize);
|
||||||
|
}
|
||||||
|
catch(const EFile &e)
|
||||||
|
{
|
||||||
|
nlwarning("packLZMA: Error while writing '%s': %s", lzmaFileName.c_str(), e.what());
|
||||||
|
CFile::deleteFile(lzmaFileName);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SZ_ERROR_MEM:
|
||||||
|
nlwarning("packLZMA: Memory allocation error while compressing '%s' (input buffer size: %u, output buffer size: %u)", srcFileName.c_str(), (uint)inSize, (uint)outSize);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SZ_ERROR_PARAM:
|
||||||
|
nlwarning("packLZMA: Incorrect parameter while compressing '%s'", srcFileName.c_str());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SZ_ERROR_OUTPUT_EOF:
|
||||||
|
nlwarning("packLZMA: Output buffer overflow while compressing '%s' (input buffer size: %u, output buffer size: %u)", srcFileName.c_str(), (uint)inSize, (uint)outSize);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SZ_ERROR_THREAD:
|
||||||
|
nlwarning("packLZMA: Errors in multithreading functions (only for Mt version)");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
nlwarning("packLZMA: Unknown error (%d) while compressing '%s'", res, srcFileName.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
31
code/ryzom/client/src/seven_zip/seven_zip.h
Normal file
31
code/ryzom/client/src/seven_zip/seven_zip.h
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2010 Winch Gate Property Limited
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef SEVEN_ZIP_H
|
||||||
|
#define SEVEN_ZIP_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
// utility func to decompress a monofile 7zip archive
|
||||||
|
bool unpack7Zip(const std::string &sevenZipFileName, const std::string &destFileName);
|
||||||
|
|
||||||
|
// utility func to decompress a single LZMA packed file
|
||||||
|
bool unpackLZMA(const std::string &lzmaFileName, const std::string &destFileName);
|
||||||
|
|
||||||
|
// utility func to compress a single file to LZMA packed file
|
||||||
|
bool packLZMA(const std::string &srcFileName, const std::string &lzmaFileName);
|
||||||
|
|
||||||
|
#endif
|
358
code/ryzom/client/src/steam_client.cpp
Normal file
358
code/ryzom/client/src/steam_client.cpp
Normal file
|
@ -0,0 +1,358 @@
|
||||||
|
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2010 Winch Gate Property Limited
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "stdpch.h"
|
||||||
|
|
||||||
|
#ifdef RZ_USE_STEAM
|
||||||
|
|
||||||
|
#include "steam_client.h"
|
||||||
|
|
||||||
|
#include <steam_api.h>
|
||||||
|
|
||||||
|
// prototypes definitions for Steam API functions we'll call
|
||||||
|
typedef bool (__cdecl *SteamAPI_InitFuncPtr)();
|
||||||
|
typedef void (__cdecl *SteamAPI_RegisterCallbackFuncPtr)(class CCallbackBase *pCallback, int iCallback);
|
||||||
|
typedef void (__cdecl *SteamAPI_RunCallbacksFuncPtr)();
|
||||||
|
typedef void (__cdecl *SteamAPI_ShutdownFuncPtr)();
|
||||||
|
typedef void (__cdecl *SteamAPI_UnregisterCallbackFuncPtr)(class CCallbackBase *pCallback);
|
||||||
|
typedef ISteamUtils* (__cdecl *SteamUtilsFuncPtr)();
|
||||||
|
typedef ISteamUser* (__cdecl *SteamUserFuncPtr)();
|
||||||
|
typedef ISteamFriends* (__cdecl *SteamFriendsFuncPtr)();
|
||||||
|
|
||||||
|
// macros to simplify dynamic functions loading
|
||||||
|
#define NL_DECLARE_SYMBOL(symbol) symbol##FuncPtr nl##symbol = NULL
|
||||||
|
#define NL_LOAD_SYMBOL(symbol) nl##symbol = (symbol##FuncPtr)NLMISC::nlGetSymbolAddress(_Handle, #symbol)
|
||||||
|
|
||||||
|
NL_DECLARE_SYMBOL(SteamAPI_Init);
|
||||||
|
NL_DECLARE_SYMBOL(SteamFriends);
|
||||||
|
NL_DECLARE_SYMBOL(SteamUser);
|
||||||
|
NL_DECLARE_SYMBOL(SteamUtils);
|
||||||
|
NL_DECLARE_SYMBOL(SteamAPI_RegisterCallback);
|
||||||
|
NL_DECLARE_SYMBOL(SteamAPI_UnregisterCallback);
|
||||||
|
NL_DECLARE_SYMBOL(SteamAPI_RunCallbacks);
|
||||||
|
NL_DECLARE_SYMBOL(SteamAPI_Shutdown);
|
||||||
|
|
||||||
|
// taken from steam_api.h, we needed to change it to use our dynamically loaded functions
|
||||||
|
|
||||||
|
// Declares a callback member function plus a helper member variable which
|
||||||
|
// registers the callback on object creation and unregisters on destruction.
|
||||||
|
// The optional fourth 'var' param exists only for backwards-compatibility
|
||||||
|
// and can be ignored.
|
||||||
|
#define NL_STEAM_CALLBACK( thisclass, func, .../*callback_type, [deprecated] var*/ ) \
|
||||||
|
_NL_STEAM_CALLBACK_SELECT( ( __VA_ARGS__, 4, 3 ), ( /**/, thisclass, func, __VA_ARGS__ ) )
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// The following macros are implementation details, not intended for public use
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
#define _NL_STEAM_CALLBACK_AUTO_HOOK( thisclass, func, param )
|
||||||
|
#define _NL_STEAM_CALLBACK_HELPER( _1, _2, SELECTED, ... ) _NL_STEAM_CALLBACK_##SELECTED
|
||||||
|
#define _NL_STEAM_CALLBACK_SELECT( X, Y ) _NL_STEAM_CALLBACK_HELPER X Y
|
||||||
|
#define _NL_STEAM_CALLBACK_3( extra_code, thisclass, func, param ) \
|
||||||
|
struct CCallbackInternal_ ## func : private CSteamCallbackImpl< sizeof( param ) > { \
|
||||||
|
CCallbackInternal_ ## func () { extra_code nlSteamAPI_RegisterCallback( this, param::k_iCallback ); } \
|
||||||
|
CCallbackInternal_ ## func ( const CCallbackInternal_ ## func & ) { extra_code nlSteamAPI_RegisterCallback( this, param::k_iCallback ); } \
|
||||||
|
CCallbackInternal_ ## func & operator=( const CCallbackInternal_ ## func & ) { return *this; } \
|
||||||
|
private: virtual void Run( void *pvParam ) { _NL_STEAM_CALLBACK_AUTO_HOOK( thisclass, func, param ) \
|
||||||
|
thisclass *pOuter = reinterpret_cast<thisclass*>( reinterpret_cast<char*>(this) - offsetof( thisclass, m_steamcallback_ ## func ) ); \
|
||||||
|
pOuter->func( reinterpret_cast<param*>( pvParam ) ); \
|
||||||
|
} \
|
||||||
|
} m_steamcallback_ ## func ; void func( param *pParam )
|
||||||
|
#define _NL_STEAM_CALLBACK_4( _, thisclass, func, param, var ) \
|
||||||
|
CSteamCallback< thisclass, param > var; void func( param *pParam )
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: templated base for callbacks - internal implementation detail
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
template< int sizeof_P >
|
||||||
|
class CSteamCallbackImpl : protected CCallbackBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
~CSteamCallbackImpl() { if ( m_nCallbackFlags & k_ECallbackFlagsRegistered ) nlSteamAPI_UnregisterCallback( this ); }
|
||||||
|
void SetGameserverFlag() { m_nCallbackFlags |= k_ECallbackFlagsGameServer; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void Run( void *pvParam ) = 0;
|
||||||
|
virtual void Run( void *pvParam, bool /*bIOFailure*/, SteamAPICall_t /*hSteamAPICall*/ ) { Run( pvParam ); }
|
||||||
|
virtual int GetCallbackSizeBytes() { return sizeof_P; }
|
||||||
|
};
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: maps a steam callback to a class member function
|
||||||
|
// template params: T = local class, P = parameter struct,
|
||||||
|
// bGameserver = listen for gameserver callbacks instead of client callbacks
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
template< class T, class P, bool bGameserver = false >
|
||||||
|
class CSteamCallback : public CSteamCallbackImpl< sizeof( P ) >
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef void (T::*func_t)(P*);
|
||||||
|
|
||||||
|
// NOTE: If you can't provide the correct parameters at construction time, you should
|
||||||
|
// use the CCallbackManual callback object (STEAM_CALLBACK_MANUAL macro) instead.
|
||||||
|
CSteamCallback( T *pObj, func_t func ) : m_pObj( NULL ), m_Func( NULL )
|
||||||
|
{
|
||||||
|
if ( bGameserver )
|
||||||
|
{
|
||||||
|
this->SetGameserverFlag();
|
||||||
|
}
|
||||||
|
Register( pObj, func );
|
||||||
|
}
|
||||||
|
|
||||||
|
// manual registration of the callback
|
||||||
|
void Register( T *pObj, func_t func )
|
||||||
|
{
|
||||||
|
if ( !pObj || !func )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( this->m_nCallbackFlags & CCallbackBase::k_ECallbackFlagsRegistered )
|
||||||
|
Unregister();
|
||||||
|
|
||||||
|
m_pObj = pObj;
|
||||||
|
m_Func = func;
|
||||||
|
// SteamAPI_RegisterCallback sets k_ECallbackFlagsRegistered
|
||||||
|
nlSteamAPI_RegisterCallback( this, P::k_iCallback );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Unregister()
|
||||||
|
{
|
||||||
|
// SteamAPI_UnregisterCallback removes k_ECallbackFlagsRegistered
|
||||||
|
nlSteamAPI_UnregisterCallback( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void Run( void *pvParam )
|
||||||
|
{
|
||||||
|
(m_pObj->*m_Func)( (P *)pvParam );
|
||||||
|
}
|
||||||
|
|
||||||
|
T *m_pObj;
|
||||||
|
func_t m_Func;
|
||||||
|
};
|
||||||
|
|
||||||
|
// listener called by Steam when AuthSessionTicket is available
|
||||||
|
class CAuthSessionTicketListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CAuthSessionTicketListener():_AuthSessionTicketResponse(this, &CAuthSessionTicketListener::OnAuthSessionTicketResponse)
|
||||||
|
{
|
||||||
|
_AuthSessionTicketHandle = 0;
|
||||||
|
_AuthSessionTicketSize = 0;
|
||||||
|
|
||||||
|
_AuthSessionTicketCallbackCalled = false;
|
||||||
|
_AuthSessionTicketCallbackError = false;;
|
||||||
|
_AuthSessionTicketCallbackTimeout = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait until a ticket is available or return if no ticket received after specified ms
|
||||||
|
bool waitTicket(uint32 ms)
|
||||||
|
{
|
||||||
|
// call Steam method
|
||||||
|
_AuthSessionTicketHandle = nlSteamUser()->GetAuthSessionTicket(_AuthSessionTicketData, sizeof(_AuthSessionTicketData), &_AuthSessionTicketSize);
|
||||||
|
|
||||||
|
nldebug("GetAuthSessionTicket returned %u bytes, handle %u", _AuthSessionTicketSize, _AuthSessionTicketHandle);
|
||||||
|
|
||||||
|
nlinfo("Waiting for Steam GetAuthSessionTicket callback...");
|
||||||
|
|
||||||
|
// define expiration time
|
||||||
|
NLMISC::TTime expirationTime = NLMISC::CTime::getLocalTime() + ms;
|
||||||
|
|
||||||
|
// wait until callback method is called or expiration
|
||||||
|
while(!_AuthSessionTicketCallbackCalled && !_AuthSessionTicketCallbackTimeout)
|
||||||
|
{
|
||||||
|
// call registered callbacks
|
||||||
|
nlSteamAPI_RunCallbacks();
|
||||||
|
|
||||||
|
// check if expired
|
||||||
|
if (NLMISC::CTime::getLocalTime() > expirationTime)
|
||||||
|
_AuthSessionTicketCallbackTimeout = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// expired
|
||||||
|
if (_AuthSessionTicketCallbackTimeout)
|
||||||
|
{
|
||||||
|
nlwarning("GetAuthSessionTicket callback never called");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
nlinfo("GetAuthSessionTicket called");
|
||||||
|
|
||||||
|
// got an error
|
||||||
|
if (_AuthSessionTicketCallbackError)
|
||||||
|
{
|
||||||
|
nlwarning("GetAuthSessionTicket callback returned error");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return ticket if available in hexadecimal
|
||||||
|
std::string getTicket() const
|
||||||
|
{
|
||||||
|
// if expired or error, ticket is not available
|
||||||
|
if (!_AuthSessionTicketCallbackCalled || _AuthSessionTicketCallbackError || _AuthSessionTicketCallbackTimeout) return "";
|
||||||
|
|
||||||
|
std::string authSessionTicket;
|
||||||
|
|
||||||
|
// optimize string by allocating the final string size
|
||||||
|
authSessionTicket.reserve(_AuthSessionTicketSize*2);
|
||||||
|
|
||||||
|
// convert buffer to hexadecimal string
|
||||||
|
for (uint32 i = 0; i < _AuthSessionTicketSize; ++i)
|
||||||
|
{
|
||||||
|
authSessionTicket += NLMISC::toString("%02x", _AuthSessionTicketData[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return authSessionTicket;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// ticket handle
|
||||||
|
HAuthTicket _AuthSessionTicketHandle;
|
||||||
|
|
||||||
|
// buffer of ticket data
|
||||||
|
uint8 _AuthSessionTicketData[1024];
|
||||||
|
|
||||||
|
// size of buffer
|
||||||
|
uint32 _AuthSessionTicketSize;
|
||||||
|
|
||||||
|
// different states of callback
|
||||||
|
bool _AuthSessionTicketCallbackCalled;
|
||||||
|
bool _AuthSessionTicketCallbackError;
|
||||||
|
bool _AuthSessionTicketCallbackTimeout;
|
||||||
|
|
||||||
|
// callback declaration
|
||||||
|
NL_STEAM_CALLBACK(CAuthSessionTicketListener, OnAuthSessionTicketResponse, GetAuthSessionTicketResponse_t, _AuthSessionTicketResponse);
|
||||||
|
};
|
||||||
|
|
||||||
|
// method called by Steam
|
||||||
|
void CAuthSessionTicketListener::OnAuthSessionTicketResponse(GetAuthSessionTicketResponse_t *inCallback)
|
||||||
|
{
|
||||||
|
_AuthSessionTicketCallbackCalled = true;
|
||||||
|
|
||||||
|
if (inCallback->m_eResult != k_EResultOK)
|
||||||
|
{
|
||||||
|
_AuthSessionTicketCallbackError = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CSteamClient::CSteamClient():_Handle(NULL), _Initialized(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CSteamClient::~CSteamClient()
|
||||||
|
{
|
||||||
|
release();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSteamClient::init()
|
||||||
|
{
|
||||||
|
std::string filename;
|
||||||
|
|
||||||
|
#if defined(NL_OS_WIN64)
|
||||||
|
filename = "steam_api64.dll";
|
||||||
|
#elif defined(NL_OS_WINDOWS)
|
||||||
|
filename = "steam_api.dll";
|
||||||
|
#elif defined(NL_OS_MAC)
|
||||||
|
filename = "libsteam_api.dylib";
|
||||||
|
#else
|
||||||
|
filename = "libsteam_api.so";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// try to load library
|
||||||
|
_Handle = NLMISC::nlLoadLibrary(filename);
|
||||||
|
|
||||||
|
if (!_Handle)
|
||||||
|
{
|
||||||
|
nlwarning("Unable to load Steam client");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
NL_LOAD_SYMBOL(SteamAPI_Init);
|
||||||
|
|
||||||
|
// check if function was found
|
||||||
|
if (!nlSteamAPI_Init)
|
||||||
|
{
|
||||||
|
nlwarning("Unable to get a pointer on SteamAPI_Init");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// initialize Steam API
|
||||||
|
if (!nlSteamAPI_Init())
|
||||||
|
{
|
||||||
|
nlwarning("Unable to initialize Steam client");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_Initialized = true;
|
||||||
|
|
||||||
|
// load more functions
|
||||||
|
NL_LOAD_SYMBOL(SteamFriends);
|
||||||
|
NL_LOAD_SYMBOL(SteamUser);
|
||||||
|
NL_LOAD_SYMBOL(SteamUtils);
|
||||||
|
NL_LOAD_SYMBOL(SteamAPI_Shutdown);
|
||||||
|
|
||||||
|
bool loggedOn = nlSteamUser()->BLoggedOn();
|
||||||
|
|
||||||
|
nlinfo("Steam AppID: %u", nlSteamUtils()->GetAppID());
|
||||||
|
nlinfo("Steam login: %s", nlSteamFriends()->GetPersonaName());
|
||||||
|
nlinfo("Steam user logged: %s", loggedOn ? "yes":"no");
|
||||||
|
|
||||||
|
// don't need to continue, if not connected
|
||||||
|
if (!loggedOn) return false;
|
||||||
|
|
||||||
|
// load symbols used by AuthSessionTicket
|
||||||
|
NL_LOAD_SYMBOL(SteamAPI_RegisterCallback);
|
||||||
|
NL_LOAD_SYMBOL(SteamAPI_UnregisterCallback);
|
||||||
|
NL_LOAD_SYMBOL(SteamAPI_RunCallbacks);
|
||||||
|
|
||||||
|
CAuthSessionTicketListener listener;
|
||||||
|
|
||||||
|
// wait 5 seconds to get ticket
|
||||||
|
if (!listener.waitTicket(5000)) return false;
|
||||||
|
|
||||||
|
// save ticket
|
||||||
|
_AuthSessionTicket = listener.getTicket();
|
||||||
|
|
||||||
|
nldebug("Auth ticket: %s", _AuthSessionTicket.c_str());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSteamClient::release()
|
||||||
|
{
|
||||||
|
if (!_Handle) return false;
|
||||||
|
|
||||||
|
if (_Initialized)
|
||||||
|
{
|
||||||
|
// only shutdown Steam if initialized
|
||||||
|
nlSteamAPI_Shutdown();
|
||||||
|
|
||||||
|
_Initialized = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// free Steam library from memory
|
||||||
|
bool res = NLMISC::nlFreeLibrary(_Handle);
|
||||||
|
|
||||||
|
_Handle = NULL;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
65
code/ryzom/client/src/steam_client.h
Normal file
65
code/ryzom/client/src/steam_client.h
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2010 Winch Gate Property Limited
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef CL_STEAM_CLIENT_H
|
||||||
|
#define CL_STEAM_CLIENT_H
|
||||||
|
|
||||||
|
#include "nel/misc/types_nl.h"
|
||||||
|
#include "nel/misc/dynloadlib.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Steam API helper to be able to call Steam functions/methods without linking to any library.
|
||||||
|
* The library is dynamically loaded and is optional.
|
||||||
|
*
|
||||||
|
* \author Cedric 'Kervala' OCHS
|
||||||
|
* \date 2016
|
||||||
|
*/
|
||||||
|
class CSteamClient
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CSteamClient();
|
||||||
|
~CSteamClient();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dynamically load Steam client library and functions pointers.
|
||||||
|
* Also retrieve authentication session ticket if available.
|
||||||
|
* If no authentication session ticket retrieved, returns false.
|
||||||
|
*/
|
||||||
|
bool init();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shutdown Steam client and unload library.
|
||||||
|
*/
|
||||||
|
bool release();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the authentication session ticket if available.
|
||||||
|
*/
|
||||||
|
std::string getAuthSessionTicket() const { return _AuthSessionTicket; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
// handle on Steam DLL
|
||||||
|
NLMISC::NL_LIB_HANDLE _Handle;
|
||||||
|
|
||||||
|
// true if succeeded to initialize (must call shutdown)
|
||||||
|
bool _Initialized;
|
||||||
|
|
||||||
|
// the retrieved authentication session ticket
|
||||||
|
std::string _AuthSessionTicket;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -3,7 +3,6 @@ FILE(GLOB SRC main.cpp
|
||||||
${CMAKE_SOURCE_DIR}/ryzom/client/src/user_agent.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/client_cfg.cpp
|
||||||
${CMAKE_SOURCE_DIR}/ryzom/client/src/login_patch.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/login_xdelta.cpp
|
||||||
${CMAKE_SOURCE_DIR}/ryzom/client/src/stdpch.cpp
|
${CMAKE_SOURCE_DIR}/ryzom/client/src/stdpch.cpp
|
||||||
${CMAKE_SOURCE_DIR}/ryzom/client/src/stdpch.h
|
${CMAKE_SOURCE_DIR}/ryzom/client/src/stdpch.h
|
||||||
|
@ -17,6 +16,7 @@ ADD_EXECUTABLE(khanat_client_patcher ${SRC})
|
||||||
INCLUDE_DIRECTORIES(
|
INCLUDE_DIRECTORIES(
|
||||||
${LIBXML2_INCLUDE_DIR}
|
${LIBXML2_INCLUDE_DIR}
|
||||||
${CURL_INCLUDE_DIRS}
|
${CURL_INCLUDE_DIRS}
|
||||||
|
${ZLIB_INCLUDE_DIR}
|
||||||
${CMAKE_SOURCE_DIR}/ryzom/client/src
|
${CMAKE_SOURCE_DIR}/ryzom/client/src
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
#include "stdpch.h"
|
#include "stdpch.h"
|
||||||
#include "login_patch.h"
|
#include "login_patch.h"
|
||||||
#include "client_cfg.h"
|
#include "client_cfg.h"
|
||||||
|
#include "user_agent.h"
|
||||||
|
|
||||||
|
#include "nel/misc/cmd_args.h"
|
||||||
|
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
|
|
||||||
#ifdef NL_OS_WINDOWS
|
#ifdef NL_OS_WINDOWS
|
||||||
|
@ -28,7 +32,8 @@ string VersionName;
|
||||||
string LoginLogin, LoginPassword;
|
string LoginLogin, LoginPassword;
|
||||||
uint32 LoginShardId = 0xFFFFFFFF;
|
uint32 LoginShardId = 0xFFFFFFFF;
|
||||||
|
|
||||||
bool useUtf8 = false;
|
CCmdArgs Args;
|
||||||
|
|
||||||
bool useEsc = false;
|
bool useEsc = false;
|
||||||
|
|
||||||
#ifdef NL_OS_WINDOWS
|
#ifdef NL_OS_WINDOWS
|
||||||
|
@ -38,9 +43,6 @@ sint attributes = 0;
|
||||||
|
|
||||||
std::string convert(const ucstring &str)
|
std::string convert(const ucstring &str)
|
||||||
{
|
{
|
||||||
if (useUtf8)
|
|
||||||
return str.toUtf8();
|
|
||||||
|
|
||||||
return str.toString();
|
return str.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,29 +93,13 @@ void printDownload(const std::string &str)
|
||||||
// temporary modified string
|
// temporary modified string
|
||||||
std::string nstr = str;
|
std::string nstr = str;
|
||||||
|
|
||||||
uint length = 0;
|
uint length = (uint)nstr.length();
|
||||||
|
|
||||||
if (useUtf8)
|
|
||||||
{
|
|
||||||
ucstring ucstr;
|
|
||||||
ucstr.fromUtf8(nstr);
|
|
||||||
length = (uint)ucstr.length();
|
|
||||||
if (length > maxLength)
|
|
||||||
{
|
|
||||||
ucstr = ucstr.luabind_substr(length - maxLength + 3);
|
|
||||||
nstr = std::string("...") + ucstr.toUtf8();
|
|
||||||
length = maxLength;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
length = (uint)nstr.length();
|
|
||||||
if (length > maxLength)
|
if (length > maxLength)
|
||||||
{
|
{
|
||||||
nstr = std::string("...") + nstr.substr(length - maxLength + 3);
|
nstr = std::string("...") + nstr.substr(length - maxLength + 3);
|
||||||
length = maxLength;
|
length = maxLength;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// add padding with spaces
|
// add padding with spaces
|
||||||
memset(spaces, ' ', maxLength);
|
memset(spaces, ' ', maxLength);
|
||||||
|
@ -142,11 +128,65 @@ void printDownload(const std::string &str)
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// hardcoded english translations to not depends on external files
|
||||||
|
struct CClientPatcherTranslations : public NLMISC::CI18N::ILoadProxy
|
||||||
|
{
|
||||||
|
virtual void loadStringFile(const std::string &filename, ucstring &text)
|
||||||
|
{
|
||||||
|
text.fromUtf8(
|
||||||
|
"TheSagaOfRyzom [Ryzom]\n"
|
||||||
|
"uiErrPatchApply [Error: Patch process ended but the patch has not been successfully applied.]\n"
|
||||||
|
"uiErrChecking [Error: Patch files failed - checking.]\n"
|
||||||
|
"uiKb [KiB]\n"
|
||||||
|
"uiMb [MiB]\n"
|
||||||
|
"uiLoginGetFile [Getting File:]\n"
|
||||||
|
"uiDLWithCurl [Downloading File With Curl:]\n"
|
||||||
|
"uiDecompressing [Decompressing File:]\n"
|
||||||
|
"uiCheckInt [Checking Integrity:]\n"
|
||||||
|
"uiNoVersionFound [No Version Found]\n"
|
||||||
|
"uiVersionFound [Version Found:]\n"
|
||||||
|
"uiApplyingDelta [Applying Delta:]\n"
|
||||||
|
"uiClientVersion [Client Version]\n"
|
||||||
|
"uiServerVersion [Server Version]\n"
|
||||||
|
"uiCheckingFile [Checking File]\n"
|
||||||
|
"uiNeededPatches [Required Patches:]\n"
|
||||||
|
"uiCheckInBNP [Checking inside BNP:]\n"
|
||||||
|
"uiSHA1Diff [Force BNP Unpacking: checksums do not correspond:]\n"
|
||||||
|
"uiCheckEndNoErr [Checking file ended with no errors]\n"
|
||||||
|
"uiCheckEndWithErr [Checking file ended with errors:]\n"
|
||||||
|
"uiPatchEndNoErr [Patching file ended with no errors]\n"
|
||||||
|
"uiPatchEndWithErr [Patch failed!]\n"
|
||||||
|
"uiPatchDiskFull [Disk full!]\n"
|
||||||
|
"uiPatchWriteError [Disk write error! (disk full?)]\n"
|
||||||
|
"uiProcessing [Processing file:]\n"
|
||||||
|
"uiUnpack [BNP Unpacking:]\n"
|
||||||
|
"uiUnpackErrHead [Cannot read bnp header:]\n"
|
||||||
|
"uiChangeDate [Changing the mod date:]\n"
|
||||||
|
"uiChgDateErr [Cannot change file time:]\n"
|
||||||
|
"uiNowDate [Now the date is:]\n"
|
||||||
|
"uiSetAttrib [Set file attributes:]\n"
|
||||||
|
"uiAttribErr [Cannot have read/write access:]\n"
|
||||||
|
"uiDelFile [Delete file:]\n"
|
||||||
|
"uiDelErr [Cannot delete file:]\n"
|
||||||
|
"uiDelNoFile [Delete file (no file)]\n"
|
||||||
|
"uiRenameFile [Rename File:]\n"
|
||||||
|
"uiRenameErr [Cannot rename file:]\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
// init the Nel context
|
// init the Nel context
|
||||||
CApplicationContext appContext;
|
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
|
// create logs in temporary directory
|
||||||
createDebug(CPath::getTemporaryDirectory().c_str(), true, true);
|
createDebug(CPath::getTemporaryDirectory().c_str(), true, true);
|
||||||
|
|
||||||
|
@ -177,11 +217,6 @@ int main(int argc, char *argv[])
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if console supports utf-8
|
|
||||||
std::string lang = toLower(std::string(setlocale(LC_CTYPE, "")));
|
|
||||||
useUtf8 = (lang.find("utf8") != string::npos || lang.find("utf-8") != string::npos);
|
|
||||||
lang = lang.substr(0, 2);
|
|
||||||
|
|
||||||
// check if console supports colors
|
// check if console supports colors
|
||||||
std::string term = toLower(std::string(getenv("TERM") ? getenv("TERM"):""));
|
std::string term = toLower(std::string(getenv("TERM") ? getenv("TERM"):""));
|
||||||
useEsc = (term.find("xterm") != string::npos || term.find("linux") != string::npos);
|
useEsc = (term.find("xterm") != string::npos || term.find("linux") != string::npos);
|
||||||
|
@ -209,70 +244,23 @@ int main(int argc, char *argv[])
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set default paths
|
// allocate translations proxy
|
||||||
std::string dataPath = "./data/";
|
CClientPatcherTranslations *trans = new CClientPatcherTranslations();
|
||||||
std::string rootPath = "./";
|
|
||||||
|
|
||||||
// use custom data path if specified
|
// use proxy
|
||||||
if (!ClientCfg.DataPath.empty())
|
CI18N::setLoadProxy(trans);
|
||||||
{
|
|
||||||
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");
|
// load english translations
|
||||||
|
CI18N::load("en");
|
||||||
|
|
||||||
// check if user can write in data directory
|
// now translations are read, we don't need it anymore
|
||||||
if (!CFile::isExists(unpackPath))
|
delete trans;
|
||||||
{
|
|
||||||
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);
|
|
||||||
|
|
||||||
printf("Checking %s files to patch...\n", convert(CI18N::get("TheSagaOfRyzom")).c_str());
|
printf("Checking %s files to patch...\n", convert(CI18N::get("TheSagaOfRyzom")).c_str());
|
||||||
|
|
||||||
// initialize patch manager and set the ryzom full path, before it's used
|
// initialize patch manager and set the ryzom full path, before it's used
|
||||||
CPatchManager *pPM = CPatchManager::getInstance();
|
CPatchManager *pPM = CPatchManager::getInstance();
|
||||||
|
|
||||||
// set the correct root path
|
|
||||||
pPM->setClientRootPath(rootPath);
|
|
||||||
|
|
||||||
// use PatchUrl
|
// use PatchUrl
|
||||||
vector<string> patchURLs;
|
vector<string> patchURLs;
|
||||||
pPM->init(patchURLs, ClientCfg.PatchUrl, ClientCfg.PatchVersion);
|
pPM->init(patchURLs, ClientCfg.PatchUrl, ClientCfg.PatchVersion);
|
||||||
|
@ -385,6 +373,8 @@ int main(int argc, char *argv[])
|
||||||
printError(convert(CI18N::get("uiErrPatchApply")) + " " + error);
|
printError(convert(CI18N::get("uiErrPatchApply")) + " " + error);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pPM->executeBatchFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -4,6 +4,7 @@ FILE(GLOB SRC *.cpp *.h)
|
||||||
ADD_LIBRARY(georges_dll SHARED ${SRC} georges_edit.rc)
|
ADD_LIBRARY(georges_dll SHARED ${SRC} georges_edit.rc)
|
||||||
|
|
||||||
INCLUDE_DIRECTORIES(${NEL_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
|
INCLUDE_DIRECTORIES(${NEL_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR})
|
||||||
|
|
||||||
TARGET_LINK_LIBRARIES(georges_dll nelmisc nelgeorges)
|
TARGET_LINK_LIBRARIES(georges_dll nelmisc nelgeorges)
|
||||||
NL_DEFAULT_PROPS(georges_dll "Ryzom, Tools, Georges: Georges Dll")
|
NL_DEFAULT_PROPS(georges_dll "Ryzom, Tools, Georges: Georges Dll")
|
||||||
|
|
|
@ -8,6 +8,8 @@ SET(CMAKE_MFC_FLAG 2)
|
||||||
|
|
||||||
ADD_EXECUTABLE(world_editor WIN32 ${SRC} world_editor.rc)
|
ADD_EXECUTABLE(world_editor WIN32 ${SRC} world_editor.rc)
|
||||||
|
|
||||||
|
INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR})
|
||||||
|
|
||||||
SOURCE_GROUP(Resources FILES world_editor.rc)
|
SOURCE_GROUP(Resources FILES world_editor.rc)
|
||||||
|
|
||||||
TARGET_LINK_LIBRARIES(world_editor
|
TARGET_LINK_LIBRARIES(world_editor
|
||||||
|
|
|
@ -110,6 +110,7 @@
|
||||||
|
|
||||||
extern bool DontUse3D;
|
extern bool DontUse3D;
|
||||||
|
|
||||||
|
#include <libxml/parser.h>
|
||||||
|
|
||||||
//{{AFX_INSERT_LOCATION}}
|
//{{AFX_INSERT_LOCATION}}
|
||||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
|
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/ryzom/client/src/seven_zip)
|
||||||
|
|
||||||
SET(MAIN_SRC patch_gen_common.cpp patch_gen_main.cpp patch_gen_main.h)
|
SET(MAIN_SRC patch_gen_common.cpp patch_gen_main.cpp patch_gen_main.h)
|
||||||
SET(SERVICE_SRC patch_gen_common.cpp patch_gen_service.cpp patch_gen_service.h)
|
SET(SERVICE_SRC patch_gen_common.cpp patch_gen_service.cpp patch_gen_service.h)
|
||||||
|
|
||||||
ADD_EXECUTABLE(patch_gen ${MAIN_SRC})
|
ADD_EXECUTABLE(patch_gen ${MAIN_SRC})
|
||||||
TARGET_LINK_LIBRARIES(patch_gen ryzom_gameshare nelmisc nelnet nelligo nelgeorges)
|
TARGET_LINK_LIBRARIES(patch_gen ryzom_sevenzip ryzom_gameshare nelmisc nelnet nelligo nelgeorges)
|
||||||
NL_DEFAULT_PROPS(patch_gen "Ryzom, Tools: Patch Generator")
|
NL_DEFAULT_PROPS(patch_gen "Ryzom, Tools: Patch Generator")
|
||||||
NL_ADD_RUNTIME_FLAGS(patch_gen)
|
NL_ADD_RUNTIME_FLAGS(patch_gen)
|
||||||
|
|
||||||
ADD_EXECUTABLE(patch_gen_service WIN32 ${SERVICE_SRC})
|
ADD_EXECUTABLE(patch_gen_service WIN32 ${SERVICE_SRC})
|
||||||
TARGET_LINK_LIBRARIES(patch_gen_service ryzom_gameshare nelmisc nelnet nelligo nelgeorges)
|
TARGET_LINK_LIBRARIES(patch_gen_service ryzom_sevenzip ryzom_gameshare nelmisc nelnet nelligo nelgeorges)
|
||||||
NL_DEFAULT_PROPS(patch_gen_service "Ryzom, Tools: Patch Generator Service")
|
NL_DEFAULT_PROPS(patch_gen_service "Ryzom, Tools: Patch Generator Service")
|
||||||
NL_ADD_RUNTIME_FLAGS(patch_gen_service)
|
NL_ADD_RUNTIME_FLAGS(patch_gen_service)
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "nel/misc/command.h"
|
#include "nel/misc/command.h"
|
||||||
#include "nel/misc/sstring.h"
|
#include "nel/misc/sstring.h"
|
||||||
#include "game_share/singleton_registry.h"
|
#include "game_share/singleton_registry.h"
|
||||||
|
#include "seven_zip.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace NLMISC;
|
using namespace NLMISC;
|
||||||
|
@ -74,37 +75,16 @@ void ApplyPatch(const std::string& srcFileName,const std::string& destFileName,c
|
||||||
#endif // NL_OS_WINDOWS
|
#endif // NL_OS_WINDOWS
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenerateLZMA(const std::string sourceFile, const std::string &outputFile)
|
void GenerateLZMA(const std::string &sourceFile, const std::string &outputFile)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
// old syntax incompatible with new versions
|
nlinfo("Compressing %s to %s using LZMA...", sourceFile.c_str(), outputFile.c_str());
|
||||||
std::string cmd = "lzma e";
|
|
||||||
cmd += " " + sourceFile + " " + outputFile;
|
|
||||||
nlinfo("Executing system command: %s", cmd.c_str());
|
|
||||||
}
|
}
|
||||||
#ifdef NL_OS_WINDOWS
|
|
||||||
_spawnlp(_P_WAIT, "lzma.exe","lzma.exe", "e", sourceFile.c_str(), outputFile.c_str(), NULL);
|
|
||||||
#else // NL_OS_WINDOWS
|
|
||||||
// new lzma only supports one file name on command line, so make a copy
|
|
||||||
CFile::copyFile(outputFile, sourceFile);
|
|
||||||
|
|
||||||
// new lzma syntax, -z = compress, -9 = best compression
|
if (!packLZMA(sourceFile, outputFile))
|
||||||
std::string cmd = NLMISC::toString("lzma -z -9 %s", outputFile.c_str());
|
|
||||||
|
|
||||||
sint error = system(cmd.c_str());
|
|
||||||
|
|
||||||
if (error)
|
|
||||||
{
|
{
|
||||||
nlwarning("'%s' failed with error code %d", cmd.c_str(), error);
|
nlwarning("LZMA compress failed");
|
||||||
|
|
||||||
CFile::deleteFile(outputFile);
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
// lzma always append a .lzma extension, so rename compressed file to wanted one
|
|
||||||
CFile::moveFile(outputFile, outputFile + ".lzma");
|
|
||||||
}
|
|
||||||
#endif // NL_OS_WINDOWS
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -1417,11 +1417,11 @@ uiErrPatchApply [Fehler : Patchprozess beendet, aber der Patch konnte nicht erfo
|
||||||
// INDEX 353
|
// INDEX 353
|
||||||
uiErrChecking [Fehler : Patchdateien versagen - Überprüfung.]
|
uiErrChecking [Fehler : Patchdateien versagen - Überprüfung.]
|
||||||
|
|
||||||
// HASH_VALUE 40D0242C40D0242C
|
// HASH_VALUE 8E9280411622E45F
|
||||||
// INDEX 354
|
// INDEX 354
|
||||||
uiKb [KB]
|
uiKb [KB]
|
||||||
|
|
||||||
// HASH_VALUE 4050243440502434
|
// HASH_VALUE 90B288459762EC61
|
||||||
// INDEX 355
|
// INDEX 355
|
||||||
uiMb [MB]
|
uiMb [MB]
|
||||||
|
|
||||||
|
@ -27271,3 +27271,11 @@ uiRadarUseCamera [Radar folgt der Kamera-Rotation.]
|
||||||
// INDEX 6466
|
// INDEX 6466
|
||||||
uittRadarUseCamera [Wenn aktiviert, wird die Kamera-Rotation für die Radar-Ansicht eingeschaltet.]
|
uittRadarUseCamera [Wenn aktiviert, wird die Kamera-Rotation für die Radar-Ansicht eingeschaltet.]
|
||||||
|
|
||||||
|
// HASH_VALUE 82A1901C06A3F72E
|
||||||
|
// INDEX 6467
|
||||||
|
uiTotalPatch [GESAMTER PATCH]
|
||||||
|
|
||||||
|
// HASH_VALUE D091B40C4890BC25
|
||||||
|
// INDEX 6468
|
||||||
|
uiRequiredFiles [BENÖTIGTE DATEIEN]
|
||||||
|
|
||||||
|
|
|
@ -1415,13 +1415,13 @@ uiErrPatchApply [Error: Patch process ended but the patch has not been successfu
|
||||||
// INDEX 353
|
// INDEX 353
|
||||||
uiErrChecking [Error: Patch files failed - checking.]
|
uiErrChecking [Error: Patch files failed - checking.]
|
||||||
|
|
||||||
// HASH_VALUE 40D0242C40D0242C
|
// HASH_VALUE 8E9280411622E45F
|
||||||
// INDEX 354
|
// INDEX 354
|
||||||
uiKb [KB]
|
uiKb [KiB]
|
||||||
|
|
||||||
// HASH_VALUE 4050243440502434
|
// HASH_VALUE 90B288459762EC61
|
||||||
// INDEX 355
|
// INDEX 355
|
||||||
uiMb [MB]
|
uiMb [MiB]
|
||||||
|
|
||||||
// HASH_VALUE 9FA5A06DD895B637
|
// HASH_VALUE 9FA5A06DD895B637
|
||||||
// INDEX 356
|
// INDEX 356
|
||||||
|
@ -27237,3 +27237,27 @@ uiRadarUseCamera [Radar follows camera rotation]
|
||||||
// INDEX 6466
|
// INDEX 6466
|
||||||
uittRadarUseCamera [If checked, use camera rotation for radar view.]
|
uittRadarUseCamera [If checked, use camera rotation for radar view.]
|
||||||
|
|
||||||
|
// HASH_VALUE 82A1901C06A3F72E
|
||||||
|
// INDEX 6467
|
||||||
|
uiTotalPatch [TOTAL PATCH]
|
||||||
|
|
||||||
|
// HASH_VALUE D091B40C4890BC25
|
||||||
|
// INDEX 6468
|
||||||
|
uiRequiredFiles [REQUIRED FILES]
|
||||||
|
|
||||||
|
// HASH_VALUE 8C42E02F0C01D422
|
||||||
|
// INDEX 6469
|
||||||
|
uiLodValue [NORMAL]
|
||||||
|
|
||||||
|
// HASH_VALUE 6878DC2CC23A6CB6
|
||||||
|
// INDEX 6470
|
||||||
|
uiDebugProfileFillRate [Profile Fillrate]
|
||||||
|
|
||||||
|
// HASH_VALUE 0F54678C93B4CBF6
|
||||||
|
// INDEX 6471
|
||||||
|
uiFixedMissionEntry_Mainland_Unknwown [Main land / Unknown]
|
||||||
|
|
||||||
|
// HASH_VALUE CAB123089C80B66B
|
||||||
|
// INDEX 6472
|
||||||
|
uiNoFiles [No Files...]
|
||||||
|
|
||||||
|
|
|
@ -1416,13 +1416,13 @@ uiErrPatchApply [Error: Proceso de Parcheado finalize pero el parche no ha sido
|
||||||
// INDEX 353
|
// INDEX 353
|
||||||
uiErrChecking [Error: Archivos del Parcheado han fallado - revisando.]
|
uiErrChecking [Error: Archivos del Parcheado han fallado - revisando.]
|
||||||
|
|
||||||
// HASH_VALUE 40D0242C40D0242C
|
// HASH_VALUE 8E9280411622E45F
|
||||||
// INDEX 354
|
// INDEX 354
|
||||||
uiKb [KB]
|
uiKb [KiB]
|
||||||
|
|
||||||
// HASH_VALUE 4050243440502434
|
// HASH_VALUE 90B288459762EC61
|
||||||
// INDEX 355
|
// INDEX 355
|
||||||
uiMb [MB]
|
uiMb [MiB]
|
||||||
|
|
||||||
// HASH_VALUE 9FA5A06DD895B637
|
// HASH_VALUE 9FA5A06DD895B637
|
||||||
// INDEX 356
|
// INDEX 356
|
||||||
|
@ -27297,3 +27297,11 @@ uiRadarUseCamera [El radar sigue la rotación de la cámara]
|
||||||
// INDEX 6466
|
// INDEX 6466
|
||||||
uittRadarUseCamera [Si marcado, usar la rotación de cámara para la vista de radar.]
|
uittRadarUseCamera [Si marcado, usar la rotación de cámara para la vista de radar.]
|
||||||
|
|
||||||
|
// HASH_VALUE 82A1901C06A3F72E
|
||||||
|
// INDEX 6467
|
||||||
|
uiTotalPatch [PARCHE TOTAL]
|
||||||
|
|
||||||
|
// HASH_VALUE D091B40C4890BC25
|
||||||
|
// INDEX 6468
|
||||||
|
uiRequiredFiles [ARCHIVOS NECESARIOS]
|
||||||
|
|
||||||
|
|
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
|
@ -1445,13 +1445,13 @@ uiErrPatchApply [Error : Patch process ended but the patch has not been successf
|
||||||
// INDEX 353
|
// INDEX 353
|
||||||
uiErrChecking [Error : Checking for patch files failed]
|
uiErrChecking [Error : Checking for patch files failed]
|
||||||
|
|
||||||
// HASH_VALUE 40D0242C40D0242C
|
// HASH_VALUE 8E9280411622E45F
|
||||||
// INDEX 354
|
// INDEX 354
|
||||||
uiKb [KB]
|
uiKb [KiB]
|
||||||
|
|
||||||
// HASH_VALUE 4050243440502434
|
// HASH_VALUE 90B288459762EC61
|
||||||
// INDEX 355
|
// INDEX 355
|
||||||
uiMb [MB]
|
uiMb [MiB]
|
||||||
|
|
||||||
// HASH_VALUE 9FA5A06DD895B637
|
// HASH_VALUE 9FA5A06DD895B637
|
||||||
// INDEX 356
|
// INDEX 356
|
||||||
|
@ -27455,3 +27455,27 @@ uiRadarUseCamera [Radar follows camera rotation]
|
||||||
// INDEX 6466
|
// INDEX 6466
|
||||||
uittRadarUseCamera [If checked, use camera rotation for radar view.]
|
uittRadarUseCamera [If checked, use camera rotation for radar view.]
|
||||||
|
|
||||||
|
// HASH_VALUE 82A1901C06A3F72E
|
||||||
|
// INDEX 6467
|
||||||
|
uiTotalPatch [TOTAL PATCH]
|
||||||
|
|
||||||
|
// HASH_VALUE D091B40C4890BC25
|
||||||
|
// INDEX 6468
|
||||||
|
uiRequiredFiles [REQUIRED FILES]
|
||||||
|
|
||||||
|
// HASH_VALUE 8C42E02F0C01D422
|
||||||
|
// INDEX 6469
|
||||||
|
uiLodValue [NORMAL]
|
||||||
|
|
||||||
|
// HASH_VALUE 6878DC2CC23A6CB6
|
||||||
|
// INDEX 6470
|
||||||
|
uiDebugProfileFillRate [Profile Fillrate]
|
||||||
|
|
||||||
|
// HASH_VALUE 0F54678C93B4CBF6
|
||||||
|
// INDEX 6471
|
||||||
|
uiFixedMissionEntry_Mainland_Unknwown [Main land / Unknown]
|
||||||
|
|
||||||
|
// HASH_VALUE CAB123089C80B66B
|
||||||
|
// INDEX 6472
|
||||||
|
uiNoFiles [No Files...]
|
||||||
|
|
||||||
|
|
|
@ -753,9 +753,9 @@ uiErrPatchApply [Error : Patch process ended but the patch has not been successf
|
||||||
|
|
||||||
uiErrChecking [Error : Checking for patch files failed]
|
uiErrChecking [Error : Checking for patch files failed]
|
||||||
|
|
||||||
uiKb [KB]
|
uiKb [KiB]
|
||||||
|
|
||||||
uiMb [MB]
|
uiMb [MiB]
|
||||||
|
|
||||||
uiLoginGetFile [Getting File :]
|
uiLoginGetFile [Getting File :]
|
||||||
uiDLFailed [Download from emergency server failed, patching is aborted]
|
uiDLFailed [Download from emergency server failed, patching is aborted]
|
||||||
|
@ -13454,3 +13454,13 @@ uiShowClock12h [Use 12-hour clock]
|
||||||
uittShowClock12h [If checked, use 12-hour clock in compass and in chat messages.]
|
uittShowClock12h [If checked, use 12-hour clock in compass and in chat messages.]
|
||||||
uiRadarUseCamera [Radar follows camera rotation]
|
uiRadarUseCamera [Radar follows camera rotation]
|
||||||
uittRadarUseCamera [If checked, use camera rotation for radar view.]
|
uittRadarUseCamera [If checked, use camera rotation for radar view.]
|
||||||
|
uiTotalPatch [TOTAL PATCH]
|
||||||
|
uiRequiredFiles [REQUIRED FILES]
|
||||||
|
// default value for LOD in login screen
|
||||||
|
uiLodValue [NORMAL]
|
||||||
|
// option displayed in keys configuration (Debug section)
|
||||||
|
uiDebugProfileFillRate [Profile Fillrate]
|
||||||
|
// displayed in mission window when continent is unknown
|
||||||
|
uiFixedMissionEntry_Mainland_Unknwown [Main land / Unknown]
|
||||||
|
// displayed when no files are playing in MP3 player
|
||||||
|
uiNoFiles [No Files...]
|
||||||
|
|
1
code/tool/CMakeLists.txt
Normal file
1
code/tool/CMakeLists.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
ADD_SUBDIRECTORY(bin2c)
|
8
code/tool/bin2c/CMakeLists.txt
Normal file
8
code/tool/bin2c/CMakeLists.txt
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
FILE(GLOB SRC *.cpp *.h)
|
||||||
|
|
||||||
|
ADD_EXECUTABLE(bin2c ${SRC})
|
||||||
|
|
||||||
|
NL_DEFAULT_PROPS(bin2c "Tools: bin2c")
|
||||||
|
NL_ADD_RUNTIME_FLAGS(bin2c)
|
||||||
|
|
||||||
|
INSTALL(TARGETS bin2c RUNTIME DESTINATION ${NL_BIN_PREFIX} COMPONENT tools)
|
|
@ -14,9 +14,6 @@
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
// bin2c.cpp : Defines the entry point for the console application.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -25,22 +22,55 @@ int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
if (argc<2)
|
if (argc<2)
|
||||||
{
|
{
|
||||||
printf ("bin2c [filename.bin] [filename.c]\n");
|
printf ("bin2c <filename.bin> [filename.c]\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char sDir[256];
|
// path and filename but without extension
|
||||||
char sPath[256];
|
char sPathWithoutExtension[256];
|
||||||
|
|
||||||
|
// basename of file
|
||||||
char sName[256];
|
char sName[256];
|
||||||
char sExt[256];
|
|
||||||
_splitpath (argv[1], sDir, sPath, sName, sExt);
|
// copy fullpath from command-line
|
||||||
|
strcpy(sPathWithoutExtension, argv[1]);
|
||||||
|
|
||||||
|
char *tmpExt = strrchr(sPathWithoutExtension, '.');
|
||||||
|
|
||||||
|
// remove extension
|
||||||
|
if (tmpExt) *tmpExt = 0;
|
||||||
|
|
||||||
|
// look for last directory separator
|
||||||
|
const char *tmpName1 = strrchr(sPathWithoutExtension, '/');
|
||||||
|
#ifdef _WIN32
|
||||||
|
const char *tmpName2 = strrchr(sPathWithoutExtension, '\\');
|
||||||
|
#else
|
||||||
|
const char *tmpName2 = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// take last separator
|
||||||
|
const char *tmpName = tmpName1 > tmpName2 ? tmpName1:tmpName2;
|
||||||
|
|
||||||
|
// keep only path
|
||||||
|
if (tmpName)
|
||||||
|
{
|
||||||
|
// computes position in path
|
||||||
|
size_t pos = tmpName - sPathWithoutExtension;
|
||||||
|
|
||||||
|
// copy basename
|
||||||
|
strcpy(sName, sPathWithoutExtension+pos+1);
|
||||||
|
}
|
||||||
|
|
||||||
char sOutput[256];
|
char sOutput[256];
|
||||||
|
|
||||||
if (argc>2)
|
if (argc>2)
|
||||||
|
{
|
||||||
strcpy (sOutput, argv[2]);
|
strcpy (sOutput, argv[2]);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_makepath (sOutput, sDir, sPath, sName, ".cpp");
|
strcpy(sOutput, sPathWithoutExtension);
|
||||||
|
strcat(sOutput, ".cpp");
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE *pIn=fopen( argv[1], "rb");
|
FILE *pIn=fopen( argv[1], "rb");
|
||||||
|
|
Loading…
Reference in a new issue