1/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
2/* If you are missing that file, acquire a complete release at teeworlds.com. */
3
4#include <base/logger.h>
5#include <base/os.h>
6#include <base/system.h>
7
8#include <engine/shared/datafile.h>
9#include <engine/storage.h>
10
11static const char *TOOL_NAME = "map_resave";
12
13static int ResaveMap(const char *pSourceMap, const char *pDestinationMap, IStorage *pStorage)
14{
15 CDataFileReader Reader;
16 if(!Reader.Open(pStorage, pPath: pSourceMap, StorageType: IStorage::TYPE_ABSOLUTE))
17 {
18 log_error(TOOL_NAME, "Failed to open source map '%s' for reading", pSourceMap);
19 return -1;
20 }
21
22 CDataFileWriter Writer;
23 if(!Writer.Open(pStorage, pFilename: pDestinationMap))
24 {
25 log_error(TOOL_NAME, "Failed to open destination map '%s' for writing", pDestinationMap);
26 Reader.Close();
27 return -1;
28 }
29
30 // add all items
31 for(int Index = 0; Index < Reader.NumItems(); Index++)
32 {
33 int Type, Id;
34 CUuid Uuid;
35 const void *pPtr = Reader.GetItem(Index, pType: &Type, pId: &Id, pUuid: &Uuid);
36
37 // Filter ITEMTYPE_EX items, they will be automatically added again.
38 if(Type == ITEMTYPE_EX)
39 {
40 continue;
41 }
42
43 int Size = Reader.GetItemSize(Index);
44 Writer.AddItem(Type, Id, Size, pData: pPtr, pUuid: &Uuid);
45 }
46
47 // add all data
48 for(int Index = 0; Index < Reader.NumData(); Index++)
49 {
50 const void *pPtr = Reader.GetData(Index);
51 int Size = Reader.GetDataSize(Index);
52 Writer.AddData(Size, pData: pPtr);
53 }
54
55 Reader.Close();
56 Writer.Finish();
57 log_info(TOOL_NAME, "Resaved '%s' to '%s'", pSourceMap, pDestinationMap);
58 return 0;
59}
60
61int main(int argc, const char **argv)
62{
63 CCmdlineFix CmdlineFix(&argc, &argv);
64 log_set_global_logger_default();
65
66 if(argc != 3)
67 {
68 log_error(TOOL_NAME, "Usage: %s <source map> <destination map>", TOOL_NAME);
69 return -1;
70 }
71
72 std::unique_ptr<IStorage> pStorage = std::unique_ptr<IStorage>(CreateStorage(InitializationType: IStorage::EInitializationType::BASIC, NumArgs: argc, ppArguments: argv));
73 if(!pStorage)
74 {
75 log_error(TOOL_NAME, "Error creating basic storage");
76 return -1;
77 }
78
79 return ResaveMap(pSourceMap: argv[1], pDestinationMap: argv[2], pStorage: pStorage.get());
80}
81