mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/4jcraft.git
synced 2026-05-28 15:05:25 +00:00
TU19: merge Minecraft.Client/Network
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
#include "../MinecraftServer.h"
|
||||
#include "../../Minecraft.World/Headers/net.minecraft.network.packet.h"
|
||||
#include "../../Minecraft.World/Headers/net.minecraft.world.level.h"
|
||||
#include "../../Minecraft.World/Headers/net.minecraft.world.level.chunk.h"
|
||||
#include "../../Minecraft.World/Headers/net.minecraft.world.level.tile.h"
|
||||
#include "../../Minecraft.World/Util/ArrayWithLength.h"
|
||||
#include "../../Minecraft.World/Platform/System.h"
|
||||
@@ -23,19 +24,12 @@ PlayerChunkMap::PlayerChunk::PlayerChunk(int x, int z, PlayerChunkMap* pcm)
|
||||
parent = pcm; // 4J added
|
||||
ticksToNextRegionUpdate = 0; // 4J added
|
||||
prioritised = false; // 4J added
|
||||
firstInhabitedTime = 0;
|
||||
|
||||
parent->getLevel()->cache->create(x, z);
|
||||
// 4J - added make sure our lights are up to date as soon as we make it.
|
||||
// This is of particular concern for local clients, who have their data
|
||||
// shared as soon as the chunkvisibilitypacket is sent, and so could
|
||||
// potentially create render data for this chunk before it has been properly
|
||||
// lit.
|
||||
while (parent->getLevel()->updateLights());
|
||||
}
|
||||
|
||||
PlayerChunkMap::PlayerChunk::~PlayerChunk() {
|
||||
delete[] changedTiles.data; // 4jcraft, changed to []
|
||||
}
|
||||
PlayerChunkMap::PlayerChunk::~PlayerChunk() { delete changedTiles.data; }
|
||||
|
||||
// 4J added - construct an an array of flags that indicate which entities are
|
||||
// still waiting to have network packets sent out to say that they have been
|
||||
@@ -77,6 +71,10 @@ void PlayerChunkMap::PlayerChunk::add(std::shared_ptr<ServerPlayer> player,
|
||||
player->connection->send(std::shared_ptr<ChunkVisibilityPacket>(
|
||||
new ChunkVisibilityPacket(pos.x, pos.z, true)));
|
||||
|
||||
if (players.empty()) {
|
||||
firstInhabitedTime = parent->level->getGameTime();
|
||||
}
|
||||
|
||||
players.push_back(player);
|
||||
|
||||
player->chunksToSend.push_back(pos);
|
||||
@@ -103,7 +101,14 @@ void PlayerChunkMap::PlayerChunk::remove(std::shared_ptr<ServerPlayer> player) {
|
||||
|
||||
players.erase(it);
|
||||
if (players.size() == 0) {
|
||||
__int64 id = (pos.x + 0x7fffffffLL) | ((pos.z + 0x7fffffffLL) << 32);
|
||||
{
|
||||
LevelChunk* chunk = parent->level->getChunk(pos.x, pos.z);
|
||||
updateInhabitedTime(chunk);
|
||||
AUTO_VAR(it, find(parent->knownChunks.begin(),
|
||||
parent->knownChunks.end(), this));
|
||||
if (it != parent->knownChunks.end()) parent->knownChunks.erase(it);
|
||||
}
|
||||
int64_t id = (pos.x + 0x7fffffffLL) | ((pos.z + 0x7fffffffLL) << 32);
|
||||
AUTO_VAR(it, parent->chunks.find(id));
|
||||
if (it != parent->chunks.end()) {
|
||||
toDelete = it->second; // Don't delete until the end of the
|
||||
@@ -157,6 +162,16 @@ void PlayerChunkMap::PlayerChunk::remove(std::shared_ptr<ServerPlayer> player) {
|
||||
delete toDelete;
|
||||
}
|
||||
|
||||
void PlayerChunkMap::PlayerChunk::updateInhabitedTime() {
|
||||
updateInhabitedTime(parent->level->getChunk(pos.x, pos.z));
|
||||
}
|
||||
|
||||
void PlayerChunkMap::PlayerChunk::updateInhabitedTime(LevelChunk* chunk) {
|
||||
chunk->inhabitedTime += parent->level->getGameTime() - firstInhabitedTime;
|
||||
|
||||
firstInhabitedTime = parent->level->getGameTime();
|
||||
}
|
||||
|
||||
void PlayerChunkMap::PlayerChunk::tileChanged(int x, int y, int z) {
|
||||
if (changes == 0) {
|
||||
parent->changedChunks.push_back(this);
|
||||
@@ -386,6 +401,7 @@ PlayerChunkMap::PlayerChunkMap(ServerLevel* level, int dimension, int radius) {
|
||||
this->radius = radius;
|
||||
this->level = level;
|
||||
this->dimension = dimension;
|
||||
lastInhabitedUpdate = 0;
|
||||
}
|
||||
|
||||
PlayerChunkMap::~PlayerChunkMap() {
|
||||
@@ -397,6 +413,22 @@ PlayerChunkMap::~PlayerChunkMap() {
|
||||
ServerLevel* PlayerChunkMap::getLevel() { return level; }
|
||||
|
||||
void PlayerChunkMap::tick() {
|
||||
int64_t time = level->getGameTime();
|
||||
|
||||
if (time - lastInhabitedUpdate > Level::TICKS_PER_DAY / 3) {
|
||||
lastInhabitedUpdate = time;
|
||||
|
||||
for (int i = 0; i < knownChunks.size(); i++) {
|
||||
PlayerChunk* chunk = knownChunks.at(i);
|
||||
|
||||
// 4J Stu - Going to let our changeChunks handler below deal with
|
||||
// this
|
||||
// chunk.broadcastChanges();
|
||||
|
||||
chunk->updateInhabitedTime();
|
||||
}
|
||||
}
|
||||
|
||||
// 4J - some changes here so that we only send one region update per tick.
|
||||
// The chunks themselves also limit their resend rate to once every
|
||||
// MIN_TICKS_BETWEEN_REGION_UPDATE ticks
|
||||
@@ -432,13 +464,13 @@ void PlayerChunkMap::tick() {
|
||||
}
|
||||
|
||||
bool PlayerChunkMap::hasChunk(int x, int z) {
|
||||
__int64 id = (x + 0x7fffffffLL) | ((z + 0x7fffffffLL) << 32);
|
||||
int64_t id = (x + 0x7fffffffLL) | ((z + 0x7fffffffLL) << 32);
|
||||
return chunks.find(id) != chunks.end();
|
||||
}
|
||||
|
||||
PlayerChunkMap::PlayerChunk* PlayerChunkMap::getChunk(int x, int z,
|
||||
bool create) {
|
||||
__int64 id = (x + 0x7fffffffLL) | ((z + 0x7fffffffLL) << 32);
|
||||
int64_t id = (x + 0x7fffffffLL) | ((z + 0x7fffffffLL) << 32);
|
||||
AUTO_VAR(it, chunks.find(id));
|
||||
|
||||
PlayerChunk* chunk = NULL;
|
||||
@@ -447,6 +479,7 @@ PlayerChunkMap::PlayerChunk* PlayerChunkMap::getChunk(int x, int z,
|
||||
} else if (create) {
|
||||
chunk = new PlayerChunk(x, z, this);
|
||||
chunks[id] = chunk;
|
||||
knownChunks.push_back(chunk);
|
||||
}
|
||||
|
||||
return chunk;
|
||||
@@ -456,7 +489,7 @@ PlayerChunkMap::PlayerChunk* PlayerChunkMap::getChunk(int x, int z,
|
||||
// doesn't exist, queue a request for it to be created.
|
||||
void PlayerChunkMap::getChunkAndAddPlayer(
|
||||
int x, int z, std::shared_ptr<ServerPlayer> player) {
|
||||
__int64 id = (x + 0x7fffffffLL) | ((z + 0x7fffffffLL) << 32);
|
||||
int64_t id = (x + 0x7fffffffLL) | ((z + 0x7fffffffLL) << 32);
|
||||
AUTO_VAR(it, chunks.find(id));
|
||||
|
||||
if (it != chunks.end()) {
|
||||
@@ -476,7 +509,7 @@ void PlayerChunkMap::getChunkAndRemovePlayer(
|
||||
return;
|
||||
}
|
||||
}
|
||||
__int64 id = (x + 0x7fffffffLL) | ((z + 0x7fffffffLL) << 32);
|
||||
int64_t id = (x + 0x7fffffffLL) | ((z + 0x7fffffffLL) << 32);
|
||||
AUTO_VAR(it, chunks.find(id));
|
||||
|
||||
if (it != chunks.end()) {
|
||||
@@ -510,7 +543,6 @@ void PlayerChunkMap::tickAddRequests(std::shared_ptr<ServerPlayer> player) {
|
||||
if (itNearest != addRequests.end()) {
|
||||
getChunk(itNearest->x, itNearest->z, true)->add(itNearest->player);
|
||||
addRequests.erase(itNearest);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -582,6 +614,14 @@ void PlayerChunkMap::add(std::shared_ptr<ServerPlayer> player) {
|
||||
minX = maxX = xc;
|
||||
minZ = maxZ = zc;
|
||||
|
||||
// 4J - added so that we don't fully create/send every chunk at this stage.
|
||||
// Particularly since moving on to large worlds, where we can be adding 1024
|
||||
// chunks here of which a large % might need to be fully created, this can
|
||||
// take a long time. Instead use the getChunkAndAddPlayer for anything but
|
||||
// the central region of chunks, which adds them to a queue of chunks which
|
||||
// are added one per tick per player.
|
||||
const int maxLegSizeToAddNow = 14;
|
||||
|
||||
// All but the last leg
|
||||
for (int legSize = 1; legSize <= size * 2; legSize++) {
|
||||
for (int leg = 0; leg < 2; leg++) {
|
||||
@@ -594,12 +634,19 @@ void PlayerChunkMap::add(std::shared_ptr<ServerPlayer> player) {
|
||||
int targetX, targetZ;
|
||||
targetX = xc + dx;
|
||||
targetZ = zc + dz;
|
||||
if (targetX > maxX) maxX = targetX;
|
||||
if (targetX < minX) minX = targetX;
|
||||
if (targetZ > maxZ) maxZ = targetZ;
|
||||
if (targetZ < minZ) minZ = targetZ;
|
||||
|
||||
getChunk(targetX, targetZ, true)->add(player, false);
|
||||
if ((legSize < maxLegSizeToAddNow) ||
|
||||
((legSize == maxLegSizeToAddNow) &&
|
||||
((leg == 0) || (k < (legSize - 1))))) {
|
||||
if (targetX > maxX) maxX = targetX;
|
||||
if (targetX < minX) minX = targetX;
|
||||
if (targetZ > maxZ) maxZ = targetZ;
|
||||
if (targetZ < minZ) minZ = targetZ;
|
||||
|
||||
getChunk(targetX, targetZ, true)->add(player, false);
|
||||
} else {
|
||||
getChunkAndAddPlayer(targetX, targetZ, player);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -613,12 +660,16 @@ void PlayerChunkMap::add(std::shared_ptr<ServerPlayer> player) {
|
||||
int targetX, targetZ;
|
||||
targetX = xc + dx;
|
||||
targetZ = zc + dz;
|
||||
if (targetX > maxX) maxX = targetX;
|
||||
if (targetX < minX) minX = targetX;
|
||||
if (targetZ > maxZ) maxZ = targetZ;
|
||||
if (targetZ < minZ) minZ = targetZ;
|
||||
if ((size * 2) <= maxLegSizeToAddNow) {
|
||||
if (targetX > maxX) maxX = targetX;
|
||||
if (targetX < minX) minX = targetX;
|
||||
if (targetZ > maxZ) maxZ = targetZ;
|
||||
if (targetZ < minZ) minZ = targetZ;
|
||||
|
||||
getChunk(targetX, targetZ, true)->add(player, false);
|
||||
getChunk(targetX, targetZ, true)->add(player, false);
|
||||
} else {
|
||||
getChunkAndAddPlayer(targetX, targetZ, player);
|
||||
}
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
||||
@@ -753,4 +804,4 @@ void PlayerChunkMap::setRadius(int newRadius) {
|
||||
assert(radius >= MIN_VIEW_DISTANCE);
|
||||
this->radius = newRadius;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user