Linux multi-monitor fullscreen support
[ryzomcore.git] / nel / tools / misc / bnp_make / main.cpp
blob823962f59b3ee240f843eeab4c297fab0e6b0d5e
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010-2020 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
6 //
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "nel/misc/types_nl.h"
22 #include <stdio.h>
23 #include <stdlib.h>
25 #ifdef NL_OS_WINDOWS
26 # include <io.h>
27 # include <direct.h>
28 #endif
30 #include <vector>
31 #include <string>
33 #include "nel/misc/debug.h"
34 #include "nel/misc/file.h"
35 #include "nel/misc/path.h"
36 #include "nel/misc/algo.h"
37 #include "nel/misc/common.h"
38 #include "nel/misc/big_file.h"
39 #include "nel/misc/cmd_args.h"
42 using namespace std;
43 using namespace NLMISC;
45 // ---------------------------------------------------------------------------
47 class CWildCard
49 public:
50 string Expression;
51 bool Not;
53 std::vector<CWildCard> WildCards;
55 // ---------------------------------------------------------------------------
57 bool keepFile (const std::string &fileName)
59 uint i;
60 bool ifPresent = false;
61 bool ifTrue = false;
62 string file = toLowerAscii(CFile::getFilename (fileName));
63 for (i=0; i<WildCards.size(); i++)
65 if (WildCards[i].Not)
67 // One ifnot condition met and the file is not added
68 if (testWildCard(file, WildCards[i].Expression))
69 return false;
71 else
73 ifPresent = true;
74 ifTrue |= testWildCard(file, WildCards[i].Expression);
78 return !ifPresent || ifTrue;
81 // ---------------------------------------------------------------------------
83 NLMISC::CBigFile::BNP gBNPHeader;
85 // ---------------------------------------------------------------------------
86 bool i_comp(const string &s0, const string &s1)
88 return nlstricmp (CFile::getFilename(s0).c_str(), CFile::getFilename(s1).c_str()) < 0;
91 bool packSubRecurse(const std::string &srcDirectory)
93 vector<string> pathContent;
95 printf ("Treating directory: %s\n", srcDirectory.c_str());
96 CPath::getPathContent(srcDirectory, true, false, true, pathContent);
98 if (pathContent.empty()) return true;
100 // Sort filename
101 sort (pathContent.begin(), pathContent.end(), i_comp);
103 // check for files with same name
104 for(uint i = 1, len = pathContent.size(); i < len; ++i)
106 if (toLowerAscii(CFile::getFilename(pathContent[i-1])) == toLowerAscii(CFile::getFilename(pathContent[i])))
108 nlwarning("File %s is not unique in BNP!", CFile::getFilename(pathContent[i]).c_str());
109 return false;
113 for (uint i=0; i<pathContent.size(); ++i)
115 if (keepFile(pathContent[i]))
117 if (gBNPHeader.appendFile(pathContent[i]))
119 printf("Adding %s\n", pathContent[i].c_str());
121 else
123 printf("Error: cannot open %s\n", pathContent[i].c_str());
128 return true;
131 // ---------------------------------------------------------------------------
132 int main(int argc, char **argv)
134 NLMISC::CApplicationContext myApplicationContext;
136 NLMISC::CCmdArgs args;
138 args.addArg("p", "pack", "", "Pack the directory to a BNP file");
139 args.addArg("u", "unpack", "", "Unpack the BNP file to a directory");
140 args.addArg("l", "list", "", "List the files contained in the BNP file");
141 args.addArg("o", "output", "destination", "Output directory or file");
142 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);
143 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);
144 args.addArg("", "list-verbose", "", "List files using 'pos size name' format");
145 args.addArg("", "extract", "name", "Extract file(s) from BNP into --output");
146 args.addAdditionalArg("input", "Input directory or BNP file depending on command");
148 if (!args.parse(argc, argv)) return 1;
150 if (args.haveArg("p"))
152 std::vector<std::string> filters;
154 // If ?
155 filters = args.getLongArg("if");
157 for (uint i = 0; i < filters.size(); ++i)
159 CWildCard card;
160 card.Expression = toLowerAscii(filters[i]);
161 card.Not = false;
162 WildCards.push_back(card);
165 // If not ?
166 filters = args.getLongArg("ifnot");
168 for (uint i = 0; i < filters.size(); ++i)
170 CWildCard card;
171 card.Expression = toLowerAscii(filters[i]);
172 card.Not = true;
173 WildCards.push_back(card);
176 // Pack a directory
177 std::string srcDirectory = args.getAdditionalArg("input").front();
179 if (!CFile::isDirectory(srcDirectory) || !CFile::isExists(srcDirectory))
181 nlwarning("Error: %s doesn't exist or is not a directory!", srcDirectory.c_str());
184 // Output directory or filename
185 if (args.haveArg("o"))
187 gBNPHeader.BigFileName = args.getArg("o").front();
189 if (CFile::isDirectory(gBNPHeader.BigFileName))
191 gBNPHeader.BigFileName = CPath::standardizePath(gBNPHeader.BigFileName) + CFile::getFilename(srcDirectory);
194 else
196 gBNPHeader.BigFileName = CFile::getFilename(srcDirectory);
199 if (CFile::getExtension(gBNPHeader.BigFileName) != "bnp")
200 gBNPHeader.BigFileName += ".bnp";
202 CFile::deleteFile(gBNPHeader.BigFileName);
204 if (!packSubRecurse(srcDirectory)) return 1;
206 return gBNPHeader.appendHeader() ? 0:-1;
209 if (args.haveArg("u"))
211 gBNPHeader.BigFileName = args.getAdditionalArg("input").front();
213 std::string dirName;
215 // Output directory or filename
216 if (args.haveArg("o"))
218 dirName = args.getArg("o").front();
220 else
222 dirName = CFile::getFilenameWithoutExtension(gBNPHeader.BigFileName);
225 // Unpack a bnp file
226 return gBNPHeader.unpack(dirName) ? 0:-1;
229 if (args.haveArg("l"))
231 gBNPHeader.BigFileName = args.getAdditionalArg("input").front();
233 // Read header of BNP file
234 if (!gBNPHeader.readHeader()) return -1;
236 for (uint i = 0; i < gBNPHeader.SFiles.size(); ++i)
238 printf("%s\n", gBNPHeader.SFiles[i].Name.c_str());
241 return 0;
244 if (args.haveLongArg("list-verbose"))
246 gBNPHeader.BigFileName = args.getAdditionalArg("input").front();
248 // Read header of BNP file
249 if (!gBNPHeader.readHeader()) return -1;
251 for (uint i = 0; i < gBNPHeader.SFiles.size(); ++i)
253 printf("%u %u %s\n", gBNPHeader.SFiles[i].Pos, gBNPHeader.SFiles[i].Size, gBNPHeader.SFiles[i].Name.c_str());
256 return 0;
259 // --extract <name>
260 if (args.haveLongArg("extract") && !args.getLongArg("extract").empty())
262 std::string bnpName = args.getAdditionalArg("input").front();
263 CBigFile::getInstance().add(bnpName, BF_ALWAYS_OPENED);
265 // Output directory or filename
266 if (!args.haveArg("o") || args.getArg("o").empty())
268 nlerror("Output file or directory not set");
271 std::string srcName = args.getLongArg("extract").front();
272 std::string dstName = args.getArg("o").front();
273 if (CFile::fileExists(dstName) && CFile::isDirectory(dstName))
275 dstName += "/" + srcName;
278 CIFile inFile;
279 // bnpName without path
280 if (!inFile.open(CFile::getFilename(bnpName) + "@" + srcName))
282 nlerror("Unable to open '%s' for reading", inFile.getStreamName().c_str());
285 COFile outFile;
286 if (!outFile.open(dstName))
288 nlerror("Unable to open '%s' for writing", outFile.getStreamName().c_str());
291 std::string buf;
292 inFile.readAll(buf);
293 outFile.serialBuffer((uint8 *)&buf[0], buf.size());
295 return 0;
298 args.displayHelp();
299 return -1;