Skip to content
This repository has been archived by the owner on Nov 25, 2024. It is now read-only.

Commit

Permalink
-Migrate to using Registries
Browse files Browse the repository at this point in the history
-Migrate to using ContentDatabase instead of hard-coded content
  • Loading branch information
Cassunshine committed Dec 13, 2023
1 parent b4f896e commit d18690c
Show file tree
Hide file tree
Showing 46 changed files with 945 additions and 306 deletions.
20 changes: 20 additions & 0 deletions Client/Network/ClientConnectionContext.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
using System;
using Voxel.Client.Rendering.Models;
using Voxel.Client.World;
using Voxel.Client.World.Entity;
using Voxel.Common.Network.Packets;
using Voxel.Common.Network.Packets.C2S;
using Voxel.Common.Network.Packets.S2C;
using Voxel.Common.Network.Packets.S2C.Gameplay;
using Voxel.Common.Network.Packets.S2C.Gameplay.Entity;
using Voxel.Common.Network.Packets.S2C.Handshake;
using Voxel.Common.Network.Packets.Utils;

Expand All @@ -16,6 +19,7 @@ namespace Voxel.Client.Network;
/// </summary>
public class ClientConnectionContext {
public bool isDead => Connection.isDead;
public Guid playerID { get; private set; }

public readonly VoxelClient Client;
private readonly C2SConnection Connection;
Expand All @@ -35,6 +39,8 @@ public ClientConnectionContext(VoxelClient client, C2SConnection connection) {
GameplayHandler.RegisterHandler<ChunkData>(HandleChunkData);
GameplayHandler.RegisterHandler<ChunkUnload>(HandleChunkUnload);

GameplayHandler.RegisterHandler<SpawnEntity>(HandleSpawnEntity);

Connection.packetHandler = HandshakeHandler;
}

Expand All @@ -50,7 +56,9 @@ private void HandleSetupWorld(SetupWorld packet) {
}

private void HandleHandshakeDone(S2CHandshakeDone packet) {
BlockModelManager.BakeRawBlockModels();
Connection.packetHandler = GameplayHandler;
playerID = packet.PlayerID;
Console.WriteLine("Client:Server Says Handshake Done");
}

Expand All @@ -70,6 +78,18 @@ private void HandleChunkUnload(ChunkUnload packet) {
packet.Apply(chunk);
}

private void HandleSpawnEntity(SpawnEntity packet) {
if (Client.world == null)
return;

if (packet.ID == playerID) {
var entity = new ControlledClientPlayerEntity();
entity.ID = packet.ID;
Client.PlayerEntity = entity;
Client.world.AddEntity(entity, packet.position, packet.rotation);
}
}

public void SendPacket(C2SPacket packet) {
Connection.DeliverPacket(packet);
PacketPool.Return(packet);
Expand Down
29 changes: 12 additions & 17 deletions Client/Network/InternetC2SConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
using System.Net;
using System.Net.Sockets;
using LiteNetLib;
using Voxel.Common.Content;
using Voxel.Common.Network.Packets;
using Voxel.Common.Network.Packets.C2S;
using Voxel.Common.Network.Packets.C2S.Handshake;
using Voxel.Common.Network.Packets.S2C;
using Voxel.Common.Network.Packets.Utils;
using Voxel.Common.Util.Registration;
using Voxel.Common.Util.Serialization.Compressed;

namespace Voxel.Client.Network;
Expand All @@ -16,14 +18,14 @@ public class InternetC2SConnection : C2SConnection, INetEventListener {
private readonly NetManager NetClient;
private NetPeer? peer;

private readonly PacketMap<C2SPacket> PacketMap = new();
private readonly CompressedVDataReader Reader = new();
private readonly CompressedVDataWriter Writer = new();

public Registries Registries => ContentDatabase.Instance.Registries;

private bool synced = false;

public InternetC2SConnection(string address, int port = 24564) {
PacketMap.FillOutgoingMap();
NetClient = new NetManager(this);

OnClosed += () => {
Expand Down Expand Up @@ -51,30 +53,20 @@ public override void DeliverPacket(Packet toSend) {
var writer = Writer;
writer.Reset();

if (!PacketMap.outgoingMap.TryGetValue(toSend.GetType(), out var rawID))
if (!Registries.PacketTypes.TypeToRaw(toSend.GetType(), out var rawID))
throw new InvalidOperationException($"Cannot send unknown packet {toSend}");

writer.Write(rawID);
writer.Write(toSend);
peer.Send(writer.currentBytes, 0, DeliveryMethod.ReliableOrdered);

//Console.WriteLine($"Sending {writer.currentBytes.Length} bytes to server");
//Console.WriteLine($"Sending {writer.currentBytes.Length} bytes to server for packet {toSend}");
}

public void OnPeerConnected(NetPeer peer) {
this.peer = peer;

Console.Out.WriteLine("Client: Connected!");

//SYNC MAPS HERE
var writer = Writer;
writer.Reset();

PacketMap.WriteOutgoingMap(writer);
peer.Send(writer.currentBytes, 0, DeliveryMethod.ReliableOrdered);

//After maps have been synced, client handshake is done.
DeliverPacket(new C2SHandshakeDone());
}

public void OnNetworkReceive(NetPeer _, NetPacketReader nReader, byte channelNumber, DeliveryMethod deliveryMethod) {
Expand All @@ -84,14 +76,17 @@ public void OnNetworkReceive(NetPeer _, NetPacketReader nReader, byte channelNum
Reader.LoadData(nReader.RawData.AsSpan(nReader.UserDataOffset, nReader.UserDataSize));

if (!synced) {
PacketMap.ReadIncomingMap(Reader);
Registries.ReadSync(Reader);
synced = true;
//Console.Out.WriteLine("Client: S2C Map Synced");
Console.Out.WriteLine("Client: S2C Map Synced");

//After maps have been synced, client handshake is done.
DeliverPacket(new C2SHandshakeDone());
return;
}

var rawID = Reader.ReadUint();
if (!PacketMap.incomingMap.TryGetValue(rawID, out var packetType))
if (!Registries.PacketTypes.RawToType(rawID, out var packetType))
return;

//Console.WriteLine($"Got packet {packetType.Name} from server");
Expand Down
11 changes: 6 additions & 5 deletions Client/Rendering/GameRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Voxel.Client.Rendering.Debug;
using Voxel.Client.Rendering.Gui;
using Voxel.Client.Rendering.World;
using Voxel.Common.Util;

namespace Voxel.Client.Rendering;

Expand Down Expand Up @@ -78,11 +79,11 @@ public override void Render(double delta) {
Framebuffer.Resolve(RenderSystem);

BlitRenderer.Blit(Framebuffer.ResolvedMainColor, RenderSystem.GraphicsDevice.MainSwapchain.Framebuffer, true);
/*ImGui.Text($"Player Pre-Move Velocity: {(Client.PlayerEntity?.preMoveVelocity.y ?? 0):F3}");
ImGui.Text($" Player Velocity: {(Client.PlayerEntity?.velocity.y ?? 0):F3}");
ImGui.Text($"Player Grounded: {Client.PlayerEntity?.isOnFloor ?? false}");*/


ImGui.Text($"Player Position: {(Client.PlayerEntity?.blockPosition ?? ivec3.Zero)}");
ImGui.Text($"Player Velocity: {(Client.PlayerEntity?.velocity.WorldToBlockPosition() ?? ivec3.Zero)}");
ImGui.Text($"Player Grounded: {Client.PlayerEntity?.isOnFloor ?? false}");
}


Expand Down
35 changes: 26 additions & 9 deletions Client/Rendering/Models/BlockModelManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Newtonsoft.Json;
using Voxel.Client.Rendering.Texture;
using Voxel.Client.Rendering.Utils;
using Voxel.Common.Content;
using Voxel.Common.Tile;
using Voxel.Core.Assets;

Expand All @@ -13,22 +14,26 @@ namespace Voxel.Client.Rendering.Models;
public static class BlockModelManager {
private const float BlueTintAmount = 0.9f;
private const string Suffix = ".json";

private static readonly string Prefix = "models/block";

private static readonly Dictionary<Block, BlockModel> Models = new();
private static readonly Dictionary<string, BlockModel> Models = new();
private static readonly List<BlockModel?> ModelsByRawID = new();

private static readonly JsonSerializer Serializer = new();

private static readonly vec3 LightColor = new(BlueTintAmount, BlueTintAmount, 1);
private static readonly vec4 LeftColor = new(ColorFunctions.GetColorMultiplier(0.8f, LightColor), 1);
private static readonly vec4 RightColor = new(ColorFunctions.GetColorMultiplier(0.77f, LightColor), 1);
private static readonly vec4 BottomColor = new(ColorFunctions.GetColorMultiplier(0.6f, LightColor), 1);
private static readonly vec4 BackwardColor = new(ColorFunctions.GetColorMultiplier(0.7f, LightColor), 1);
private static readonly vec4 ForwardColor = new(ColorFunctions.GetColorMultiplier(0.67f, LightColor), 1);

public static void RegisterModel(Block block, BlockModel model) => Models[block] = model;
public static bool TryGetModel(Block block, [NotNullWhen(true)] out BlockModel? model) => Models.TryGetValue(block, out model);
public static void RegisterModel(string name, BlockModel model) => Models[name] = model;
public static bool TryGetModel(Block block, [NotNullWhen(true)] out BlockModel? model) {
model = ModelsByRawID[(int)block.id];
return model != null;
}

public static BlockModel GetDefault(Atlas.Sprite sprite) {
return new BlockModel.Builder()
Expand Down Expand Up @@ -113,21 +118,33 @@ public static void Init(AssetReader reader, Atlas atlas) {
foreach ((string name, var stream, _) in reader.LoadAll(Prefix, Suffix)) {
using var sr = new StreamReader(stream);
using var jsonTextReader = new JsonTextReader(sr);

string texture = Serializer.Deserialize<ModelJson>(jsonTextReader)?.Texture ?? "";
int start = Prefix.Length + 1;
int end = name.Length - Suffix.Length;
string blockName = name[start..end];

if (Blocks.GetBlock(blockName, out var block) && atlas.TryGetSprite(texture, out var sprite))
RegisterModel(block, GetDefault(sprite));
if (atlas.TryGetSprite(texture, out var sprite))
RegisterModel(blockName, GetDefault(sprite));
}
if (
atlas.TryGetSprite("main/grass_top", out var top) &&
atlas.TryGetSprite("main/grass_side", out var side) &&
atlas.TryGetSprite("main/dirt", out var bottom)
)
RegisterModel(Blocks.Grass, GetGrass(top, bottom, side));
RegisterModel("grass", GetGrass(top, bottom, side));
}


public static void BakeRawBlockModels() {
ModelsByRawID.Clear();

foreach ((var entry, string? id, uint raw) in ContentDatabase.Instance.Registries.Blocks.Entries()) {
if (Models.TryGetValue(id, out var mdl))
ModelsByRawID.Add(mdl);
else
ModelsByRawID.Add(null);
}
}

private class ModelJson {
Expand Down
76 changes: 50 additions & 26 deletions Client/Rendering/World/ChunkMeshBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -148,53 +148,77 @@ ushort oti(int x, int y, int z) {
//Left Face
FaceToNeighborIndexes[0] = new[] {
oti(-1, 0, 0),
oti(-1, 0, -1), oti(-1, -1, -1),
oti(-1, -1, 0), oti(-1, -1, 1),
oti(-1, 0, 1), oti(-1, 1, 1),
oti(-1, 1, 0), oti(-1, 1, -1),
oti(-1, 0, -1),
oti(-1, -1, -1),
oti(-1, -1, 0),
oti(-1, -1, 1),
oti(-1, 0, 1),
oti(-1, 1, 1),
oti(-1, 1, 0),
oti(-1, 1, -1),
};

//Right Face
FaceToNeighborIndexes[1] = new[] {
oti(1, 0, 0),
oti(1, -1, 0), oti(1, -1, -1),
oti(1, 0, -1), oti(1, 1, -1),
oti(1, 1, 0), oti(1, 1, 1),
oti(1, 0, 1), oti(1, -1, 1),
oti(1, -1, 0),
oti(1, -1, -1),
oti(1, 0, -1),
oti(1, 1, -1),
oti(1, 1, 0),
oti(1, 1, 1),
oti(1, 0, 1),
oti(1, -1, 1),
};

//Bottom Face
FaceToNeighborIndexes[2] = new[] {
oti(0, -1, 0),
oti(-1, -1, 0), oti(-1, -1, -1),
oti(0, -1, -1), oti(1, -1, -1),
oti(1, -1, 0), oti(1, -1, 1),
oti(0, -1, 1), oti(-1, -1, 1),
oti(-1, -1, 0),
oti(-1, -1, -1),
oti(0, -1, -1),
oti(1, -1, -1),
oti(1, -1, 0),
oti(1, -1, 1),
oti(0, -1, 1),
oti(-1, -1, 1),
};
//Top Face
FaceToNeighborIndexes[3] = new[] {
oti(0, 1, 0),
oti(0, 1, -1), oti(-1, 1, -1),
oti(-1, 1, 0), oti(-1, 1, 1),
oti(0, 1, 1), oti(1, 1, 1),
oti(1, 1, 0), oti(1, 1, -1),
oti(0, 1, -1),
oti(-1, 1, -1),
oti(-1, 1, 0),
oti(-1, 1, 1),
oti(0, 1, 1),
oti(1, 1, 1),
oti(1, 1, 0),
oti(1, 1, -1),
};

//Backward Face
FaceToNeighborIndexes[4] = new[] {
oti(0, 0, -1),
oti(0, -1, -1), oti(-1, -1, -1),
oti(-1, 0, -1), oti(-1, 1, -1),
oti(0, 1, -1), oti(1, 1, -1),
oti(1, 0, -1), oti(1, -1, -1),
oti(0, -1, -1),
oti(-1, -1, -1),
oti(-1, 0, -1),
oti(-1, 1, -1),
oti(0, 1, -1),
oti(1, 1, -1),
oti(1, 0, -1),
oti(1, -1, -1),
};
//Forward Face
FaceToNeighborIndexes[5] = new[] {
oti(0, 0, 1),
oti(-1, 0, 1), oti(-1, -1, 1),
oti(0, -1, 1), oti(1, -1, 1),
oti(1, 0, 1), oti(1, 1, 1),
oti(0, 1, 1), oti(-1, 1, 1),
oti(-1, 0, 1),
oti(-1, -1, 1),
oti(0, -1, 1),
oti(1, -1, 1),
oti(1, 0, 1),
oti(1, 1, 1),
oti(0, 1, 1),
oti(-1, 1, 1),
};
}
}
Expand Down Expand Up @@ -276,7 +300,7 @@ private void WorkLoop() {
var checkBlock = chunkStorages[checkTuple.Item1][checkTuple.Item2];

//Mark if any side of this block is visible.
isVisible |= !checkBlock.IsNotAir;
isVisible |= checkBlock.IsAir;
neighbors[n] = checkBlock;
}

Expand All @@ -289,7 +313,7 @@ private void WorkLoop() {
faceBlocks[fb] = neighbors[fIndexList[fb]];

//If block directly on face is solid, skip face.
if (faceBlocks[0] != Blocks.Air)
if (!faceBlocks[0].IsAir)
continue;

float calculateAO(float s1, float corner, float s2) {
Expand Down
9 changes: 9 additions & 0 deletions Client/Server/IntegratedServer.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
using Voxel.Common.Content;
using Voxel.Common.Server;

namespace Voxel.Client.Server;

public class IntegratedServer : VoxelServer {


public override void Start() {
ContentDatabase.Instance.Clear();
ContentDatabase.Instance.LoadPack(MainContentPack.Instance);
ContentDatabase.Instance.Finish();

base.Start();
}
}
Loading

0 comments on commit d18690c

Please sign in to comment.