4jcraft/Minecraft.World/Level/Storage/ZoneFile.cpp
2026-03-13 17:06:56 -05:00

106 lines
3.1 KiB
C++

#include "../../Platform/stdafx.h"
#include "../../IO/Streams/ByteBuffer.h"
#include "../../IO/Files/File.h"
#include "ZoneFile.h"
namespace {
std::FILE* OpenBinaryFileForReadWrite(const File& file) {
#if defined(_WIN32)
std::FILE* stream = _wfopen(file.getPath().c_str(), L"r+b");
if (stream == NULL) {
stream = _wfopen(file.getPath().c_str(), L"w+b");
}
#else
const std::string nativePath = wstringtofilename(file.getPath());
std::FILE* stream = std::fopen(nativePath.c_str(), "r+b");
if (stream == NULL) {
stream = std::fopen(nativePath.c_str(), "w+b");
}
#endif
return stream;
}
} // namespace
const int ZoneFile::slotsLength =
ZonedChunkStorage::CHUNKS_PER_ZONE * ZonedChunkStorage::CHUNKS_PER_ZONE;
ZoneFile::ZoneFile(__int64 key, File file, File entityFile)
: slots(slotsLength) {
lastUse = 0;
this->key = key;
this->file = file;
// 4J - try/catch removed
// try {
this->entityFile = new NbtSlotFile(entityFile);
// } catch (Exception e) {
// System.out.println("Broken entity file: " + entityFile + " (" +
// e.toString() + "), replacing.."); entityFile.delete();
// entityFile.createNewFile();
// this.entityFile = new NbtSlotFile(entityFile);
// }
channel = OpenBinaryFileForReadWrite(file);
// 4J - try/catch removed
// try {
readHeader();
// } catch (Exception e) {
// e.printStackTrace();
// throw new IOException("Broken zone file: " + file + ": " + e);
// }
}
ZoneFile::~ZoneFile() { delete[] slots.data; }
void ZoneFile::readHeader() {
ZoneIo* zoneIo = new ZoneIo(channel, 0);
ByteBuffer* bb = zoneIo->read(FILE_HEADER_SIZE);
bb->flip();
if (bb->remaining() < 5) return;
int magic = bb->getInt();
// if (magic != MAGIC_NUMBER) throw new IOException("Bad magic number: "
// + magic); // 4J - TODO
short version = bb->getShort();
// if (version != 0) throw new IOException("Bad version number: " +
// version); // 4J - TODO
slotCount = bb->getShort();
bb->getShortArray(slots);
bb->position(bb->position() + slotsLength * 2);
}
void ZoneFile::writeHeader() {
ZoneIo* zoneIo = new ZoneIo(channel, 0);
ByteBuffer* bb = ByteBuffer::allocate(FILE_HEADER_SIZE);
bb->order(ZonedChunkStorage::BYTEORDER);
bb->putInt(MAGIC_NUMBER);
bb->putShort((short)0);
bb->putShort((short)slotCount);
bb->putShortArray(slots);
bb->position(bb->position() + slots.length * 2);
bb->flip();
zoneIo->write(bb, FILE_HEADER_SIZE);
}
void ZoneFile::close() {
if (channel != NULL) {
std::fclose(channel);
channel = NULL;
}
entityFile->close();
}
ZoneIo* ZoneFile::getZoneIo(int slot) {
if (slots[slot] == 0) {
slots[slot] = ++slotCount;
writeHeader();
}
int byteOffs = (slots[slot] - 1) * ZonedChunkStorage::CHUNK_SIZE_BYTES +
FILE_HEADER_SIZE;
return new ZoneIo(channel, byteOffs);
}
bool ZoneFile::containsSlot(int slot) { return slots[slot] > 0; }