merge from compatibility-develop

This commit is contained in:
SIELA1915 2016-02-12 18:28:23 +01:00
parent 3cd8969cd7
commit f5459a1b9b
54 changed files with 2992 additions and 1742 deletions

View file

@ -269,10 +269,6 @@ IF(WITH_QT5)
# Gui
SET(QT_LIBRARIES ${QT_LIBRARIES} Qt5::Gui Qt5::OpenGL)
IF(WIN32)
SET(QT_LIBRARIES ${QT_LIBRARIES} Qt5::WinExtras)
ENDIF()
ADD_QT_LIBRARY(PrintSupport)
IF(WIN32)
@ -390,10 +386,6 @@ IF(WITH_QT5)
ENDIF()
ELSE()
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()
ELSE()
MESSAGE(WARNING "Unable to find Qt 5")

View 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()

View file

@ -258,6 +258,7 @@ MACRO(NL_SETUP_DEFAULT_OPTIONS)
OPTION(WITH_NELNS "Build NeL Network Services." OFF)
OPTION(WITH_RYZOM "Build Ryzom Core." ON )
OPTION(WITH_SNOWBALLS "Build Snowballs." OFF)
OPTION(WITH_TOOLS "Build Tools" OFF)
ENDMACRO(NL_SETUP_DEFAULT_OPTIONS)
MACRO(NL_SETUP_NEL_DEFAULT_OPTIONS)
@ -1083,15 +1084,15 @@ MACRO(SETUP_EXTERNAL)
IF(APPLE)
IF(WITH_STATIC_EXTERNAL)
SET(CMAKE_FIND_LIBRARY_SUFFIXES .a)
ELSE(WITH_STATIC_EXTERNAL)
ELSE()
SET(CMAKE_FIND_LIBRARY_SUFFIXES .dylib .so .a)
ENDIF(WITH_STATIC_EXTERNAL)
ENDIF()
ELSE(APPLE)
IF(WITH_STATIC_EXTERNAL)
SET(CMAKE_FIND_LIBRARY_SUFFIXES .a .so)
ELSE(WITH_STATIC_EXTERNAL)
ELSE()
SET(CMAKE_FIND_LIBRARY_SUFFIXES .so .a)
ENDIF(WITH_STATIC_EXTERNAL)
ENDIF()
ENDIF(APPLE)
ENDIF(WIN32)

View file

@ -336,6 +336,10 @@ void itoaInt64 (sint64 number, char *str, sint64 base = 10);
std::string bytesToHumanReadable (const std::string &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
uint32 humanReadableToBytes (const std::string &str);

View file

@ -230,7 +230,7 @@ public:
/** Get application directory.
* \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.
* \return temporary directory where applications should write files.
@ -540,7 +540,7 @@ public:
/** Get application directory.
* \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.
* \return temporary directory where applications should write files.

View file

@ -246,27 +246,38 @@ inline bool fromString(const std::string &str, bool &val)
{
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;
}
else if (str[0] == '0')
{
break;
case '0':
case 'f':
case 'F':
case 'n':
case 'N':
val = false;
}
else
{
break;
default:
val = false;
return false;
}
}
else
{
if (str == "true")
if (str == "true" || str == "yes")
{
val = true;
}
else if (str == "false")
else if (str == "false" || str == "no")
{
val = false;
}

View file

@ -715,7 +715,7 @@ SOURCE_GROUP(Stereo FILES
NL_TARGET_LIB(nel3d ${HEADERS} ${SRC})
INCLUDE_DIRECTORIES(BEFORE ${FREETYPE_INCLUDE_DIRS})
INCLUDE_DIRECTORIES(${FREETYPE_INCLUDE_DIRS})
INCLUDE_DIRECTORIES(${LIBVR_INCLUDE_DIR})
TARGET_LINK_LIBRARIES(nel3d nelmisc ${FREETYPE_LIBRARIES} ${LIBOVR_LIBRARIES} ${LIBVR_LIBRARY})

View file

@ -380,7 +380,26 @@ string bytesToHumanReadable (uint64 bytes)
div++;
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)
@ -394,7 +413,8 @@ uint32 humanReadableToBytes (const string &str)
if(str[0]<'0' || str[0]>'9')
return 0;
res = atoi (str.c_str());
if (!fromString(str, res))
return 0;
if(str[str.size()-1] == 'B')
{
@ -404,10 +424,28 @@ uint32 humanReadableToBytes (const string &str)
// there's no break and it's **normal**
switch (str[str.size()-2])
{
case 'G': res *= 1024;
case 'M': res *= 1024;
case 'K': res *= 1024;
default: ;
// 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 'M': res *= 1024;
case 'K': res *= 1024;
default: ;
}
}
default: ;
}
}
@ -694,8 +732,22 @@ bool launchProgram(const std::string &programName, const std::string &arguments,
SetEnvironmentVariable( SE_TRANSLATOR_IN_MAIN_MODULE, NULL );
}
string arg = " " + arguments;
BOOL res = CreateProcessA(programName.c_str(), (char*)arg.c_str(), NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE | CREATE_NO_WINDOW, NULL, NULL, &si, &pi);
const char *sProgramName = programName.c_str();
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)
{
@ -716,25 +768,13 @@ bool launchProgram(const std::string &programName, const std::string &arguments,
}
#elif defined(NL_OS_MAC)
std::string command;
// we need to open bundles with "open" command
std::string command = NLMISC::toString("open \"%s\"", programName.c_str());
if (CFile::getExtension(programName) == "app")
// append arguments if any
if (!arguments.empty())
{
// we need to open bundles with "open" command
command = NLMISC::toString("open \"%s\"", programName.c_str());
// append arguments if any
if (!arguments.empty())
{
command += NLMISC::toString(" --args %s", arguments.c_str());
}
}
else
{
command = programName;
// append arguments if any
if (!arguments.empty()) command += " " + arguments;
command += NLMISC::toString(" --args %s", arguments.c_str());
}
int res = system(command.c_str());
@ -838,8 +878,22 @@ sint launchProgramAndWaitForResult(const std::string &programName, const std::st
SetEnvironmentVariable( SE_TRANSLATOR_IN_MAIN_MODULE, NULL );
}
string arg = " " + arguments;
BOOL ok = CreateProcessA(programName.c_str(), (char*)arg.c_str(), NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE | CREATE_NO_WINDOW, NULL, NULL, &si, &pi);
const char *sProgramName = programName.c_str();
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)
{

View file

@ -260,7 +260,7 @@ void CLog::displayString (const char *str)
TempArgs.FileName = _FileName;
TempArgs.Line = _Line;
TempArgs.FuncName = _FuncName;
TempArgs.CallstackAndLog = "";
TempArgs.CallstackAndLog.clear();
TempString = str;
}
@ -281,7 +281,7 @@ void CLog::displayString (const char *str)
localargs.FileName = _FileName;
localargs.Line = _Line;
localargs.FuncName = _FuncName;
localargs.CallstackAndLog = "";
localargs.CallstackAndLog.clear();
disp = str;
args = &localargs;
@ -314,7 +314,7 @@ void CLog::displayString (const char *str)
(*idi)->display( *args, disp );
}
}
TempString = "";
TempString.clear();
unsetPosition();
}

View file

@ -1777,19 +1777,29 @@ std::string CFileContainer::getWindowsDirectory()
#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())
{
#ifdef NL_OS_WINDOWS
wchar_t buffer[MAX_PATH];
SHGetSpecialFolderPathW(NULL, buffer, CSIDL_APPDATA, TRUE);
#ifdef CSIDL_LOCAL_APPDATA
if (local)
{
SHGetSpecialFolderPathW(NULL, buffer, CSIDL_LOCAL_APPDATA, TRUE);
}
else
#endif
{
SHGetSpecialFolderPathW(NULL, buffer, CSIDL_APPDATA, TRUE);
}
appPath = CPath::standardizePath(ucstring((ucchar*)buffer).toUtf8());
#elif defined(NL_OS_MAC)
appPath = CPath::standardizePath(getenv("HOME"));
@ -2568,13 +2578,13 @@ std::string CPath::makePathAbsolute( const std::string &relativePath, const std:
{
absolutePath = relativePath;
}
#else
// Unix filesystem absolute path
else
#endif
// Unix filesystem absolute path (works also under Windows)
if (relativePath[0] == '/')
{
absolutePath = relativePath;
}
#endif
else
{
// 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
absolutePath += relativePath;
absolutePath = standardizePath(absolutePath, true);
}
absolutePath = standardizePath(absolutePath, true);
if (simplify)
{
// split all components path to manage parent directories
std::vector<std::string> tokens;
explode(absolutePath, std::string("/"), tokens, true);
explode(absolutePath, std::string("/"), tokens, false);
std::vector<std::string> directoryParts;
@ -2639,7 +2650,10 @@ std::string CPath::makePathAbsolute( const std::string &relativePath, const std:
// rebuild the whole absolute path
for(uint i = 1, len = directoryParts.size(); i < len; ++i)
absolutePath += "/" + directoryParts[i];
{
if (!directoryParts[i].empty())
absolutePath += "/" + directoryParts[i];
}
// add trailing slash
absolutePath += "/";

View file

@ -555,7 +555,7 @@ string CSheetId::toString(bool ifNotFoundUseNumericId) const
}
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 );
}
}

View file

@ -136,7 +136,7 @@ else:
needUpdateBnp = needUpdateDirNoSubdirFile(log, sourcePath, targetBnp)
if (needUpdateBnp):
printLog(log, "BNP " + targetBnp)
subprocess.call([ BnpMake, "/p", sourcePath, targetPath ] + package[1])
subprocess.call([ BnpMake, "-p", sourcePath, "-o", targetBnp ] + package[1][1:])
else:
printLog(log, "SKIP " + targetBnp)
printLog(log, "")

View file

@ -134,8 +134,8 @@ int main(int argc, char **argv)
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("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("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("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)", false);
args.addAdditionalArg("input", "Input directory or BNP file depending on command");
if (!args.parse(argc, argv)) return 1;

View file

@ -114,6 +114,20 @@ int main(int argc, char *argv[])
// init Nel context
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;
try

View file

@ -19,6 +19,7 @@
#include "ut_misc_co_task.h"
#include "ut_misc_command.h"
#include "ut_misc_common.h"
#include "ut_misc_config_file.h"
#include "ut_misc_debug.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 CUTMiscCommand));
add(auto_ptr<Test::Suite>(new CUTMiscCommon));
add(auto_ptr<Test::Suite>(new CUTMiscConfigFile));
add(auto_ptr<Test::Suite>(new CUTMiscDebug));
add(auto_ptr<Test::Suite>(new CUTMiscDynLibLoad));

View 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

View file

@ -444,11 +444,13 @@ struct CUTMiscStringCommon : public Test::Suite
// min limit -1, unable to compare with minimum value because no lower type
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
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
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
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
ret = NLMISC::fromString("1.2", val);
@ -682,60 +685,59 @@ struct CUTMiscStringCommon : public Test::Suite
// tests for bool
bool val;
// true value
val = false;
// true values
ret = NLMISC::fromString("1", val);
TEST_ASSERT(val);
TEST_ASSERT_MSG(ret, "should succeed");
TEST_ASSERT(ret && val);
val = false;
NLMISC::fromString("t", val);
TEST_ASSERT(val);
ret = NLMISC::fromString("t", val);
TEST_ASSERT(ret && val);
val = false;
NLMISC::fromString("y", val);
TEST_ASSERT(val);
ret = NLMISC::fromString("y", val);
TEST_ASSERT(ret && val);
val = false;
NLMISC::fromString("T", val);
TEST_ASSERT(val);
ret = NLMISC::fromString("T", val);
TEST_ASSERT(ret && val);
val = false;
NLMISC::fromString("Y", val);
TEST_ASSERT(val);
ret = NLMISC::fromString("Y", val);
TEST_ASSERT(ret && 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);
TEST_ASSERT(!val);
TEST_ASSERT_MSG(ret, "should succeed");
TEST_ASSERT(ret && !val);
val = true;
NLMISC::fromString("f", val);
TEST_ASSERT(!val);
ret = NLMISC::fromString("f", val);
TEST_ASSERT(ret && !val);
val = true;
NLMISC::fromString("n", val);
TEST_ASSERT(!val);
ret = NLMISC::fromString("n", val);
TEST_ASSERT(ret && !val);
val = true;
NLMISC::fromString("F", val);
TEST_ASSERT(!val);
ret = NLMISC::fromString("F", val);
TEST_ASSERT(ret && !val);
val = true;
NLMISC::fromString("N", val);
TEST_ASSERT(!val);
ret = NLMISC::fromString("N", val);
TEST_ASSERT(ret && !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);
TEST_ASSERT_MSG(!ret, "should not succeed");
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");
TEST_ASSERT(!ret && !val);
}
};

View file

@ -3,7 +3,6 @@ ADD_SUBDIRECTORY(src)
IF(WITH_RYZOM_CLIENT)
#ADD_SUBDIRECTORY(data)
#ADD_SUBDIRECTORY(patcher)
IF(UNIX AND NOT APPLE)
ADD_SUBDIRECTORY(unix)

View file

@ -265,7 +265,7 @@
fontsize="10"
line_maxw="182"
shadow="true"
hardtext="No File..." />
hardtext="uiNoFiles" />
</group>
</group>
<tree node="mp3_player" />

View file

@ -183,7 +183,7 @@
posref="BL BL"
scale="true"
y="4"
w="110"
w="130"
h="2"
texture="W_line_hor2.tga" />
<view type="text"
@ -202,7 +202,7 @@
posref="MM MM"
x="0"
y="-1"
w="110"
w="130"
h="8"
vertical="false"
align="L"
@ -246,7 +246,7 @@
posref="BL BL"
scale="true"
y="4"
w="110"
w="130"
h="2"
texture="W_line_hor2.tga" />
<view type="text"
@ -265,7 +265,7 @@
posref="MM MM"
x="0"
y="-1"
w="110"
w="130"
h="8"
vertical="false"
align="L"
@ -3441,7 +3441,7 @@
widget="sbint"
link="UI:SAVE:CHAT:FONT_SIZE"
min="9"
max="14"
max="20"
realtime="true" />
<param ui="entity_colors:cc_user:c"
type="db"

View file

@ -24,7 +24,7 @@
<group id="checkpass" posref="MM MM" w="1024" h="768" active="false"
<group id="checkpass" posref="MM MM" w="1024" h="768" active="false"
on_active="init_res_lod" on_deactive="uninit_res_lod" >
<group id="content" x="0" y="0" w="1024" h="768" posref="TL TL" >
@ -32,35 +32,35 @@
<!-- BACKGROUND -->
<view type="bitmap" posref="TL TL" id="bl" texture="new_launcher_bg.tga" global_color="false" render_layer="-1" />
<instance template="log_box" id="window" y="-8" posref="MM MM" w="1024" h="768" color="0 0 0 0"/>
<!--
<view type="bitmap" id="jena" posparent="window" posref="MR MR" x="-64" texture="log_jena.tga" global_color="false" render_layer="-1" />
-->
<!-- Login Edit_Boxes -->
<view type="text" id="txt_log" x="0" posref="TM TM" posparent="window" hardtext="uiLogin" fontsize="10" y="-200" color="255 255 255 255" />
<view type="text" id="txt_pas" posparent="txt_log" posref="TM TM" hardtext="uiPassword" fontsize="10" y="-48" color="255 255 255 255" />
<instance template="edit_box_log" id="eb_login" posparent="txt_log" posref="BM TM" w="240" h="24" fontsize="12" x="0" y="-4"
text_ref="BM BM" text_y="-2"
reset_focus_on_hide="false" max_historic="0"
onenter="set_keyboard_focus" params="target=ui:login:checkpass:content:submit_gr:eb_password:eb|select_all=false"
prompt="" enter_loose_focus="true" multi_line="false" max_num_chars="12" color="135 243 28 255" />
<instance template="edit_box_log" id="eb_password" posparent="txt_pas" posref="BM TM" w="240" h="24" fontsize="14" x="0" y="-4"
text_ref="BM BM" text_y="-2"
reset_focus_on_hide="false" max_historic="0" entry_type="password"
onenter="on_login" params=""
prompt="" enter_loose_focus="true" multi_line="false" max_num_chars="20" color="135 243 28 255" />
<ctrl style="log_std_but" id="but_log" posparent="eb_password" posref="TM TM" y="-32" onclick_l="on_login" hardtext="uiOnConnect" />
<!-- Boxes Web Shortcuts
<!-- Boxes Web Shortcuts
<instance template="server_box" id="web_win" posparent="eb_login" posref="BL TL" w="568" h="202" y="-24" /> -->
<!-- Create Account -->
<ctrl style="log_std_but" id="but_create_account" posparent="but_log" posref="BM TM" y="-28"
<ctrl style="log_std_but" id="but_create_account" posparent="but_log" posref="BM TM" y="-28"
onclick_l="on_create_account" hardtext="uiCreateAccount" />
<!-- Edit Account -->
@ -73,23 +73,23 @@
<!-- Forget Password -->
<ctrl style="log_std_but" id="but_forget_pwd" posparent="but_edit_account" posref="BM TM" y="-8"
onclick_l="open_url" params_l="cfg_ForgetPwdURL" hardtext="uiForgetPwd" />
<!-- Free Trial
onclick_l="open_url" params_l="cfg_ForgetPwdURL" hardtext="uiForgetPwd" />
<!-- Free Trial
<ctrl style="log_spe_but" id="but_free_trial" posparent="but_forget_pwd" posref="BL TL" y="-8"
onclick_l="open_url" params_l="cfg_FreeTrialURL" hardtext="uiFreeTrial" />
-->
<!-- Login Support -->
<ctrl style="log_std_but" id="but_login_support" posparent="but_forget_pwd" posref="BM TM" y="-8"
onclick_l="open_url" params_l="cfg_LoginSupportURL" hardtext="uiLoginSupport" />
<!-- Scan Data -->
<!--
<ctrl style="log_spe_but" id="but_scan_data" posparent="but_login_support" posref="BL TL" y="-8"
onclick_l="on_scan_data_start" hardtext="uiScanData" />
<link expr="@UI:VARIABLES:DISPLAY_ACCOUNT_BUTTONS" target=" but_game_configuration:active,
<link expr="@UI:VARIABLES:DISPLAY_ACCOUNT_BUTTONS" target=" but_game_configuration:active,
but_create_account:active,
but_edit_account:active,
but_forget_pwd:active,
@ -101,10 +101,10 @@
<link expr="@UI:VARIABLES:DISPLAY_ACCOUNT_BUTTONS" target=" but_create_account:active,
but_upgrade_account:active,
but_forget_pwd:active,
but_game_configuration:active,
but_game_configuration:active,
but_edit_account:active,
but_login_support:active" />
<!-- RESOLUTION ET LEVEL OF DETAILS -->
<instance template="server_box" id="res_win" posparent="window" posref="TL TL" w="276" h="24" y="-733" x="10"/>
<instance template="server_box" id="lod_win" posparent="res_win" posref="TR TL" w="276" h="24" x="16" />
@ -120,7 +120,7 @@
<view type="text" id="lod_value" posparent="lod_win" posref="MM MM" y="-2" color="135 243 28 255" fontsize="10" shadow="true" hardtext="uiLodValue" />
<!-- Boutons Res -->
<!-- Boutons Res -->
<ctrl type="button" button_type="push_button" id="less_res_but" posparent="res_win" posref="ML ML" x="8" y="0"
tx_normal="but_left.tga" tx_pushed="but_left.tga" tx_over="but_left.tga"
color="135 243 28 128" col_over="135 243 28 255" col_pushed="135 243 28 255"
@ -131,7 +131,7 @@
color="135 243 28 128" col_over="135 243 28 255" col_pushed="135 243 28 255"
onclick_l="more_res" params_l="" />
<!-- Boutons LoD -->
<!-- Boutons LoD -->
<ctrl type="button" button_type="push_button" id="less_lod_but" posparent="lod_win" posref="ML ML" x="8" y="0"
tx_normal="but_left.tga" tx_pushed="but_left.tga" tx_over="but_left.tga"
color="135 243 28 128" col_over="135 243 28 255" col_pushed="135 243 28 255"
@ -180,35 +180,35 @@
<group id="sharddisp" posref="MM MM" w="1024" h="768" active="false" on_enter="login_connect">
<group id="content" x="0" y="0" w="1024" h="768" posref="TL TL" >
<!-- BACKGROUND -->
<view type="bitmap" posref="TL TL" id="bl" texture="new_launcher_bg.tga" global_color="false" render_layer="-2" />
<instance template="log_box" id="window" y="-8" posref="MM MM" w="800" h="440" />
<view type="bitmap" id="kami" posparent="window" posref="TR TR" x="-50" y="-24" texture="log_kami.tga" global_color="false" render_layer="-1" />
<!-- EXIT BUTTON -->
<ctrl style="log_button" id="but_exit" posparent="window" posref="TR TR" y="-20" onclick_l="login_quit" hardtext="uiExitLogin" />
<!-- SERVER SELECTION -->
<instance template="server_box" id="server_win" posparent="window" posref="ML ML" w="612" h="338" x="8" y="0" />
<group id="shard_list" posparent="server_win" posref="TM TM" y="-4" w="604" child_resize_h="true" max_sizeparent="parent" max_sizeref="w" max_w="-18" max_h="330" >
</group>
<!-- scroll bar -->
<instance template="bk_scroll" id="back_scrollbar" posparent="server_win" posref="TR TL" x="4" w="24" sizeref="h" h="0" />
<ctrl style="skin_scroll" id="scroll_bar" align="T" target="shard_list" posparent="server_win" posref="TR TL" target_stepy="22" x="8" y="0" />
<!-- Connect Button -->
<ctrl style="log_std_but" id="but_log" posparent="server_win" posref="BM TM" y="-8" onclick_l="login_connect" hardtext="uiOnConnect" />
<!-- Table Infos -->
<instance template="log_box_frame" id="infos_win" posparent="server_win" posref="TL BL" w="612" h="22" y="4" />
<view type="text" id="status_txt" posref="BL BM" x="376" y="1" posparent="infos_win" fontsize="10" color="255 255 255 255" hardtext="uiOnStatus" shadow="true" />
<view type="text" id="version_txt" posref="BL BM" x="456" y="1" posparent="infos_win" fontsize="10" color="255 255 255 255" hardtext="uiOnVersion" shadow="true" />
<view type="text" id="release_txt" posref="BL BM" x="544" y="1" posparent="infos_win" fontsize="10" color="255 255 255 255" hardtext="uiOnRelease" shadow="true" />
</group>
</group>
@ -224,12 +224,12 @@ on_enter="leave_modal" options="no_bordure" mouse_pos="false" exit_key_pushed="t
<!-- Window -->
<instance template="log_box_frame" id="bk" posref="MM MM" sizeref="wh" w="0" h="0" />
<instance template="bk_scroll" id="back_scrollbar" posref="TR TR" x="-8" y="-8" w="24" h="342" />
<!-- Html -->
<group type="html" id="html" posref="TM TM" url="home" title_prefix=""
x="0" y="-8" w="624" h="342"
background_color="0 0 0 0"
@ -268,7 +268,7 @@ on_enter="leave_modal" options="no_bordure" mouse_pos="false" exit_key_pushed="t
<group type="list" id="text_list" fontsize="9" posref="TL TL" posparent="black" x="0" y="0" space="0" sizeref="wh" w="-28" h="0" maxelements="2000"/>
<ctrl style="skin_scroll" id="scroll_bar" posref="TR TR" target_stepy="16" x="-4" />
</group>
<ctrl style="log_std_but" id="but_close" posparent="html" posref="BM TM" y="-8" onclick_l="leave_modal" hardtext="uiNoteClose"/>
</group>
@ -285,28 +285,28 @@ on_enter="leave_modal" options="no_bordure" mouse_pos="false" exit_key_pushed="t
<group id="checking" posref="MM MM" w="1024" h="768" active="false" >
<group id="content" x="0" y="0" w="1024" h="768" posref="TL TL" >
<!-- BACKGROUND -->
<view type="bitmap" posref="TL TL" id="bl" texture="new_launcher_bg.tga" global_color="false" render_layer="-2" />
<instance template="log_box" id="window" y="-8" posref="MM MM" w="800" h="440" />
<!-- EXIT BUTTON -->
<ctrl style="log_button" id="but_exit" posparent="window" posref="TR TR" y="-20" onclick_l="login_quit" hardtext="uiExitLogin" />
<!-- Window -->
<instance template="server_box" id="check_win" posparent="window" posref="MM MM" w="600" h="128" x="0" y="0" />
<!-- Textes -->
<view type="text" id="title" posparent="check_win" posref="TM BM" y="8" color="255 255 255 255"
fontsize="12" shadow="true" hardtext="uiOnChecking" />
<view type="text" id="state" posparent="check_win" posref="TL TL" w="584" x="8" y="-8" line_maxw="584" color="135 243 28 255"
fontsize="12" shadow="true" multi_line="true" multi_line_space="0" case_mode="%case_first_sentence_letter_up"/>
<view type="text" id="progress" posref="BL TL" posparent="state" fontsize="12" y="-8" color="135 243 28 255" line_maxw="584"
shadow="true" multi_line="true" multi_line_space="0" />
</group>
</group>
@ -318,17 +318,17 @@ on_enter="leave_modal" options="no_bordure" mouse_pos="false" exit_key_pushed="t
<template name="t_cat" id="" posref="TL TL" posparent="parent" keep="true" >
<group id="#id" w="382" h="22" x="0" y="0" posref="#posref" posparent="#posparent" >
<view type="text" id="name" posref="BL BL" fontsize="12" x="26" y="1" color="135 243 28 255" shadow="true" />
<view type="text" id="size" posref="BR BR" fontsize="12" x="-8" y="1" color="135 243 28 255" shadow="true" hardtext="...Kbs" />
<ctrl type="button" button_type="toggle_button" id="on_off" sizeref="hw" h="-2" w="0" x="0" posref="ML ML" scale="true" pushed="true"
texture="blank.tga" tx_pushed="blank.tga" tx_over="blank.tga" color="0 0 0 0" col_pushed="75 144 29 80" col_over="96 117 24 32"
onclick_l="set" params_l="dblink=UI:VARIABLES:CAT:#id|value=not(@UI:VARIABLES:CAT:#id)" />
<view type="bitmap" id="state" posref="ML ML" x="2" texture="patch_on.tga" />
<link expr="ifthenelse( eq(@UI:VARIABLES:CAT:#id,0),
'patch_on.tga',
'patch_off.tga' )" target="state:texture" />
@ -352,20 +352,20 @@ on_enter="leave_modal" options="no_bordure" mouse_pos="false" exit_key_pushed="t
<instance template="server_box" id="global_win" posparent="bl" posref="TM TM" w="400" h="22" x="-14" y="-240" />
<instance template="server_box" id="nonopt_win" posparent="global_win" posref="BM TM" w="400" h="22" y="-8" />
<instance template="server_box" id="opt_win" posparent="nonopt_win" posref="BM TM" w="400" h="206" y="-30" />
<!-- Textes -->
<view type="text" id="title" posparent="global_win" posref="TM BM" y="24" color="255 255 255 255"
fontsize="12" shadow="true" hardtext="uiOnPatchDetail" />
<view type="text" id="opt_txt" posparent="opt_win" posref="TL BL" y="1" color="255 255 255 255"
fontsize="10" shadow="true" hardtext="uiOnPatchOpt" />
<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" />
</group>
<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" />
</group>
@ -393,52 +393,52 @@ on_enter="leave_modal" options="no_bordure" mouse_pos="false" exit_key_pushed="t
<group id="patching" posref="MM MM" w="1024" h="768" active="false"
<group id="patching" posref="MM MM" w="1024" h="768" active="false"
on_active="set_release_note" on_active_params="shard=selected|group=ui:login:patching:content:release_txt" >
<group id="content" x="0" y="0" w="1024" h="768" posref="TL TL" >
<!-- BACKGROUND -->
<view type="bitmap" posref="TL TL" id="bl" texture="new_launcher_bg.tga" global_color="false" render_layer="-2" />
<instance template="log_box" id="window" y="-8" posref="MM MM" w="800" h="440" />
<!-- EXIT BUTTON -->
<ctrl style="log_button" id="but_exit" posparent="window" posref="TR TR" y="-20" onclick_l="login_quit" hardtext="uiExitLogin" />
<!-- patch -->
<instance template="server_box" id="global_win" posparent="bl" posref="TM TM" w="600" h="22" x="-14" y="-180" />
<instance template="server_box" id="patch_win" posparent="global_win" posref="BM TM" w="600" h="48" y="-8" />
<link expr="eq(@UI:VARIABLES:SCREEN,4)" target="global_win:active,patch_win:active"/>
<group id="global_patch" w="582" 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="size" posref="BR BR" fontsize="12" x="-8" y="0" color="135 243 28 255" shadow="true" hardtext=".../...Kbs" />
</group>
<link expr="eq(@UI:VARIABLES:SCREEN,4)" target="global_patch:active"/>
<view type="text" id="progress" posref="TL TL" posparent="patch_win" fontsize="12" x="8" y="-8" color="135 243 28 255" shadow="true"/>
<view type="text" id="state" posparent="progress" posref="TR TL" w="520" x="4" y="0" line_maxw="520" color="135 243 28 255"
fontsize="12" shadow="true" multi_line="true" multi_line_space="0" case_mode="%case_first_sentence_letter_up"/>
<link expr="eq(@UI:VARIABLES:SCREEN,4)" target="progress:active,state:active"/>
<!-- Reboot -->
<instance template="server_box" id="reboot_win" posparent="bl" posref="TM TM" w="600" h="78" x="-14" y="-180" />
<group id="global_warn" w="582" h="54" posparent="reboot_win" posref="MM MM" >
<view type="text" id="warn" posref="TM TM" fontsize="12" x="0" y="-3" color="135 243 28 255" shadow="true" hardtext="uiRebootConfirm" />
<ctrl style="log_std_but" id="rebootbut" posparent="warn" posref="BM TM" y="-8" onclick_l="reboot" hardtext="uiRebootBut" />
</group>
<link expr="eq(@UI:VARIABLES:SCREEN,5)" target="reboot_win:active,global_warn:active"/>
<!-- Release Note -->
<instance template="server_box" id="release_win" posparent="bl" posref="TM TM" w="600" h="324" x="-14" y="-282" />
<view type="text" id="release_title" posref="TM BM" posparent="release_win" fontsize="10" y="-2" color="255 255 255 255"
<view type="text" id="release_title" posref="TM BM" posparent="release_win" fontsize="10" y="-2" color="255 255 255 255"
hardtext="uiOnRelease" shadow="true"/>
<!--
<group id="release_txt" posparent="release_win" posref="TL TL" x="8" y="-8" w="584" child_resize_h="true" h="0" max_h="308" >
<view type="text" id="content" posref="TL TL" w="584" line_maxw="584" color="135 243 28 255"
@ -484,15 +484,15 @@ on_enter="leave_modal" options="no_bordure" mouse_pos="false" exit_key_pushed="t
<group type="list" id="text_list" fontsize="9" posref="TL TL" posparent="black" x="0" y="0" space="0" sizeref="wh" w="-28" h="0" maxelements="2000"/>
<ctrl style="skin_scroll" id="scroll_bar" posref="TR TR" target_stepy="16" x="-4" />
</group>
<!-- scroll bar -->
<instance template="bk_scroll" id="back_scrollbar" posparent="release_win" posref="TR TL" x="4" w="24" sizeref="h" h="0" />
<ctrl style="skin_scroll" id="scroll_bar" align="T" target="release_txt" posparent="release_win" posref="TR TL" target_stepy="22" x="8" y="-8" />
<!-- close button-->
<!-- <ctrl style="log_std_but" id="but_close" posparent="release_txt" posref="BM TM" x="0" y="-8" fontsize="12" onclick_l="close_patch" params_l="" hardtext="uiClosePatch" active="false"/>-->
</group>
</group>
@ -509,28 +509,28 @@ on_enter="leave_modal" options="no_bordure" mouse_pos="false" exit_key_pushed="t
<!-- BACKGROUND -->
<view type="bitmap" posref="TL TL" id="bl" texture="new_launcher_bg.tga" global_color="false" render_layer="-2" />
<instance template="log_box" id="window" y="-8" posref="MM MM" w="800" h="440" />
<!-- EXIT BUTTON -->
<ctrl style="log_button" id="but_exit" posparent="window" posref="TR TR" y="-20" onclick_l="login_quit" hardtext="uiExitLogin" />
<!-- WINDOW -->
<instance template="server_box" id="eula_win" posparent="window" posref="MM MM" w="612" h="338" x="-24" y="0" />
<!-- EULA TEXT -->
<group id="eula_txt" posparent="eula_win" posref="TL TL" x="8" y="-8" w="596" child_resize_h="true" h="0" max_h="322" >
<view type="text" id="content" posref="TL TL" w="596" line_maxw="596" color="135 243 28 255"
fontsize="12" shadow="true" multi_line="true" multi_line_space="0" hardtext="uiEulaContent" />
</group>
<!-- SCROLL BAR -->
<instance template="bk_scroll" id="back_scrollbar" posparent="eula_win" posref="TR TL" x="4" w="24" sizeref="h" h="0" />
<ctrl style="skin_scroll" id="scroll_bar" align="T" target="eula_txt" posparent="eula_win" posref="TR TL" target_stepy="22" x="8" y="-8" />
<!-- TITLE -->
<view type="text" id="title" posparent="eula_win" posref="TM BM" y="8" color="255 255 255 255"
fontsize="20" shadow="true" hardtext="uiEula" />
<!-- ACCEPT & DECLINE BUTTONS -->
<ctrl style="log_std_but" id="but_accept" posparent="eula_win" posref="BM TR" x="-4" y="-8" fontsize="12" onclick_l="accept_eula" params_l="" hardtext="uiEulaAccept" />
<ctrl style="log_std_but" id="but_decline" posparent="eula_win" posref="BM TL" x="4" y="-8" fontsize="12" onclick_l="login_quit" params_l="" hardtext="uiEulaDecline" />
@ -550,25 +550,25 @@ on_enter="leave_modal" options="no_bordure" mouse_pos="false" exit_key_pushed="t
<group id="datascan" posref="MM MM" w="1024" h="768" active="false" >
<group id="content" x="0" y="0" w="1024" h="768" posref="TL TL" >
<!-- BACKGROUND -->
<view type="bitmap" posref="TL TL" id="bl" texture="new_launcher_bg.tga" global_color="false" render_layer="-2" />
<instance template="log_box" id="window" y="-8" posref="MM MM" w="800" h="440" />
<!-- EXIT BUTTON -->
<ctrl style="log_button" id="but_exit" posparent="window" posref="TR TR" y="-20" onclick_l="login_quit" hardtext="uiExitLogin" />
<!-- Window -->
<group id="placeholder" posparent="window" posref="MM MM" w="600" h="340" x="0" y="0" />
<!-- title -->
<view type="text" id="title" posparent="placeholder" posref="TM BM" y="22" color="255 255 255 255"
fontsize="12" shadow="true" hardtext="uiOnDataScanning" />
<view type="text" id="explain" posparent="placeholder" posref="TM BM" y="4" color="255 255 255 255"
fontsize="8" shadow="true" hardtext="uiOnDataScanningHelp" />
<!-- check state -->
<instance template="server_box" id="check_win" posparent="placeholder" posref="TM TM" sizeref="w" h="88" x="0" y="0" />
<view type="text" id="state" posparent="check_win" posref="TL TL" w="584" x="8" y="-8" line_maxw="584" color="135 243 28 255"
@ -600,25 +600,25 @@ on_enter="leave_modal" options="no_bordure" mouse_pos="false" exit_key_pushed="t
<!-- * CREATE ACCOUNT * -->
<!-- ******************** -->
<style style="log_url" type="text_button" button_type="toggle_button"
tx_normal="but" tx_pushed="but" tx_over="but_over" wmargin="16"
<style style="log_url" type="text_button" button_type="toggle_button"
tx_normal="but" tx_pushed="but" tx_over="but_over" wmargin="16"
color="255 255 255 0" col_over="255 255 255 0" col_pushed="255 255 255 0"
text_y="-6" text_underlined="true" fontsize="10" shadow="true"
text_color_normal="255 255 255 255" text_color_over="100 255 100 255" text_color_pushed="255 255 255 255"
text_color_normal="255 255 255 255" text_color_over="100 255 100 255" text_color_pushed="255 255 255 255"
text_shadow_color_normal="0 0 0 255"
text_shadow_color_pushed="0 0 0 255"
text_shadow_color_over="0 0 0 255"
text_shadow_color_over="0 0 0 255"
/>
<template name="log_box_blank" posref="TL TL" x="0" y="0" w="64" h="16" id="" posparent="parent" sizeref=""
<template name="log_box_blank" posref="TL TL" x="0" y="0" w="64" h="16" id="" posparent="parent" sizeref=""
keep="true" color="200 255 230 50" >
<group id="#id" posparent="#posparent" posref="#posref" w="#w" h="#h" x="#x" y="#y" sizeref="#sizeref" >
<group id="bg" sizeref="hw" h="0" w="0" />
<group id="bg" sizeref="hw" h="0" w="0" />
<view type="bitmap" id="bk" scale="true" posparent="bg" posref="MM MM" sizeref="hw" h="-32" w="-32" texture="blank.tga" color="#color" render_layer="-1"/>
<view type="bitmap" id="tl" texture="LogBoxBlank_TL.tga" posref="TL TL" color="#color" render_layer="-1"/>
<view type="bitmap" id="tr" texture="LogBoxBlank_TR.tga" posref="TR TR" color="#color" render_layer="-1"/>
<view type="bitmap" id="br" texture="LogBoxBlank_BR.tga" posref="BR BR" color="#color" render_layer="-1"/>
<view type="bitmap" id="bl" texture="LogBoxBlank_BL.tga" posref="BL BL" color="#color" render_layer="-1"/>
<view type="bitmap" id="bl" texture="LogBoxBlank_BL.tga" posref="BL BL" color="#color" render_layer="-1"/>
<view type="bitmap" id="t" texture="blank.tga" posref="TM TM" scale="true" sizeref="w" w="-32" h="16" color="#color" render_layer="-1"/>
<view type="bitmap" id="b" texture="blank.tga" posref="BM BM" scale="true" sizeref="w" w="-32" h="16" color="#color" render_layer="-1"/>
<view type="bitmap" id="l" texture="blank.tga" posref="ML ML" scale="true" sizeref="h" h="-32" w="16" color="#color" render_layer="-1"/>
@ -630,20 +630,20 @@ on_enter="leave_modal" options="no_bordure" mouse_pos="false" exit_key_pushed="t
<group id="create_account" posref="MM MM" w="1024" h="768" active="false" >
<group id="content" x="0" y="0" w="1024" h="768" posref="TL TL" >
<!-- BACKGROUND -->
<view type="bitmap" posref="TL TL" id="bl" texture="new_launcher_bg.tga" global_color="false" render_layer="-2" />
<instance template="log_box" id="window" y="-8" posref="MM MM" w="800" h="440" />
<!-- Window -->
<group id="placeholder" posparent="window" posref="MM MM" w="600" h="360" x="0" y="0" />
<!-- title -->
<view type="text" id="title" posparent="placeholder" posref="TM BM" y="0" color="255 255 255 255"
fontsize="16" shadow="true" hardtext="uiCreateAccount" />
<group id="submit_gr" x="30" y="-20" posparent="window" sizeref="wh" w="-30" h="-15" posref="TL TL" >
<!-- login -->
<view type="text" id="txt_log" posref="TL TL" hardtext="uiUsername" fontsize="12" x="0" y="-60" color="255 255 255 255" />
@ -652,10 +652,10 @@ on_enter="leave_modal" options="no_bordure" mouse_pos="false" exit_key_pushed="t
on_focus="create_account_rules" on_focus_params="rules_login" reset_focus_on_hide="false" max_historic="0"
onenter="set_keyboard_focus" params="target=ui:login:create_account:content:submit_gr:eb_password:eb|select_all=false"
prompt="" enter_loose_focus="true" multi_line="false" max_num_chars="12" color="135 243 28 255" />
<!-- password -->
<view type="text" id="txt_pas" posparent="txt_log" posref="BL TL" hardtext="uiPassword" fontsize="12" x="0" y="-30" color="255 255 255 255" />
<instance template="edit_box_log" id="eb_password" posparent="txt_pas" posref="BL BL" w="260" h="24" fontsize="16" x="190" y="0"
text_ref="BM BM" text_y="-2"
on_focus="create_account_rules" on_focus_params="rules_password" reset_focus_on_hide="false" max_historic="0" entry_type="password"
@ -664,16 +664,16 @@ on_enter="leave_modal" options="no_bordure" mouse_pos="false" exit_key_pushed="t
<!-- confirm password -->
<view type="text" id="txt_confirm_pas" posparent="txt_pas" posref="BL TL" hardtext="uiConfirmPassword" fontsize="12" x="0" y="-30" color="255 255 255 255" />
<instance template="edit_box_log" id="eb_confirm_password" posparent="txt_confirm_pas" posref="BL BL" w="260" h="24" fontsize="16" x="190" y="0"
text_ref="BM BM" text_y="-2"
on_focus="create_account_rules" on_focus_params="rules_password_conf" reset_focus_on_hide="false" max_historic="0" entry_type="password"
onenter="set_keyboard_focus" params="target=ui:login:create_account:content:submit_gr:eb_email:eb|select_all=false"
prompt="" enter_loose_focus="true" multi_line="false" max_num_chars="20" color="135 243 28 255" />
<!-- email -->
<view type="text" id="txt_email" posparent="txt_confirm_pas" posref="BL TL" hardtext="uiEmail" fontsize="12" x="0" y="-30" color="255 255 255 255" />
<instance template="edit_box_log" id="eb_email" posparent="txt_email" posref="BL BL" w="260" h="24" fontsize="12" x="190" y="0"
text_ref="BM BM" text_y="-2"
on_focus="create_account_rules" on_focus_params="rules_email" reset_focus_on_hide="false" max_historic="0"
@ -681,30 +681,30 @@ on_enter="leave_modal" options="no_bordure" mouse_pos="false" exit_key_pushed="t
prompt="" enter_loose_focus="true" multi_line="false" max_num_chars="254" color="135 243 28 255" />
<!-- accept conditions -->
<ctrl type="button" id="accept_cond" button_type="toggle_button" pushed="true"
posref="BL TL" posparent="txt_email" x="0" y="-30" tx_normal="w_opacity_on.tga"
tx_pushed="w_slot_on.tga" tx_over="w_slot_on.tga" color="255 255 255 255" col_pushed="255 255 255 255"
<ctrl type="button" id="accept_cond" button_type="toggle_button" pushed="true"
posref="BL TL" posparent="txt_email" x="0" y="-30" tx_normal="w_opacity_on.tga"
tx_pushed="w_slot_on.tga" tx_over="w_slot_on.tga" color="255 255 255 255" col_pushed="255 255 255 255"
col_over="255 255 255 0" onclick_l="create_account_rules" params_l="" tooltip=""
/>
<view type="text" id="txt_accept_cond" posref="BR BL" posparent="accept_cond" hardtext="uiAcceptTermsOfUse1" fontsize="10" x="20" y="-2" color="255 255 255 255" />
<ctrl type="text_button" id="terms_launch_url" style="log_url" posref="BR BL" posparent="txt_accept_cond" x="2" y="0" hardtext="uiAcceptTermsOfUse2"
<ctrl type="text_button" id="terms_launch_url" style="log_url" posref="BR BL" posparent="txt_accept_cond" x="2" y="0" hardtext="uiAcceptTermsOfUse2"
onclick_l="open_url" params_l="cfg_ConditionsTermsURL"/>
<!-- ********************** -->
<!-- *** WELCOME/ERRORS *** -->
<!-- ********************** -->
<instance template="log_box_blank" id="welcome_errors_gr" posparent="eb_login" posref="TR TL" h="165" w="260" x="20" y="0"
<instance template="log_box_blank" id="welcome_errors_gr" posparent="eb_login" posref="TR TL" h="165" w="260" x="20" y="0"
blackColor="0 0 0 255" whiteColor="255 255 255 255" />
<group id="erros_txt" posparent="welcome_errors_gr" posref="TL TL" x="8" y="-8" sizeref="w" child_resize_h="true"
max_sizeparent="welcome_errors_gr" max_sizeref="h" max_h="-16">
<view type="text" id="errors_list" posref="TL TL" x="15" y="-15" fontsize="12" color="255 255 255 255" line_maxw="584"
shadow="true" multi_line="true" multi_line_space="20" multi_max_line="100" hardtext="uiCreateAccountWelcome" />
</group>
<instance template="bk_scroll" id="err_back_scrollbar" active="true" posparent="welcome_errors_gr" posref="TR TL" x="4" w="24" sizeref="h" h="0" />
<ctrl style="skin_scroll" id="err_scroll_bar" active="true" align="T" target="erros_txt" posparent="welcome_errors_gr" posref="TR TL" target_stepy="15" x="8" y="-8" />
@ -738,14 +738,14 @@ on_enter="leave_modal" options="no_bordure" mouse_pos="false" exit_key_pushed="t
</group>
<group id="login_gr" x="30" y="-40" posparent="window" sizeref="wh" w="-60" h="-45" posref="TL TL" >
<view type="text" id="success" multi_line="true" line_maxw="600" posref="TL TL" hardtext="uiSubmitSucces1" fontsize="14" x="90" y="-50" color="255 255 255 255" />
<view type="text" id="email_adress" multi_line="false" line_maxw="600" posparent="success" posref="BL TL" hardtext="ADRESSE\n" fontsize="14" x="80" y="-10" color="150 255 150 255" />
<view type="text" id="successEnd" multi_line="true" line_maxw="600" posparent="email_adress" posref="BL TL" hardtext="uiSubmitSucces2" fontsize="14" x="-80" y="-10" color="255 255 255 255" />
<!-- Close Button -->
<ctrl style="log_std_but" id="but_close" posparent="placeholder" posref="BM BR" x="-10" y="15" onclick_l="on_create_account_close" hardtext="uiCancelCreateAccount" />
<!-- Submit Button -->
<ctrl style="log_std_but" id="but_login" posparent="placeholder" posref="BM BL" x="10" y="15" onclick_l="create_account_login" hardtext="uiOnConnect" />
@ -771,17 +771,17 @@ on_enter="leave_modal" options="no_bordure" mouse_pos="false" exit_key_pushed="t
<view type="bitmap" posref="TL TL" id="bl" texture="new_launcher_bg.tga" global_color="false" render_layer="-2" />
<instance template="log_box" id="window" y="-8" posref="MM MM" w="800" h="440" />
<instance template="html_text_button" id="back_to_login" text="BACK TO LOGIN" posparent="parent" posref="TL TL" y="-15"
<instance template="html_text_button" id="back_to_login" text="BACK TO LOGIN" posparent="parent" posref="TL TL" y="-15"
onclick="on_back_to_login" onclick_param="" active="true"/>
<instance template="html_text_button" id="reload_test_page" text="RELOAD START PAGE" posparent="parent" posref="TL TL" y="-45"
<instance template="html_text_button" id="reload_test_page" text="RELOAD START PAGE" posparent="parent" posref="TL TL" y="-45"
onclick="on_reload_test_page" onclick_param="" active="false"/>
-->
<!-- EXIT BUTTON -->
<!-- <ctrl style="log_button" id="but_exit" posparent="window" posref="TR TR" y="-20" onclick_l="login_quit" hardtext="uiExitLogin" />
-->
<!-- Window -->
<!-- <group id="placeholder" posparent="window" posref="MM MM" w="600" h="340" x="0" y="0" />
-->
@ -791,7 +791,7 @@ on_enter="leave_modal" options="no_bordure" mouse_pos="false" exit_key_pushed="t
<view type="text" id="explain" posparent="placeholder" posref="TM BM" y="4" color="255 255 255 255"
fontsize="8" shadow="true" hardtext="uiOnDataScanningHelp" />
-->
<!--
<group id="black" posref="BR BR" sizeref="hw" w="-16" h="-12" inherit_gc_alpha="true"/>
<instance template="inner_thin_border" posparent="black" inherit_gc_alpha="true"/>

View file

@ -1,14 +1,15 @@
# Need clientsheets lib for sheets packer tool
ADD_SUBDIRECTORY(client_sheets)
# Need seven_zip lib for patch_gen tool
ADD_SUBDIRECTORY(seven_zip)
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
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)
IF(WITH_RYZOM_CUSTOM_PATCH_SERVER)
@ -115,6 +116,15 @@ IF(WITH_RYZOM_CLIENT)
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)
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()
@ -129,6 +139,10 @@ IF(WITH_RYZOM_CLIENT)
${ZLIB_INCLUDE_DIR}
)
IF(STEAM_FOUND)
INCLUDE_DIRECTORIES(${STEAM_INCLUDE_DIRS})
ENDIF()
TARGET_LINK_LIBRARIES(khanat_client
nelmisc
nelnet
@ -137,13 +151,13 @@ IF(WITH_RYZOM_CLIENT)
nel3d
nelgui
nelsound
ryzom_sevenzip
ryzom_clientsheets
ryzom_gameshare
nelpacs
${LUA_LIBRARIES}
${LUABIND_LIBRARIES}
${CURL_LIBRARIES}
${SEVENZIP_LIBRARY}
)
ADD_DEFINITIONS(${LIBXML2_DEFINITIONS})

View file

@ -62,6 +62,10 @@
#include "client_cfg.h"
#include "far_tp.h"
#ifdef RZ_USE_STEAM
#include "steam_client.h"
#endif
///////////
// USING //
///////////
@ -319,6 +323,13 @@ int main(int argc, char **argv)
prelogInit();
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
RYZOM_TRY("Login")
if (!ClientCfg.Local && (ClientCfg.TestBrowser || ClientCfg.FSHost.empty()))

View file

@ -659,7 +659,7 @@ static void addPaths(IProgressCallback &progress, const std::vector<std::string>
std::vector<std::string> directoryPrefixes;
// current directory has priority everywhere
directoryPrefixes.push_back("");
directoryPrefixes.push_back(CPath::standardizePath(CPath::getCurrentPath()));
#if defined(NL_OS_WINDOWS)
// 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()));
#endif
std::vector<std::string> directoriesToProcess;
std::map<std::string, sint> directoriesToProcess;
// reserve maximum memory space for all combinations
directoriesToProcess.reserve(directoryPrefixes.size() * paths.size());
// first pass, build a vector with all existing directories to process in second pass
// first pass, build a map with all existing directories to process in second pass
for (uint j = 0; j < directoryPrefixes.size(); j++)
{
std::string directoryPrefix = directoryPrefixes[j];
@ -698,15 +695,17 @@ static void addPaths(IProgressCallback &progress, const std::vector<std::string>
// only process existing directories
if (CFile::isExists(directory))
directoriesToProcess.push_back(directory);
directoriesToProcess[directory] = 1;
}
}
uint total = (uint)directoriesToProcess.size();
uint current = 0, next = 0;
std::map<std::string, sint>::const_iterator it = directoriesToProcess.begin(), iend = directoriesToProcess.end();
// second pass, add search paths
for (uint i = 0, len = directoriesToProcess.size(); i < len; ++i)
while (it != iend)
{
// update next progress value
++next;
@ -717,9 +716,11 @@ static void addPaths(IProgressCallback &progress, const std::vector<std::string>
// next is current value
current = next;
CPath::addSearchPath(directoriesToProcess[i], recurse, false, &progress);
CPath::addSearchPath(it->first, recurse, false, &progress);
progress.popCropedValues();
++it;
}
}

View file

@ -112,7 +112,7 @@ bool InitMouseWithCursor (bool hardware)
}
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);
}
}

View file

@ -77,7 +77,7 @@ extern bool SetMousePosFirstTime;
vector<CShard> Shards;
string LoginLogin, LoginPassword, ClientApp, Salt;
string LoginLogin, LoginPassword, ClientApp, Salt, LoginCustomParameters;
uint32 LoginShardId = 0xFFFFFFFF;
@ -1169,7 +1169,7 @@ void onlogin(bool vanishScreen = true)
// Check the login/pass
// main menu page for r2mode
string res = checkLogin(LoginLogin, LoginPassword, ClientApp);
string res = checkLogin(LoginLogin, LoginPassword, ClientApp, LoginCustomParameters);
if (res.empty())
{
// 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();
Shards.clear();
@ -2795,7 +2795,7 @@ string checkLogin(const string &login, const string &password, const string &cli
{
// R2 login sequence
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)";
// the response should contains the result code and the cookie value

View file

@ -46,7 +46,7 @@ struct CShard
std::string EmergencyPatchURL;
};
extern std::string LoginLogin, LoginPassword;
extern std::string LoginLogin, LoginPassword, LoginCustomParameters;
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 getBGDownloaderCommandLine();

View file

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

View file

@ -331,10 +331,6 @@ private:
void clearDataScanLog();
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);
// Forward message to Installation Software
void onFileInstallFinished();

View file

@ -5,7 +5,7 @@ FILE(GLOB LIB_SRC *.cpp *.h)
LIST(REMOVE_ITEM LIB_SRC ${CMAKE_CURRENT_SOURCE_DIR}/7zMain.cpp)
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_ADD_RUNTIME_FLAGS(ryzom_sevenzip)
NL_ADD_LIB_SUFFIX(ryzom_sevenzip)
@ -14,11 +14,11 @@ ADD_DEFINITIONS(-DUNICODE -D_UNICODE -D_7ZIP_PPMD_SUPPPORT)
IF(WITH_PCH)
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)
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)
ADD_EXECUTABLE(7zDec ${CMAKE_CURRENT_SOURCE_DIR}/7zMain.cpp)
@ -28,4 +28,4 @@ IF(WITH_RYZOM_TOOLS)
NL_ADD_RUNTIME_FLAGS(7zDec)
INSTALL(TARGETS 7zDec RUNTIME DESTINATION ${RYZOM_BIN_PREFIX} COMPONENT tools)
ENDIF(WITH_RYZOM_TOOLS)
ENDIF()

View 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;
}

View 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

View 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

View 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

View file

@ -3,7 +3,6 @@ FILE(GLOB SRC main.cpp
${CMAKE_SOURCE_DIR}/ryzom/client/src/user_agent.cpp
${CMAKE_SOURCE_DIR}/ryzom/client/src/client_cfg.cpp
${CMAKE_SOURCE_DIR}/ryzom/client/src/login_patch.cpp
${CMAKE_SOURCE_DIR}/ryzom/client/src/login_patch_seven_zip.cpp
${CMAKE_SOURCE_DIR}/ryzom/client/src/login_xdelta.cpp
${CMAKE_SOURCE_DIR}/ryzom/client/src/stdpch.cpp
${CMAKE_SOURCE_DIR}/ryzom/client/src/stdpch.h
@ -17,6 +16,7 @@ ADD_EXECUTABLE(khanat_client_patcher ${SRC})
INCLUDE_DIRECTORIES(
${LIBXML2_INCLUDE_DIR}
${CURL_INCLUDE_DIRS}
${ZLIB_INCLUDE_DIR}
${CMAKE_SOURCE_DIR}/ryzom/client/src
)

View file

@ -1,6 +1,10 @@
#include "stdpch.h"
#include "login_patch.h"
#include "client_cfg.h"
#include "user_agent.h"
#include "nel/misc/cmd_args.h"
#include <locale.h>
#ifdef NL_OS_WINDOWS
@ -28,7 +32,8 @@ string VersionName;
string LoginLogin, LoginPassword;
uint32 LoginShardId = 0xFFFFFFFF;
bool useUtf8 = false;
CCmdArgs Args;
bool useEsc = false;
#ifdef NL_OS_WINDOWS
@ -38,9 +43,6 @@ sint attributes = 0;
std::string convert(const ucstring &str)
{
if (useUtf8)
return str.toUtf8();
return str.toString();
}
@ -91,28 +93,12 @@ void printDownload(const std::string &str)
// temporary modified string
std::string nstr = str;
uint length = 0;
uint length = (uint)nstr.length();
if (useUtf8)
if (length > maxLength)
{
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)
{
nstr = std::string("...") + nstr.substr(length - maxLength + 3);
length = maxLength;
}
nstr = std::string("...") + nstr.substr(length - maxLength + 3);
length = maxLength;
}
// add padding with spaces
@ -142,11 +128,65 @@ void printDownload(const std::string &str)
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[])
{
// init the Nel context
CApplicationContext appContext;
Args.setVersion(getDisplayVersion());
Args.setDescription("Ryzom client");
Args.addArg("c", "config", "id", "Use this configuration to determine what directory to use by default");
if (!Args.parse(argc, argv)) return 1;
// create logs in temporary directory
createDebug(CPath::getTemporaryDirectory().c_str(), true, true);
@ -177,11 +217,6 @@ int main(int argc, char *argv[])
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
std::string term = toLower(std::string(getenv("TERM") ? getenv("TERM"):""));
useEsc = (term.find("xterm") != string::npos || term.find("linux") != string::npos);
@ -209,70 +244,23 @@ int main(int argc, char *argv[])
return 1;
}
// set default paths
std::string dataPath = "./data/";
std::string rootPath = "./";
// allocate translations proxy
CClientPatcherTranslations *trans = new CClientPatcherTranslations();
// use custom data path if specified
if (!ClientCfg.DataPath.empty())
{
dataPath = CPath::standardizePath(ClientCfg.DataPath.front());
string::size_type pos = dataPath.rfind('/', dataPath.length()-2);
if (pos != string::npos)
rootPath = dataPath.substr(0, pos+1);
}
// use proxy
CI18N::setLoadProxy(trans);
std::string unpackPath = CPath::standardizePath(rootPath + "unpack");
// load english translations
CI18N::load("en");
// check if user can write in data directory
if (!CFile::isExists(unpackPath))
{
if (!CFile::createDirectoryTree(unpackPath))
{
printError("You don't have permission to create " + unpackPath);
return 1;
}
}
else
{
if (!CFile::createEmptyFile(unpackPath + "empty"))
{
printError("You don't have write permission in " + unpackPath);
return 1;
}
CFile::deleteFile(unpackPath + "empty");
}
// only use PreDataPath for looking paths
if (!ClientCfg.PreDataPath.empty())
{
for(uint i = 0; i < ClientCfg.PreDataPath.size(); ++i)
{
CPath::addSearchPath(NLMISC::expandEnvironmentVariables(ClientCfg.PreDataPath[i]), true, false);
}
}
// add more search paths if translation is not found
if (!CPath::exists(lang + ".uxt"))
{
CPath::addSearchPath("patcher", true, false);
#ifdef RYZOM_SHARE_PREFIX
CPath::addSearchPath(RYZOM_SHARE_PREFIX"/patcher", true, false);
#endif
}
// load translation
CI18N::load(lang);
// now translations are read, we don't need it anymore
delete trans;
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
CPatchManager *pPM = CPatchManager::getInstance();
// set the correct root path
pPM->setClientRootPath(rootPath);
// use PatchUrl
vector<string> patchURLs;
pPM->init(patchURLs, ClientCfg.PatchUrl, ClientCfg.PatchVersion);
@ -385,6 +373,8 @@ int main(int argc, char *argv[])
printError(convert(CI18N::get("uiErrPatchApply")) + " " + error);
return 1;
}
pPM->executeBatchFile();
}
/*

View file

@ -4,6 +4,7 @@ FILE(GLOB SRC *.cpp *.h)
ADD_LIBRARY(georges_dll SHARED ${SRC} georges_edit.rc)
INCLUDE_DIRECTORIES(${NEL_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR})
TARGET_LINK_LIBRARIES(georges_dll nelmisc nelgeorges)
NL_DEFAULT_PROPS(georges_dll "Ryzom, Tools, Georges: Georges Dll")

View file

@ -8,6 +8,8 @@ SET(CMAKE_MFC_FLAG 2)
ADD_EXECUTABLE(world_editor WIN32 ${SRC} world_editor.rc)
INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR})
SOURCE_GROUP(Resources FILES world_editor.rc)
TARGET_LINK_LIBRARIES(world_editor

View file

@ -110,6 +110,7 @@
extern bool DontUse3D;
#include <libxml/parser.h>
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

View file

@ -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(SERVICE_SRC patch_gen_common.cpp patch_gen_service.cpp patch_gen_service.h)
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_ADD_RUNTIME_FLAGS(patch_gen)
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_ADD_RUNTIME_FLAGS(patch_gen_service)

View file

@ -27,6 +27,7 @@
#include "nel/misc/command.h"
#include "nel/misc/sstring.h"
#include "game_share/singleton_registry.h"
#include "seven_zip.h"
using namespace std;
using namespace NLMISC;
@ -74,37 +75,16 @@ void ApplyPatch(const std::string& srcFileName,const std::string& destFileName,c
#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
std::string cmd = "lzma e";
cmd += " " + sourceFile + " " + outputFile;
nlinfo("Executing system command: %s", cmd.c_str());
nlinfo("Compressing %s to %s using LZMA...", sourceFile.c_str(), outputFile.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
std::string cmd = NLMISC::toString("lzma -z -9 %s", outputFile.c_str());
sint error = system(cmd.c_str());
if (error)
if (!packLZMA(sourceFile, outputFile))
{
nlwarning("'%s' failed with error code %d", cmd.c_str(), error);
CFile::deleteFile(outputFile);
nlwarning("LZMA compress failed");
}
else
{
// lzma always append a .lzma extension, so rename compressed file to wanted one
CFile::moveFile(outputFile, outputFile + ".lzma");
}
#endif // NL_OS_WINDOWS
}
@ -230,7 +210,7 @@ void CPackageDescription::storeToPdr(CPersistentDataRecord& pdr) const
void CPackageDescription::readIndex(CBNPFileSet& packageIndex) const
{
std::string indexPath = _RootDirectory + _IndexFileName;
nlinfo("Reading history file: %s ...", indexPath.c_str());
// clear out old contents before reading from input file
@ -294,7 +274,7 @@ void CPackageDescription::generateClientIndex(CProductDescriptionForClient& theC
std::string patchNumber = toString("%05u", packageIndex.getVersionNumber());
std::string patchDirectory = _PatchDirectory + patchNumber;
std::string patchFile = patchDirectory + "/" + _ClientIndexFileName;
nlinfo("Generating client index: %s...", patchFile.c_str());
// make sure the version sub directory exist

View file

@ -1417,11 +1417,11 @@ uiErrPatchApply [Fehler : Patchprozess beendet, aber der Patch konnte nicht erfo
// INDEX 353
uiErrChecking [Fehler : Patchdateien versagen - Überprüfung.]
// HASH_VALUE 40D0242C40D0242C
// HASH_VALUE 8E9280411622E45F
// INDEX 354
uiKb [KB]
// HASH_VALUE 4050243440502434
// HASH_VALUE 90B288459762EC61
// INDEX 355
uiMb [MB]
@ -27271,3 +27271,11 @@ uiRadarUseCamera [Radar folgt der Kamera-Rotation.]
// INDEX 6466
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]

View file

@ -1415,13 +1415,13 @@ uiErrPatchApply [Error: Patch process ended but the patch has not been successfu
// INDEX 353
uiErrChecking [Error: Patch files failed - checking.]
// HASH_VALUE 40D0242C40D0242C
// HASH_VALUE 8E9280411622E45F
// INDEX 354
uiKb [KB]
uiKb [KiB]
// HASH_VALUE 4050243440502434
// HASH_VALUE 90B288459762EC61
// INDEX 355
uiMb [MB]
uiMb [MiB]
// HASH_VALUE 9FA5A06DD895B637
// INDEX 356
@ -27237,3 +27237,27 @@ uiRadarUseCamera [Radar follows camera rotation]
// INDEX 6466
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...]

View file

@ -1416,13 +1416,13 @@ uiErrPatchApply [Error: Proceso de Parcheado finalize pero el parche no ha sido
// INDEX 353
uiErrChecking [Error: Archivos del Parcheado han fallado - revisando.]
// HASH_VALUE 40D0242C40D0242C
// HASH_VALUE 8E9280411622E45F
// INDEX 354
uiKb [KB]
uiKb [KiB]
// HASH_VALUE 4050243440502434
// HASH_VALUE 90B288459762EC61
// INDEX 355
uiMb [MB]
uiMb [MiB]
// HASH_VALUE 9FA5A06DD895B637
// INDEX 356
@ -27297,3 +27297,11 @@ uiRadarUseCamera [El radar sigue la rotación de la cámara]
// INDEX 6466
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]

File diff suppressed because it is too large Load diff

View file

@ -1445,13 +1445,13 @@ uiErrPatchApply [Error : Patch process ended but the patch has not been successf
// INDEX 353
uiErrChecking [Error : Checking for patch files failed]
// HASH_VALUE 40D0242C40D0242C
// HASH_VALUE 8E9280411622E45F
// INDEX 354
uiKb [KB]
uiKb [KiB]
// HASH_VALUE 4050243440502434
// HASH_VALUE 90B288459762EC61
// INDEX 355
uiMb [MB]
uiMb [MiB]
// HASH_VALUE 9FA5A06DD895B637
// INDEX 356
@ -27455,3 +27455,27 @@ uiRadarUseCamera [Radar follows camera rotation]
// INDEX 6466
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...]

View file

@ -753,9 +753,9 @@ uiErrPatchApply [Error : Patch process ended but the patch has not been successf
uiErrChecking [Error : Checking for patch files failed]
uiKb [KB]
uiKb [KiB]
uiMb [MB]
uiMb [MiB]
uiLoginGetFile [Getting File :]
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.]
uiRadarUseCamera [Radar follows camera rotation]
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
View file

@ -0,0 +1 @@
ADD_SUBDIRECTORY(bin2c)

View 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)

View file

@ -14,9 +14,6 @@
// 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/>.
// bin2c.cpp : Defines the entry point for the console application.
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -25,22 +22,55 @@ int main(int argc, char* argv[])
{
if (argc<2)
{
printf ("bin2c [filename.bin] [filename.c]\n");
printf ("bin2c <filename.bin> [filename.c]\n");
}
else
{
char sDir[256];
char sPath[256];
// path and filename but without extension
char sPathWithoutExtension[256];
// basename of file
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];
if (argc>2)
{
strcpy (sOutput, argv[2]);
}
else
{
_makepath (sOutput, sDir, sPath, sName, ".cpp");
strcpy(sOutput, sPathWithoutExtension);
strcat(sOutput, ".cpp");
}
FILE *pIn=fopen( argv[1], "rb");