the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 250 lines 6.7 kB view raw
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,&currentSlot,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}