the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
1#include "stdafx.h"
2#include "File.h"
3#include "NbtSlotFile.h"
4
5
6byteArray NbtSlotFile::READ_BUFFER(1024*1024);
7__int64 NbtSlotFile::largest = 0;
8
9NbtSlotFile::NbtSlotFile(File file)
10{
11 totalFileSlots = 0;
12 fileSlotMapLength = ZonedChunkStorage::CHUNKS_PER_ZONE * ZonedChunkStorage::CHUNKS_PER_ZONE;
13 fileSlotMap = new vector<int> *[fileSlotMapLength];
14
15 if ( !file.exists() || file.length() )
16 {
17 raf = CreateFile(wstringtofilename(file.getPath()), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
18 writeHeader();
19 }
20 else
21 {
22 raf = CreateFile(wstringtofilename(file.getPath()), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
23 }
24
25 readHeader();
26
27 for (int i = 0; i < fileSlotMapLength; i++)
28 {
29 fileSlotMap[i] = new vector<int>;
30 }
31
32 DWORD numberofBytesRead;
33 for (int fileSlot = 0; fileSlot < totalFileSlots; fileSlot++)
34 {
35 seekSlotHeader(fileSlot);
36 short slot;
37 ReadFile(raf,&slot,2,&numberofBytesRead,NULL);
38 if (slot == 0)
39 {
40 freeFileSlots.push_back(fileSlot);
41 } else if (slot < 0)
42 {
43 fileSlotMap[(-slot) - 1]->push_back(fileSlot);
44 } else {
45 fileSlotMap[slot - 1]->push_back(fileSlot);
46 }
47 }
48}
49
50void NbtSlotFile::readHeader()
51{
52 DWORD numberOfBytesRead;
53 SetFilePointer(raf,0,0,FILE_BEGIN);
54 int magic;
55 ReadFile(raf,&magic,4,&numberOfBytesRead,NULL);
56// if (magic != MAGIC_NUMBER) throw new IOException("Bad magic number: " + magic); // 4J - TODO
57 short version;
58 ReadFile(raf,&version,2,&numberOfBytesRead,NULL);
59// if (version != 0) throw new IOException("Bad version number: " + version); // 4J - TODO
60 ReadFile(raf,&totalFileSlots,4,&numberOfBytesRead,NULL);
61}
62
63void NbtSlotFile::writeHeader()
64{
65 DWORD numberOfBytesWritten;
66 short version = 0;
67 SetFilePointer(raf,0,0,FILE_BEGIN);
68 WriteFile(raf,&MAGIC_NUMBER,4,&numberOfBytesWritten,NULL);
69 WriteFile(raf,&version,2,&numberOfBytesWritten,NULL);
70 WriteFile(raf,&totalFileSlots,4,&numberOfBytesWritten,NULL);
71}
72
73void NbtSlotFile::seekSlotHeader(int fileSlot)
74{
75 int target = FILE_HEADER_SIZE + fileSlot * (FILE_SLOT_SIZE + FILE_SLOT_HEADER_SIZE);
76 SetFilePointer(raf,target,0,FILE_BEGIN);
77}
78
79void NbtSlotFile::seekSlot(int fileSlot)
80{
81 int target = FILE_HEADER_SIZE + fileSlot * (FILE_SLOT_SIZE + FILE_SLOT_HEADER_SIZE);
82 SetFilePointer(raf,target+FILE_SLOT_HEADER_SIZE,0,FILE_BEGIN);
83}
84
85vector<CompoundTag *> *NbtSlotFile::readAll(int slot)
86{
87 DWORD numberOfBytesRead;
88 vector<CompoundTag *> *tags = new vector<CompoundTag *>;
89 vector<int> *fileSlots = fileSlotMap[slot];
90 int skipped = 0;
91
92 AUTO_VAR(itEnd, fileSlots->end());
93 for (AUTO_VAR(it, fileSlots->begin()); it != itEnd; it++)
94 {
95 int c = *it; //fileSlots->at(i);
96
97 int pos = 0;
98 int continuesAt = -1;
99 int expectedSlot = slot + 1;
100 do
101 {
102 seekSlotHeader(c);
103 short oldSlot;
104 ReadFile(raf,&oldSlot,2,&numberOfBytesRead,NULL);
105 short size;
106 ReadFile(raf,&size,2,&numberOfBytesRead,NULL);
107 ReadFile(raf,&continuesAt,4,&numberOfBytesRead,NULL);
108 int lastSlot;
109 ReadFile(raf,&lastSlot,4,&numberOfBytesRead,NULL);
110
111 seekSlot(c);
112 if (expectedSlot > 0 && oldSlot == -expectedSlot)
113 {
114 skipped++;
115 goto fileSlotLoop; // 4J - used to be continue fileSlotLoop, with for loop labelled as fileSlotLoop
116 }
117
118// if (oldSlot != expectedSlot) throw new IOException("Wrong slot! Got " + oldSlot + ", expected " + expectedSlot); // 4J - TODO
119
120 ReadFile(raf,READ_BUFFER.data + pos,size,&numberOfBytesRead,NULL);
121
122 if (continuesAt >= 0)
123 {
124 pos += size;
125 c = continuesAt;
126 expectedSlot = -slot - 1;
127 }
128 } while (continuesAt >= 0);
129 tags->push_back(NbtIo::decompress(READ_BUFFER));
130fileSlotLoop:
131 continue;
132 }
133
134 return tags;
135
136}
137
138int NbtSlotFile::getFreeSlot()
139{ int fileSlot;
140
141// 4J - removed - don't see how toReplace can ever have anything in here, and might not be initialised
142// if (toReplace->size() > 0)
143// {
144// fileSlot = toReplace->back();
145// toReplace->pop_back();
146// } else
147
148 if (freeFileSlots.size() > 0)
149 {
150 fileSlot = freeFileSlots.back();
151 freeFileSlots.pop_back();
152 }
153 else
154 {
155 fileSlot = totalFileSlots++;
156 writeHeader();
157 }
158
159 return fileSlot;
160
161}
162void NbtSlotFile::replaceSlot(int slot, vector<CompoundTag *> *tags)
163{
164 DWORD numberOfBytesWritten;
165 toReplace = fileSlotMap[slot];
166 fileSlotMap[slot] = new vector<int>();
167
168 AUTO_VAR(itEndTags, tags->end());
169 for (AUTO_VAR(it, tags->begin()); it != itEndTags; it++)
170 {
171 CompoundTag *tag = *it; //tags->at(i);
172 byteArray compressed = NbtIo::compress(tag);
173 if (compressed.length > largest)
174 {
175 wchar_t buf[256];
176 largest = compressed.length;
177#ifndef _CONTENT_PACKAGE
178 swprintf(buf, 256, L"New largest: %I64d (%ls)\n",largest,tag->getString(L"id").c_str() );
179 OutputDebugStringW(buf);
180#endif
181 }
182
183 int pos = 0;
184 int remaining = compressed.length;
185 if (remaining == 0) continue;
186
187 int nextFileSlot = getFreeSlot();
188 short currentSlot = slot + 1;
189 int lastFileSlot = -1;
190
191 while (remaining > 0)
192 {
193 int fileSlot = nextFileSlot;
194 fileSlotMap[slot]->push_back(fileSlot);
195
196 short toWrite = remaining;
197 if (toWrite > FILE_SLOT_SIZE)
198 {
199 toWrite = FILE_SLOT_SIZE;
200 }
201
202 remaining -= toWrite;
203 if (remaining > 0)
204 {
205 nextFileSlot = getFreeSlot();
206 }
207 else
208 {
209 nextFileSlot = -1;
210 }
211
212 seekSlotHeader(fileSlot);
213 WriteFile(raf,¤tSlot,2,&numberOfBytesWritten,NULL);
214 WriteFile(raf,&toWrite,2,&numberOfBytesWritten,NULL);
215 WriteFile(raf,&nextFileSlot,4,&numberOfBytesWritten,NULL);
216 WriteFile(raf,&lastFileSlot,4,&numberOfBytesWritten,NULL);
217
218 seekSlot(fileSlot);
219 WriteFile(raf,compressed.data+pos,toWrite,&numberOfBytesWritten,NULL);
220
221 if (remaining > 0)
222 {
223 lastFileSlot = fileSlot;
224 pos += toWrite;
225 currentSlot = -slot - 1;
226 }
227 }
228 delete[] compressed.data;
229 }
230
231 AUTO_VAR(itEndToRep, toReplace->end());
232 for (AUTO_VAR(it, toReplace->begin()); it != itEndToRep; it++)
233 {
234 int c = *it; //toReplace->at(i);
235
236 freeFileSlots.push_back(c);
237
238 seekSlotHeader(c);
239 short zero = 0;
240 WriteFile(raf,&zero,2,&numberOfBytesWritten,NULL);
241 }
242
243 toReplace->clear();
244
245}
246
247void NbtSlotFile::close()
248{
249 CloseHandle(raf);
250}