Send updated biome information instantly back to the player, but only when the biome actually changed

fixes #478
This commit is contained in:
IntegratedQuantum 2025-05-09 22:01:11 +02:00
parent ffab4407e9
commit ed99d940d2
3 changed files with 32 additions and 9 deletions

View File

@ -1019,7 +1019,8 @@ pub const Protocols = struct {
gamemode = 0,
teleport = 1,
worldEditPos = 2,
timeAndBiome = 3,
time = 3,
biome = 4,
};
const WorldEditPosition = enum(u2) {
@ -1063,10 +1064,9 @@ pub const Protocols = struct {
}
}
},
.timeAndBiome => {
.time => {
if(conn.manager.world) |world| {
const expectedTime = try reader.readInt(i64);
const biomeId = try reader.readInt(u32);
var curTime = world.gameTime.load(.monotonic);
if(@abs(curTime -% expectedTime) >= 10) {
@ -1080,6 +1080,11 @@ pub const Protocols = struct {
curTime = actualTime;
}
}
}
},
.biome => {
if(conn.manager.world) |world| {
const biomeId = try reader.readInt(u32);
const newBiome = main.server.terrain.biomes.getByIndex(biomeId) orelse return error.MissingBiome;
const oldBiome = world.playerBiome.swap(newBiome, .monotonic);
@ -1118,15 +1123,22 @@ pub const Protocols = struct {
conn.send(.fast, id, writer.data.items);
}
pub fn sendTimeAndBiome(conn: *Connection, world: *const main.server.ServerWorld) void {
pub fn sendBiome(conn: *Connection, biomeIndex: u32) void {
var writer = utils.BinaryWriter.initCapacity(main.stackAllocator, 13);
defer writer.deinit();
writer.writeEnum(UpdateType, .timeAndBiome);
writer.writeInt(i64, world.gameTime);
writer.writeEnum(UpdateType, .biome);
writer.writeInt(u32, biomeIndex);
const pos = @as(Vec3i, @intFromFloat(conn.user.?.player.pos));
writer.writeInt(u32, world.getBiome(pos[0], pos[1], pos[2]).paletteId);
conn.send(.fast, id, writer.data.items);
}
pub fn sendTime(conn: *Connection, world: *const main.server.ServerWorld) void {
var writer = utils.BinaryWriter.initCapacity(main.stackAllocator, 13);
defer writer.deinit();
writer.writeEnum(UpdateType, .time);
writer.writeInt(i64, world.gameTime);
conn.send(.fast, id, writer.data.items);
}

View File

@ -105,6 +105,8 @@ pub const User = struct { // MARK: User
gamemode: std.atomic.Value(main.game.Gamemode) = .init(.creative),
worldEditData: WorldEditData = undefined,
lastSentBiomeId: u32 = 0xffffffff,
inventoryClientToServerIdMap: std.AutoHashMap(u32, u32) = undefined,
connected: Atomic(bool) = .init(true),
@ -406,6 +408,15 @@ fn update() void { // MARK: update()
main.network.Protocols.entityPosition.send(user.conn, user.player.pos, entityData.items, itemData);
}
for(userList) |user| {
const pos = @as(Vec3i, @intFromFloat(user.player.pos));
const biomeId = world.?.getBiome(user.lastPos[0], pos[1], pos[2]).paletteId;
if(biomeId != user.lastSentBiomeId) {
user.lastSentBiomeId = biomeId;
main.network.Protocols.genericUpdate.sendBiome(user.conn, biomeId);
}
}
while(userDeinitList.dequeue()) |user| {
user.decreaseRefCount();
}

View File

@ -946,7 +946,7 @@ pub const ServerWorld = struct { // MARK: ServerWorld
const userList = server.getUserListAndIncreaseRefCount(main.stackAllocator);
defer server.freeUserListAndDecreaseRefCount(main.stackAllocator, userList);
for(userList) |user| {
main.network.Protocols.genericUpdate.sendTimeAndBiome(user.conn, self);
main.network.Protocols.genericUpdate.sendTime(user.conn, self);
}
}
// TODO: Entities