2012-05-29 13:31:11 +00:00
// 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/>.
# include "nel/misc/types_nl.h"
# include <stdio.h>
# include <stdlib.h>
# ifdef NL_OS_WINDOWS
# include <io.h>
# include <direct.h>
# endif
# include <vector>
# include <string>
# 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"
2016-01-23 11:30:01 +00:00
# include "nel/misc/big_file.h"
# include "nel/misc/cmd_args.h"
2012-05-29 13:31:11 +00:00
using namespace std ;
using namespace NLMISC ;
// ---------------------------------------------------------------------------
class CWildCard
{
public :
string Expression ;
bool Not ;
} ;
std : : vector < CWildCard > WildCards ;
// ---------------------------------------------------------------------------
2016-01-23 11:30:01 +00:00
bool keepFile ( const std : : string & fileName )
2012-05-29 13:31:11 +00:00
{
uint i ;
bool ifPresent = false ;
bool ifTrue = false ;
string file = toLower ( CFile : : getFilename ( fileName ) ) ;
for ( i = 0 ; i < WildCards . size ( ) ; i + + )
{
if ( WildCards [ i ] . Not )
{
// One ifnot condition met and the file is not added
2016-01-23 11:30:01 +00:00
if ( testWildCard ( file , WildCards [ i ] . Expression ) )
2012-05-29 13:31:11 +00:00
return false ;
}
else
{
ifPresent = true ;
2016-01-23 11:30:01 +00:00
ifTrue | = testWildCard ( file , WildCards [ i ] . Expression ) ;
2012-05-29 13:31:11 +00:00
}
}
return ! ifPresent | | ifTrue ;
}
// ---------------------------------------------------------------------------
2016-01-23 11:30:01 +00:00
NLMISC : : CBigFile : : BNP gBNPHeader ;
2012-05-29 13:31:11 +00:00
// ---------------------------------------------------------------------------
bool i_comp ( const string & s0 , const string & s1 )
{
return nlstricmp ( CFile : : getFilename ( s0 ) . c_str ( ) , CFile : : getFilename ( s1 ) . c_str ( ) ) < 0 ;
}
2016-01-23 11:30:01 +00:00
void packSubRecurse ( const std : : string & srcDirectory )
2012-05-29 13:31:11 +00:00
{
vector < string > pathContent ;
2016-01-23 11:30:01 +00:00
printf ( " Treating directory: %s \n " , srcDirectory . c_str ( ) ) ;
CPath : : getPathContent ( srcDirectory , true , false , true , pathContent ) ;
2016-01-23 17:49:10 +00:00
if ( pathContent . empty ( ) ) return ;
2012-05-29 13:31:11 +00:00
// Sort filename
sort ( pathContent . begin ( ) , pathContent . end ( ) , i_comp ) ;
2016-01-23 17:49:10 +00:00
// check for files with same name
for ( uint i = 1 , len = pathContent . size ( ) ; i < len ; + + i )
{
if ( toLower ( CFile : : getFilename ( pathContent [ i - 1 ] ) ) = = toLower ( CFile : : getFilename ( pathContent [ i ] ) ) )
{
nlerror ( " File %s is not unique in BNP! " , CFile : : getFilename ( pathContent [ i ] ) . c_str ( ) ) ;
return ;
}
}
2016-01-23 11:30:01 +00:00
for ( uint i = 0 ; i < pathContent . size ( ) ; + + i )
2012-05-29 13:31:11 +00:00
{
2016-01-23 11:30:01 +00:00
if ( keepFile ( pathContent [ i ] ) )
2012-05-29 13:31:11 +00:00
{
2016-01-23 11:30:01 +00:00
if ( gBNPHeader . appendFile ( pathContent [ i ] ) )
2012-05-29 13:31:11 +00:00
{
2016-01-23 17:49:10 +00:00
printf ( " Adding %s \n " , pathContent [ i ] . c_str ( ) ) ;
2012-05-29 13:31:11 +00:00
}
else
{
2016-01-23 17:49:10 +00:00
printf ( " Error: cannot open %s \n " , pathContent [ i ] . c_str ( ) ) ;
2012-05-29 13:31:11 +00:00
}
}
}
}
// ---------------------------------------------------------------------------
2016-01-23 11:30:01 +00:00
int main ( int argc , char * * argv )
2012-05-29 13:31:11 +00:00
{
2016-01-23 11:30:01 +00:00
NLMISC : : CApplicationContext myApplicationContext ;
2012-05-29 13:31:11 +00:00
2016-01-23 11:30:01 +00:00
NLMISC : : CCmdArgs args ;
2012-05-29 13:31:11 +00:00
2016-01-23 11:30:01 +00:00
args . addArg ( " p " , " pack " , " " , " Pack the directory to a BNP file " ) ;
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 " ) ;
2016-01-31 18:02:47 +00:00
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 ) ;
2016-01-23 11:30:01 +00:00
args . addAdditionalArg ( " input " , " Input directory or BNP file depending on command " ) ;
2012-05-29 13:31:11 +00:00
2016-01-23 11:30:01 +00:00
if ( ! args . parse ( argc , argv ) ) return 1 ;
2012-05-29 13:31:11 +00:00
2016-01-23 11:30:01 +00:00
if ( args . haveArg ( " p " ) )
2012-05-29 13:31:11 +00:00
{
2016-01-23 11:30:01 +00:00
std : : vector < std : : string > filters ;
2012-05-29 13:31:11 +00:00
// If ?
2016-01-23 11:30:01 +00:00
filters = args . getLongArg ( " if " ) ;
for ( uint i = 0 ; i < filters . size ( ) ; + + i )
2012-05-29 13:31:11 +00:00
{
CWildCard card ;
2016-01-23 11:30:01 +00:00
card . Expression = toLower ( filters [ i ] ) ;
2012-05-29 13:31:11 +00:00
card . Not = false ;
2016-01-23 11:30:01 +00:00
WildCards . push_back ( card ) ;
2012-05-29 13:31:11 +00:00
}
2016-01-23 11:30:01 +00:00
2012-05-29 13:31:11 +00:00
// If not ?
2016-01-23 11:30:01 +00:00
filters = args . getLongArg ( " ifnot " ) ;
for ( uint i = 0 ; i < filters . size ( ) ; + + i )
2012-05-29 13:31:11 +00:00
{
CWildCard card ;
2016-01-23 11:30:01 +00:00
card . Expression = toLower ( filters [ i ] ) ;
2012-05-29 13:31:11 +00:00
card . Not = true ;
2016-01-23 11:30:01 +00:00
WildCards . push_back ( card ) ;
2012-05-29 13:31:11 +00:00
}
// Pack a directory
2016-01-23 11:30:01 +00:00
std : : string srcDirectory = args . getAdditionalArg ( " input " ) . front ( ) ;
2012-05-29 13:31:11 +00:00
2016-01-23 11:30:01 +00:00
if ( ! CFile : : isDirectory ( srcDirectory ) | | ! CFile : : isExists ( srcDirectory ) )
2012-05-29 13:31:11 +00:00
{
2016-01-23 11:30:01 +00:00
nlwarning ( " Error: %s doesn't exist or is not a directory! " , srcDirectory . c_str ( ) ) ;
2012-05-29 13:31:11 +00:00
}
2016-01-23 11:30:01 +00:00
// Output directory or filename
if ( args . haveArg ( " o " ) )
2012-05-29 13:31:11 +00:00
{
2016-01-23 11:30:01 +00:00
gBNPHeader . BigFileName = args . getArg ( " o " ) . front ( ) ;
if ( CFile : : isDirectory ( gBNPHeader . BigFileName ) )
2012-05-29 13:31:11 +00:00
{
2016-01-23 11:30:01 +00:00
gBNPHeader . BigFileName = CPath : : standardizePath ( gBNPHeader . BigFileName ) + CFile : : getFilename ( srcDirectory ) ;
2012-05-29 13:31:11 +00:00
}
}
2016-01-23 11:30:01 +00:00
else
2012-05-29 13:31:11 +00:00
{
2016-01-23 11:30:01 +00:00
gBNPHeader . BigFileName = CFile : : getFilename ( srcDirectory ) ;
2012-05-29 13:31:11 +00:00
}
2016-01-23 11:30:01 +00:00
if ( CFile : : getExtension ( gBNPHeader . BigFileName ) ! = " bnp " )
gBNPHeader . BigFileName + = " .bnp " ;
2012-05-29 13:31:11 +00:00
2016-01-23 11:30:01 +00:00
CFile : : deleteFile ( gBNPHeader . BigFileName ) ;
2012-05-29 13:31:11 +00:00
2016-01-23 11:30:01 +00:00
packSubRecurse ( srcDirectory ) ;
return gBNPHeader . appendHeader ( ) ? 0 : - 1 ;
2012-05-29 13:31:11 +00:00
}
2016-01-23 11:30:01 +00:00
if ( args . haveArg ( " u " ) )
2012-05-29 13:31:11 +00:00
{
2016-01-23 11:30:01 +00:00
gBNPHeader . BigFileName = args . getAdditionalArg ( " input " ) . front ( ) ;
std : : string dirName ;
// Output directory or filename
if ( args . haveArg ( " o " ) )
2012-05-29 13:31:11 +00:00
{
2016-01-23 11:30:01 +00:00
dirName = args . getArg ( " o " ) . front ( ) ;
2012-05-29 13:31:11 +00:00
}
2016-01-23 11:30:01 +00:00
else
2012-05-29 13:31:11 +00:00
{
2016-01-23 11:30:01 +00:00
dirName = CFile : : getFilenameWithoutExtension ( gBNPHeader . BigFileName ) ;
2012-05-29 13:31:11 +00:00
}
// Unpack a bnp file
2016-01-23 11:30:01 +00:00
return gBNPHeader . unpack ( dirName ) ? 0 : - 1 ;
}
2012-05-29 13:31:11 +00:00
2016-01-23 11:30:01 +00:00
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 ( ) ) ;
}
2012-05-29 13:31:11 +00:00
return 0 ;
}
2016-01-23 11:30:01 +00:00
args . displayHelp ( ) ;
2012-05-29 13:31:11 +00:00
return - 1 ;
}