// NeL - MMORPG Framework
// Copyright (C) 2010-2020 Winch Gate Property Limited
//
// This source file has been modified by the following contributors:
// Copyright (C) 2020 Jan BOON (Kaetemi)
//
// 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 .
#include "nel/misc/types_nl.h"
#include
#include
#ifdef NL_OS_WINDOWS
# include
# include
#endif
#include
#include
#include "nel/misc/debug.h"
#include "nel/misc/file.h"
#include "nel/misc/path.h"
#include "nel/misc/algo.h"
#include "nel/misc/common.h"
#include "nel/misc/big_file.h"
#include "nel/misc/cmd_args.h"
using namespace std;
using namespace NLMISC;
// ---------------------------------------------------------------------------
class CWildCard
{
public:
string Expression;
bool Not;
};
std::vector WildCards;
// ---------------------------------------------------------------------------
bool keepFile (const std::string &fileName)
{
uint i;
bool ifPresent = false;
bool ifTrue = false;
string file = toLowerAscii(CFile::getFilename (fileName));
for (i=0; i pathContent;
printf ("Treating directory: %s\n", srcDirectory.c_str());
CPath::getPathContent(srcDirectory, true, false, true, pathContent);
if (pathContent.empty()) return true;
// Sort filename
sort (pathContent.begin(), pathContent.end(), i_comp);
// check for files with same name
for(uint i = 1, len = pathContent.size(); i < len; ++i)
{
if (toLowerAscii(CFile::getFilename(pathContent[i-1])) == toLowerAscii(CFile::getFilename(pathContent[i])))
{
nlwarning("File %s is not unique in BNP!", CFile::getFilename(pathContent[i]).c_str());
return false;
}
}
for (uint i=0; i filters;
// If ?
filters = args.getLongArg("if");
for (uint i = 0; i < filters.size(); ++i)
{
CWildCard card;
card.Expression = toLowerAscii(filters[i]);
card.Not = false;
WildCards.push_back(card);
}
// If not ?
filters = args.getLongArg("ifnot");
for (uint i = 0; i < filters.size(); ++i)
{
CWildCard card;
card.Expression = toLowerAscii(filters[i]);
card.Not = true;
WildCards.push_back(card);
}
// Pack a directory
std::string srcDirectory = args.getAdditionalArg("input").front();
if (!CFile::isDirectory(srcDirectory) || !CFile::isExists(srcDirectory))
{
nlwarning("Error: %s doesn't exist or is not a directory!", srcDirectory.c_str());
}
// Output directory or filename
if (args.haveArg("o"))
{
gBNPHeader.BigFileName = args.getArg("o").front();
if (CFile::isDirectory(gBNPHeader.BigFileName))
{
gBNPHeader.BigFileName = CPath::standardizePath(gBNPHeader.BigFileName) + CFile::getFilename(srcDirectory);
}
}
else
{
gBNPHeader.BigFileName = CFile::getFilename(srcDirectory);
}
if (CFile::getExtension(gBNPHeader.BigFileName) != "bnp")
gBNPHeader.BigFileName += ".bnp";
CFile::deleteFile(gBNPHeader.BigFileName);
if (!packSubRecurse(srcDirectory)) return 1;
return gBNPHeader.appendHeader() ? 0:-1;
}
if (args.haveArg("u"))
{
gBNPHeader.BigFileName = args.getAdditionalArg("input").front();
std::string dirName;
// Output directory or filename
if (args.haveArg("o"))
{
dirName = args.getArg("o").front();
}
else
{
dirName = CFile::getFilenameWithoutExtension(gBNPHeader.BigFileName);
}
// Unpack a bnp file
return gBNPHeader.unpack(dirName) ? 0:-1;
}
if (args.haveArg("l"))
{
gBNPHeader.BigFileName = args.getAdditionalArg("input").front();
// Read header of BNP file
if (!gBNPHeader.readHeader()) return -1;
for (uint i = 0; i < gBNPHeader.SFiles.size(); ++i)
{
printf("%s\n", gBNPHeader.SFiles[i].Name.c_str());
}
return 0;
}
if (args.haveLongArg("list-verbose"))
{
gBNPHeader.BigFileName = args.getAdditionalArg("input").front();
// Read header of BNP file
if (!gBNPHeader.readHeader()) return -1;
for (uint i = 0; i < gBNPHeader.SFiles.size(); ++i)
{
printf("%u %u %s\n", gBNPHeader.SFiles[i].Pos, gBNPHeader.SFiles[i].Size, gBNPHeader.SFiles[i].Name.c_str());
}
return 0;
}
// --extract
if (args.haveLongArg("extract") && !args.getLongArg("extract").empty())
{
std::string bnpName = args.getAdditionalArg("input").front();
CBigFile::getInstance().add(bnpName, BF_ALWAYS_OPENED);
// Output directory or filename
if (!args.haveArg("o") || args.getArg("o").empty())
{
nlerror("Output file or directory not set");
}
std::string srcName = args.getLongArg("extract").front();
std::string dstName = args.getArg("o").front();
if (CFile::fileExists(dstName) && CFile::isDirectory(dstName))
{
dstName += "/" + srcName;
}
CIFile inFile;
// bnpName without path
if (!inFile.open(CFile::getFilename(bnpName) + "@" + srcName))
{
nlerror("Unable to open '%s' for reading", inFile.getStreamName().c_str());
}
COFile outFile;
if (!outFile.open(dstName))
{
nlerror("Unable to open '%s' for writing", outFile.getStreamName().c_str());
}
std::string buf;
inFile.readAll(buf);
outFile.serialBuffer((uint8 *)&buf[0], buf.size());
return 0;
}
args.displayHelp();
return -1;
}