TU19: merge Minecraft.Client/Network

This commit is contained in:
Tropical
2026-03-21 21:54:07 -05:00
parent 92fbafe432
commit 3f143811e3
18 changed files with 1802 additions and 491 deletions

View File

@@ -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;
}
}
}