Skip to content

Commit

Permalink
Hotfix/freakingpartialchunksagain (#349)
Browse files Browse the repository at this point in the history
* Fix freaking chunks

* FERX TEH CHURNKS

* Fixed it!

* Undo that other stuff

* Final Answer

* stuff
  • Loading branch information
Jonpro03 committed May 25, 2023
1 parent c1d60c4 commit d9d5b67
Show file tree
Hide file tree
Showing 13 changed files with 59 additions and 37 deletions.
17 changes: 17 additions & 0 deletions Obsidian.API/_Enums/ChunkStatus.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace Obsidian.API;
public enum ChunkStatus
{
empty,
structure_starts,
structure_references,
biomes,
noise,
surface,
carvers,
liquid_carvers,
features,
light,
spawn,
heightmaps,
full
}
2 changes: 1 addition & 1 deletion Obsidian/Client.cs
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,7 @@ await QueuePacketAsync(new LoginSuccess(Player.Uuid, Player.Username)

await SendPlayerListDecoration();
await SendPlayerInfoAsync();
await Player.UpdateChunksAsync(distance: 2);
await Player.UpdateChunksAsync(distance: 7);
await SendInfoAsync();
await Server.Events.InvokePlayerJoinAsync(new PlayerJoinEventArgs(Player, DateTimeOffset.Now));
}
Expand Down
4 changes: 2 additions & 2 deletions Obsidian/Entities/Entity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ public async Task UpdatePositionAsync(VectorF pos, bool onGround = true)
{
var (x, z) = pos.ToChunkCoord();
var chunk = await this.World.GetChunkAsync(x, z, false);
if (chunk != null && chunk.isGenerated)
if (chunk != null && chunk.IsGenerated)
{
this.Position = pos;
}
Expand All @@ -184,7 +184,7 @@ public async Task UpdatePositionAsync(VectorF pos, Angle yaw, Angle pitch, bool
var (x, z) = pos.ToChunkCoord();
var chunk = await this.World.GetChunkAsync(x, z, false);

if (chunk != null && chunk.isGenerated)
if (chunk != null && chunk.IsGenerated)
{
this.Position = pos;
}
Expand Down
8 changes: 4 additions & 4 deletions Obsidian/Entities/Player.cs
Original file line number Diff line number Diff line change
Expand Up @@ -956,8 +956,8 @@ internal async Task UpdateChunksAsync(bool unloadAll = false, int distance = 0)

(int playerChunkX, int playerChunkZ) = Position.ToChunkCoord();
(int lastPlayerChunkX, int lastPlayerChunkZ) = LastPosition.ToChunkCoord();

int dist = distance < 1? ((client.ClientSettings?.ViewDistance ?? 14) - 2) : 2;
int dist = distance < 1 ? client.ClientSettings?.ViewDistance ?? 7 : distance;
for (int x = playerChunkX + dist; x > playerChunkX - dist; x--)
for (int z = playerChunkZ + dist; z > playerChunkZ - dist; z--)
clientNeededChunks.Add((x, z));
Expand All @@ -978,10 +978,10 @@ internal async Task UpdateChunksAsync(bool unloadAll = false, int distance = 0)
client.LoadedChunks.TryRemove(chunkLoc);
});

await Parallel.ForEachAsync(clientNeededChunks.Take(100), async (chunkLoc, _) =>
await Parallel.ForEachAsync(clientNeededChunks, async (chunkLoc, _) =>
{
var chunk = await World.GetChunkAsync(chunkLoc.X, chunkLoc.Z);
if (chunk is not null && chunk.isGenerated)
if (chunk is not null && chunk.IsGenerated)
{
await client.SendChunkAsync(chunk);
client.LoadedChunks.Add((chunk.X, chunk.Z));
Expand Down
2 changes: 1 addition & 1 deletion Obsidian/Net/Packets/Play/Serverbound/SwingArmPacket.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public partial class SwingArmPacket : IServerboundPacket

public async ValueTask HandleAsync(Server server, Player player)
{
var entities = player.GetEntitiesNear(player.client.ClientSettings.ViewDistance);
var entities = player.GetEntitiesNear(player.client.ClientSettings?.ViewDistance ?? 8);
foreach (var otherEntity in entities)
{
if (otherEntity is not Player otherPlayer)
Expand Down
12 changes: 7 additions & 5 deletions Obsidian/WorldData/Chunk.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ public class Chunk
public int X { get; }
public int Z { get; }

public bool isGenerated = false;
public bool IsGenerated => chunkStatus == ChunkStatus.full;

public ChunkStatus chunkStatus = ChunkStatus.empty;

private const int width = 16;
private const int worldHeight = 320;
Expand Down Expand Up @@ -44,15 +46,13 @@ public Chunk(int x, int z)
}
}

private Chunk(int x, int z, ChunkSection[] sections, Dictionary<HeightmapType, Heightmap> heightmaps, bool isGenerated)
private Chunk(int x, int z, ChunkSection[] sections, Dictionary<HeightmapType, Heightmap> heightmaps)
{
X = x;
Z = z;

Heightmaps = heightmaps;
Sections = sections;

this.isGenerated = isGenerated;
}

public IBlock GetBlock(Vector position) => GetBlock(position.X, position.Y, position.Z);
Expand Down Expand Up @@ -280,13 +280,15 @@ public Chunk Clone(int x, int z)

var heightmaps = new Dictionary<HeightmapType, Heightmap>();

var chunk = new Chunk(x, z, sections, heightmaps, isGenerated);
var chunk = new Chunk(x, z, sections, heightmaps);

foreach (var (type, heightmap) in Heightmaps)
{
heightmaps.Add(type, heightmap.Clone(chunk));
}

chunk.chunkStatus = chunkStatus;

return chunk;
}

Expand Down
6 changes: 3 additions & 3 deletions Obsidian/WorldData/Generators/EmptyWorldGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ static EmptyWorldGenerator()
}
}

empty.isGenerated = true;
spawn.isGenerated = true;
empty.chunkStatus = ChunkStatus.full;
spawn.chunkStatus = ChunkStatus.full;
}

public async Task<Chunk> GenerateChunkAsync(int x, int z, Chunk? chunk = null)
{
if (chunk is { isGenerated: true })
if (chunk is { IsGenerated: true })
return chunk;

if (x == 0 && z == 0)
Expand Down
4 changes: 2 additions & 2 deletions Obsidian/WorldData/Generators/OverworldGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public async Task<Chunk> GenerateChunkAsync(int cx, int cz, Chunk? chunk = null)
chunk ??= new Chunk(cx, cz);

// Sanity checks
if (chunk.isGenerated)
if (chunk.IsGenerated)
return chunk;
if (helper is null)
throw new NullReferenceException("GenHelper must not be null. Call Init()");
Expand Down Expand Up @@ -97,7 +97,7 @@ public async Task<Chunk> GenerateChunkAsync(int cx, int cz, Chunk? chunk = null)
//ChunkBuilder.CarveCaves(helper, chunk);
await OverworldDecorator.DecorateAsync(chunk, helper);

chunk.isGenerated = true;
chunk.chunkStatus = ChunkStatus.full;
return chunk;
}

Expand Down
4 changes: 2 additions & 2 deletions Obsidian/WorldData/Generators/SuperflatGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,12 @@ static SuperflatGenerator()
}
}

model.isGenerated = true;
model.chunkStatus = ChunkStatus.full;
}

public async Task<Chunk> GenerateChunkAsync(int x, int z, Chunk? chunk = null)
{
if (chunk is { isGenerated: true })
if (chunk is { IsGenerated: true })
return chunk;

return model.Clone(x, z);
Expand Down
17 changes: 11 additions & 6 deletions Obsidian/WorldData/Region.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Obsidian.ChunkData;
using Obsidian.Blocks;
using Obsidian.ChunkData;
using Obsidian.Entities;
using Obsidian.Nbt;
using Obsidian.Registries;
Expand All @@ -23,7 +24,7 @@ public class Region : IAsyncDisposable

public ConcurrentDictionary<int, Entity> Entities { get; } = new();

public int LoadedChunkCount => loadedChunks.Count(c => c.isGenerated);
public int LoadedChunkCount => loadedChunks.Count(c => c.IsGenerated);

private DenseCollection<Chunk> loadedChunks { get; } = new(cubicRegionSize, cubicRegionSize);

Expand Down Expand Up @@ -62,18 +63,20 @@ internal async Task FlushAsync()

internal async ValueTask<Chunk> GetChunkAsync(int x, int z)
{
(x, z) = (NumericsHelper.Modulo(x, cubicRegionSize), NumericsHelper.Modulo(z, cubicRegionSize));
var chunk = loadedChunks[x, z];
if (chunk is null)
{
chunk = await GetChunkFromFileAsync(x, z); // Still might be null but that's okay.
loadedChunks[x, z] = chunk;
loadedChunks[x, z] = chunk!;
}

return chunk;
return chunk!;
}

internal async Task UnloadChunk(int x, int z)
{
(x, z) = (NumericsHelper.Modulo(x, cubicRegionSize), NumericsHelper.Modulo(z, cubicRegionSize));
var chunk = loadedChunks[x, z];
if (chunk is null) { return; }
await SerializeChunkAsync(chunk);
Expand All @@ -97,7 +100,7 @@ internal IEnumerable<Chunk> GeneratedChunks()
{
foreach (var c in loadedChunks)
{
if (c is not null && c.isGenerated)
if (c is not null && c.IsGenerated)
{
yield return c;
}
Expand Down Expand Up @@ -241,7 +244,7 @@ private static Chunk DeserializeChunk(NbtCompound chunkCompound)
chunk.SetBlockEntity(tileEntityCompound.GetInt("x"), tileEntityCompound.GetInt("y"), tileEntityCompound.GetInt("z"), tileEntityCompound);
}

chunk.isGenerated = !chunk.Sections.All(c => c.IsEmpty);
chunk.chunkStatus = (ChunkStatus)(Enum.TryParse(typeof(ChunkStatus), chunkCompound.GetString("Status"), out var status) ? status : ChunkStatus.empty);

return chunk;
}
Expand Down Expand Up @@ -313,6 +316,8 @@ private static NbtCompound SerializeChunk(Chunk chunk)
{
new NbtTag<int>("xPos", chunk.X),
new NbtTag<int>("zPos", chunk.Z),
new NbtTag<int>("yPos", -4),
new NbtTag<string>("Status", chunk.chunkStatus.ToString()),
new NbtCompound("Heightmaps")
{
new NbtArray<long>("MOTION_BLOCKING", chunk.Heightmaps[HeightmapType.MotionBlocking].data.storage),
Expand Down
10 changes: 4 additions & 6 deletions Obsidian/WorldData/RegionFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ public async Task SetChunkAsync(int x, int z, byte[] bytes, NbtCompression compr

var (offset, size) = this.GetLocation(tableIndex);

this.ResetPosition();

if (offset == 0 && size == 0)
{
await this.WriteNewChunkAsync(bytes, chunkSectionSize, tableIndex);
Expand All @@ -101,10 +103,6 @@ public async Task SetChunkAsync(int x, int z, byte[] bytes, NbtCompression compr
return;
}

this.ResetPosition();

this.regionFileStream.Position = offset;

using var mem = new RentedArray<byte>(size);

if (chunkSectionSize * sectionSize > size)// gotta allocate new sector now
Expand Down Expand Up @@ -133,7 +131,7 @@ public async Task SetChunkAsync(int x, int z, byte[] bytes, NbtCompression compr
mem.Span[4] = (byte)compression;

bytes.CopyTo(mem.Span[5..]);

this.regionFileStream.Position = offset;
await this.regionFileStream.WriteAsync(mem);

this.semaphore.Release();
Expand Down Expand Up @@ -213,7 +211,7 @@ private async Task WriteChunkHeaderAsync(int length, byte compression)
this.Timestamps[tableIndex] = time;

private void SetLocation(int tableIndex, int offset, int size) =>
this.Locations[tableIndex] = (offset << 8) | (size & 0xFF);
this.Locations[tableIndex] = ((offset + 2) << 8) | (size & 0xFF);

private int CalculateChunkSize(long length) =>
(int)Math.Ceiling((length + 5) / (double)sectionSize);
Expand Down
8 changes: 4 additions & 4 deletions Obsidian/WorldData/World.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ public async Task<bool> DestroyEntityAsync(Entity entity)

if (chunk is not null)
{
if (!chunk.isGenerated && scheduleGeneration)
if (!chunk.IsGenerated && scheduleGeneration)
{
if (!ChunksToGen.Contains((chunkX, chunkZ)))
ChunksToGen.Enqueue((chunkX, chunkZ));
Expand All @@ -139,7 +139,7 @@ public async Task<bool> DestroyEntityAsync(Entity entity)
// Create a partial chunk.
chunk = new Chunk(chunkX, chunkZ)
{
isGenerated = false // Not necessary; just being explicit.
chunkStatus = ChunkStatus.structure_starts
};
region.SetChunk(chunk);
return chunk;
Expand Down Expand Up @@ -503,12 +503,12 @@ public async Task ManageChunksAsync()
{
c = new Chunk(job.x, job.z)
{
isGenerated = false // Not necessary; just being explicit.
chunkStatus = ChunkStatus.structure_starts
};
// Set chunk now so that it no longer comes back as null. #threadlyfe
region.SetChunk(c);
}
if (!c.isGenerated)
if (!c.IsGenerated)
{
c = await Generator.GenerateChunkAsync(job.x, job.z, c);
await worldLight.ProcessSkyLightForChunk(c);
Expand Down
2 changes: 1 addition & 1 deletion Obsidian/WorldData/WorldLight.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public async Task ProcessSkyLightForChunk(Chunk chunk)
public async Task SetLightAndSpread(Vector pos, LightType lt, int level, Chunk chunk)
{
if (chunk is null) { return; }
if (!chunk.isGenerated) { return; }
if (!chunk.IsGenerated) { return; }

int curLevel = chunk.GetLightLevel(pos, lt);
if (level <= curLevel) { return; }
Expand Down

0 comments on commit d9d5b67

Please sign in to comment.