mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2024-12-23 11:50:04 +00:00
Reimplement chunk data caching
This commit is contained in:
parent
82b505a737
commit
95b385dee1
@ -20,6 +20,37 @@ void ChunkManager::newChunk(ChunkPos pos) {
|
||||
chunk->NPCs = std::set<int32_t>();
|
||||
|
||||
chunks[pos] = chunk;
|
||||
|
||||
// add the chunk to the cache of all players and NPCs in the surrounding chunks
|
||||
std::set<Chunk*> surroundings = getViewableChunks(pos);
|
||||
for (Chunk* c : surroundings) {
|
||||
for (CNSocket* sock : c->players)
|
||||
PlayerManager::getPlayer(sock)->viewableChunks->insert(chunk);
|
||||
for (int32_t id : c->NPCs)
|
||||
NPCManager::NPCs[id]->viewableChunks->insert(chunk);
|
||||
}
|
||||
}
|
||||
|
||||
void ChunkManager::deleteChunk(ChunkPos pos) {
|
||||
if (!chunkExists(pos)) {
|
||||
std::cout << "[WARN] Tried to delete a chunk that doesn't exist\n";
|
||||
return;
|
||||
}
|
||||
|
||||
Chunk* chunk = chunks[pos];
|
||||
|
||||
// remove the chunk from the cache of all players and NPCs in the surrounding chunks
|
||||
std::set<Chunk*> surroundings = getViewableChunks(pos);
|
||||
for(Chunk* c : surroundings)
|
||||
{
|
||||
for (CNSocket* sock : c->players)
|
||||
PlayerManager::getPlayer(sock)->viewableChunks->erase(chunk);
|
||||
for (int32_t id : c->NPCs)
|
||||
NPCManager::NPCs[id]->viewableChunks->erase(chunk);
|
||||
}
|
||||
|
||||
chunks.erase(pos); // remove from map
|
||||
delete chunk; // free from memory
|
||||
}
|
||||
|
||||
void ChunkManager::updatePlayerChunk(CNSocket* sock, ChunkPos from, ChunkPos to) {
|
||||
@ -53,6 +84,9 @@ void ChunkManager::updatePlayerChunk(CNSocket* sock, ChunkPos from, ChunkPos to)
|
||||
addPlayerToChunks(toEnter, sock);
|
||||
|
||||
plr->chunkPos = to; // update cached chunk position
|
||||
// updated cached viewable chunks
|
||||
plr->viewableChunks->clear();
|
||||
plr->viewableChunks->insert(newViewables.begin(), newViewables.end());
|
||||
}
|
||||
|
||||
void ChunkManager::updateNPCChunk(int32_t id, ChunkPos from, ChunkPos to) {
|
||||
@ -85,7 +119,10 @@ void ChunkManager::updateNPCChunk(int32_t id, ChunkPos from, ChunkPos to) {
|
||||
removeNPCFromChunks(toExit, id);
|
||||
addNPCToChunks(toEnter, id);
|
||||
|
||||
npc->chunkPos = to;
|
||||
npc->chunkPos = to; // update cached chunk position
|
||||
// updated cached viewable chunks
|
||||
npc->viewableChunks->clear();
|
||||
npc->viewableChunks->insert(newViewables.begin(), newViewables.end());
|
||||
}
|
||||
|
||||
void ChunkManager::trackPlayer(ChunkPos chunkPos, CNSocket* sock) {
|
||||
@ -111,10 +148,8 @@ void ChunkManager::untrackPlayer(ChunkPos chunkPos, CNSocket* sock) {
|
||||
chunk->players.erase(sock); // gone
|
||||
|
||||
// if chunk is empty, free it
|
||||
if (chunk->NPCs.size() == 0 && chunk->players.size() == 0) {
|
||||
chunks.erase(chunkPos); // remove from map
|
||||
delete chunk; // free from memory
|
||||
}
|
||||
if (chunk->NPCs.size() == 0 && chunk->players.size() == 0)
|
||||
deleteChunk(chunkPos);
|
||||
}
|
||||
|
||||
void ChunkManager::untrackNPC(ChunkPos chunkPos, int32_t id) {
|
||||
@ -126,10 +161,8 @@ void ChunkManager::untrackNPC(ChunkPos chunkPos, int32_t id) {
|
||||
chunk->NPCs.erase(id); // gone
|
||||
|
||||
// if chunk is empty, free it
|
||||
if (chunk->NPCs.size() == 0 && chunk->players.size() == 0) {
|
||||
chunks.erase(chunkPos); // remove from map
|
||||
delete chunk; // free from memory
|
||||
}
|
||||
if (chunk->NPCs.size() == 0 && chunk->players.size() == 0)
|
||||
deleteChunk(chunkPos);
|
||||
}
|
||||
|
||||
void ChunkManager::addPlayerToChunks(std::set<Chunk*> chnks, CNSocket* sock) {
|
||||
@ -394,11 +427,10 @@ std::vector<ChunkPos> ChunkManager::getChunksInMap(uint64_t mapNum) {
|
||||
return chnks;
|
||||
}
|
||||
|
||||
bool ChunkManager::inPopulatedChunks(int posX, int posY, uint64_t instanceID) {
|
||||
auto nearbyChunks = ChunkManager::getViewableChunks(chunkPosAt(posX, posY, instanceID));
|
||||
bool ChunkManager::inPopulatedChunks(std::set<Chunk*>* chnks) {
|
||||
|
||||
for (Chunk *c: nearbyChunks) {
|
||||
if (!c->players.empty())
|
||||
for (auto it = chnks->begin(); it != chnks->end(); it++) {
|
||||
if (!(*it)->players.empty())
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@ namespace ChunkManager {
|
||||
extern std::map<ChunkPos, Chunk*> chunks;
|
||||
|
||||
void newChunk(ChunkPos pos);
|
||||
void deleteChunk(ChunkPos pos);
|
||||
|
||||
void updatePlayerChunk(CNSocket* sock, ChunkPos from, ChunkPos to);
|
||||
void updateNPCChunk(int32_t id, ChunkPos from, ChunkPos to);
|
||||
@ -48,7 +49,7 @@ namespace ChunkManager {
|
||||
std::set<Chunk*> getViewableChunks(ChunkPos chunkPos);
|
||||
|
||||
std::vector<ChunkPos> getChunksInMap(uint64_t mapNum);
|
||||
bool inPopulatedChunks(int posX, int posY, uint64_t instanceID);
|
||||
bool inPopulatedChunks(std::set<Chunk*>* chnks);
|
||||
void createInstance(uint64_t);
|
||||
void destroyInstance(uint64_t);
|
||||
void destroyInstanceIfEmpty(uint64_t);
|
||||
|
@ -689,11 +689,9 @@ void MobManager::retreatStep(Mob *mob, time_t currTime) {
|
||||
|
||||
void MobManager::step(CNServer *serv, time_t currTime) {
|
||||
for (auto& pair : Mobs) {
|
||||
int x = pair.second->appearanceData.iX;
|
||||
int y = pair.second->appearanceData.iY;
|
||||
|
||||
// skip chunks without players
|
||||
if (!ChunkManager::inPopulatedChunks(x, y, pair.second->instanceID))
|
||||
if (!ChunkManager::inPopulatedChunks(pair.second->viewableChunks))
|
||||
continue;
|
||||
|
||||
// skip mob movement and combat if disabled
|
||||
@ -1115,8 +1113,8 @@ bool MobManager::aggroCheck(Mob *mob, time_t currTime) {
|
||||
CNSocket *closest = nullptr;
|
||||
int closestDistance = INT_MAX;
|
||||
|
||||
std::set<Chunk*> chunks = ChunkManager::getViewableChunks(mob->chunkPos);
|
||||
for (Chunk *chunk : chunks) {
|
||||
for (auto it = mob->viewableChunks->begin(); it != mob->viewableChunks->end(); it++) {
|
||||
Chunk* chunk = *it;
|
||||
for (CNSocket *s : chunk->players) {
|
||||
Player *plr = s->plr;
|
||||
|
||||
|
@ -9,6 +9,7 @@ public:
|
||||
NPCClass npcClass;
|
||||
uint64_t instanceID;
|
||||
ChunkPos chunkPos;
|
||||
std::set<Chunk*>* viewableChunks;
|
||||
|
||||
BaseNPC() {};
|
||||
BaseNPC(int x, int y, int z, int angle, uint64_t iID, int type, int id) {
|
||||
@ -25,6 +26,7 @@ public:
|
||||
instanceID = iID;
|
||||
|
||||
chunkPos = std::make_tuple(0, 0, 0);
|
||||
viewableChunks = new std::set<Chunk*>();
|
||||
};
|
||||
BaseNPC(int x, int y, int z, int angle, uint64_t iID, int type, int id, NPCClass classType) : BaseNPC(x, y, z, angle, iID, type, id) {
|
||||
npcClass = classType;
|
||||
|
@ -103,8 +103,8 @@ void NPCManager::updateNPCPosition(int32_t id, int X, int Y, int Z, uint64_t I,
|
||||
}
|
||||
|
||||
void NPCManager::sendToViewable(BaseNPC *npc, void *buf, uint32_t type, size_t size) {
|
||||
std::set<Chunk*> chunks = ChunkManager::getViewableChunks(npc->chunkPos);
|
||||
for (Chunk *chunk : chunks) {
|
||||
for (auto it = npc->viewableChunks->begin(); it != npc->viewableChunks->end(); it++) {
|
||||
Chunk* chunk = *it;
|
||||
for (CNSocket *s : chunk->players) {
|
||||
s->sendPacket(buf, type, size);
|
||||
}
|
||||
@ -718,7 +718,7 @@ void NPCManager::eggStep(CNServer* serv, time_t currTime) {
|
||||
|
||||
// check dead eggs and eggs in inactive chunks
|
||||
for (auto egg : Eggs) {
|
||||
if (!egg.second->dead || !ChunkManager::inPopulatedChunks(egg.second->appearanceData.iX, egg.second->appearanceData.iY, egg.second->instanceID))
|
||||
if (!egg.second->dead || !ChunkManager::inPopulatedChunks(egg.second->viewableChunks))
|
||||
continue;
|
||||
if (egg.second->deadUntil <= timeStamp) {
|
||||
// respawn it
|
||||
|
@ -78,5 +78,6 @@ struct Player {
|
||||
int64_t buddyIDs[50];
|
||||
|
||||
ChunkPos chunkPos;
|
||||
std::set<Chunk*>* viewableChunks;
|
||||
time_t lastHeartbeat;
|
||||
};
|
||||
|
@ -54,6 +54,7 @@ void PlayerManager::addPlayer(CNSocket* key, Player plr) {
|
||||
|
||||
players[key] = p;
|
||||
p->chunkPos = std::make_tuple(0, 0, 0);
|
||||
p->viewableChunks = new std::set<Chunk*>();
|
||||
p->lastHeartbeat = 0;
|
||||
|
||||
key->plr = p;
|
||||
@ -291,8 +292,8 @@ void PlayerManager::enterPlayer(CNSocket* sock, CNPacketData* data) {
|
||||
|
||||
void PlayerManager::sendToViewable(CNSocket* sock, void* buf, uint32_t type, size_t size) {
|
||||
Player* plr = getPlayer(sock);
|
||||
std::set<Chunk*> chunks = ChunkManager::getViewableChunks(plr->chunkPos);
|
||||
for (Chunk* chunk : chunks) {
|
||||
for (auto it = plr->viewableChunks->begin(); it != plr->viewableChunks->end(); it++) {
|
||||
Chunk* chunk = *it;
|
||||
for (CNSocket* otherSock : chunk->players) {
|
||||
if (otherSock == sock)
|
||||
continue;
|
||||
|
Loading…
Reference in New Issue
Block a user