* Finish ExternalFileLevelStorage.

This commit is contained in:
iProgramInCpp
2023-08-02 09:58:26 +03:00
parent 3eb8062d06
commit 16e2b79165
4 changed files with 85 additions and 3 deletions

View File

@@ -35,7 +35,7 @@ void LevelData::read(RakNet::BitStream& bs, int version)
field_78 = std::string(rs.C_String());
}
void LevelData::write(RakNet::BitStream& bs, int d)
void LevelData::write(RakNet::BitStream& bs)
{
bs.Write(m_seed);
bs.Write(m_spawnPos.x);

View File

@@ -37,7 +37,7 @@ struct LevelData
LevelData(TLong seed, const std::string&, int);
void read(RakNet::BitStream& bs, int d);
void write(RakNet::BitStream& bs, int d);
void write(RakNet::BitStream& bs);
TLong m_seed = 0;
Pos m_spawnPos;

View File

@@ -1,5 +1,8 @@
#include "ExternalFileLevelStorage.hpp"
#include "LevelChunk.hpp"
#include "Level.hpp"
#include "GetTime.h"
#define C_CHUNKS_TO_SAVE_PER_TICK (2)
ExternalFileLevelStorage::ExternalFileLevelStorage(const std::string& a, const std::string& path) :
field_8(a),
@@ -76,6 +79,57 @@ void ExternalFileLevelStorage::closeAll()
void ExternalFileLevelStorage::tick()
{
m_timer++;
if (m_timer % 50 != 0 || !m_pLevel)
return;
for (int z = 0; z < C_MAX_CHUNKS_Z; z++)
{
for (int x = 0; x < C_MAX_CHUNKS_X; x++)
{
LevelChunk* pChunk = m_pLevel->getChunk(x, z);
if (!pChunk || !pChunk->m_bUnsaved)
continue;
int index = x + z * 16;
auto iter = m_unsavedLevelChunks.begin();
for (; iter != m_unsavedLevelChunks.end(); ++iter)
{
if (iter->m_index == index)
{
iter->m_foundTime = RakNet::GetTimeMS();
break;
}
}
if (iter == m_unsavedLevelChunks.end())
{
UnsavedLevelChunk ulc = { index, RakNet::GetTimeMS(), pChunk };
m_unsavedLevelChunks.push_back(ulc);
}
pChunk->m_bUnsaved = false;
}
}
int count = 0;
while (count < C_CHUNKS_TO_SAVE_PER_TICK && !m_unsavedLevelChunks.empty())
{
count++;
auto iter = m_unsavedLevelChunks.begin();
for (auto it2 = m_unsavedLevelChunks.begin(); it2 != m_unsavedLevelChunks.end(); ++it2)
{
if (iter->m_foundTime > it2->m_foundTime)
iter = it2;
}
LevelChunk* pChunk = iter->m_pChunk;
m_unsavedLevelChunks.erase(iter);
save(m_pLevel, pChunk);
}
}
void ExternalFileLevelStorage::flush()
@@ -223,3 +277,22 @@ _cleanup:
fclose(pFile);
return false;
}
bool ExternalFileLevelStorage::writeLevelData(const std::string& path, LevelData* pLevelData)
{
FILE* pFile = fopen(path.c_str(), "wb");
if (!pFile)
return false;
RakNet::BitStream bs;
pLevelData->write(bs);
fwrite(&pLevelData->field_20, sizeof(int), 1, pFile);
int length = bs.GetNumberOfBytesUsed();
fwrite(&length, sizeof(int), 1, pFile);
fwrite(bs.GetData(), 1, length, pFile);
fclose(pFile);
return true;
}

View File

@@ -7,6 +7,13 @@
#ifndef DEMO
struct UnsavedLevelChunk
{
int m_index;
int m_foundTime;
LevelChunk* m_pChunk;
};
class ExternalFileLevelStorage : public LevelStorage, ChunkStorage
{
public:
@@ -28,6 +35,7 @@ public:
static bool readLevelData(const std::string& path, LevelData* pLevelData);
static bool readPlayerData(const std::string& path, LevelData* pLevelData);
static bool writeLevelData(const std::string& path, LevelData* pLevelData);
public:
std::string field_8;
@@ -35,6 +43,7 @@ public:
LevelData* m_pLevelData = nullptr;
RegionFile* m_pRegionFile = nullptr;
Level* m_pLevel = nullptr;
int m_timer = 0;
std::list<UnsavedLevelChunk> m_unsavedLevelChunks;
};