diff --git a/Mine2d.sln.DotSettings b/Mine2d.sln.DotSettings
index 8d8ab74..f5e3247 100644
--- a/Mine2d.sln.DotSettings
+++ b/Mine2d.sln.DotSettings
@@ -1,2 +1,3 @@
- SDL
\ No newline at end of file
+ SDL
+ True
\ No newline at end of file
diff --git a/Mine2d/engine/Publisher.cs b/Mine2d/engine/Publisher.cs
index d43da77..56f3dc2 100644
--- a/Mine2d/engine/Publisher.cs
+++ b/Mine2d/engine/Publisher.cs
@@ -1,78 +1,86 @@
using System.Reflection;
-using Mine2d.engine.networking;
+using Mine2d.engine.extensions;
using Mine2d.engine.system.annotations;
+using Mine2d.game.backend.network.packets;
using Mine2d.game.core.extensions;
namespace Mine2d.engine;
+public delegate void InteractionHandler(Packet packet);
+
public class Publisher
{
- private readonly Dictionary> subscribers =
- new();
- private readonly HashSet clientOnlySubscriptions = new();
- private readonly HashSet serverSubscriptions = new();
+ private readonly Dictionary> subscribers = new();
+ private readonly HashSet clientOnlySubscriptions = new();
+ private readonly HashSet serverSubscriptions = new();
private readonly InteractorKind kind;
public Publisher(InteractorKind kind)
{
+ Enum.GetValues()
+ .ForEach(type => this.subscribers[type] = new HashSet());
+
this.kind = kind;
this.Scan();
}
private void Scan()
{
- var types = Assembly
+ Assembly
.GetAssembly(this.GetType())!
- .GetTypesSafe();
- foreach (var type in types)
- {
- var classAttrs = type.GetCustomAttributes(typeof(InteractorAttribute), false);
- if (classAttrs.Length == 0)
+ .GetTypesSafe()
+ .Where(t => t.HasAttribute())
+ .SelectMany(t => t.GetMethods())
+ .Where(m => m.HasAttribute())
+ .ForEach(method =>
{
- continue;
- }
- var methods = type.GetMethods();
- foreach (var method in methods)
- {
- var methodAttrs = method.GetCustomAttributes(typeof(InteractionAttribute), false);
- if (methodAttrs.Length == 0)
+ var attribute = method.GetCustomAttribute()!;
+ Console.WriteLine($"Registering interaction method {method.Name} declared in {method.DeclaringType}");
+ Console.WriteLine($"InteractorKind: {attribute.Kind}");
+ Console.WriteLine($"PacketType: {attribute.Type}");
+
+ switch (attribute.Kind)
{
- continue;
+ case InteractorKind.Hybrid:
+ case InteractorKind.Server:
+ this.serverSubscriptions.Add(attribute.Type);
+ break;
+ case InteractorKind.Client:
+ this.clientOnlySubscriptions.Add(attribute.Type);
+ break;
+ default:
+ throw new ArgumentOutOfRangeException(nameof(attribute.Kind), attribute.Kind, null);
}
- var attr = (InteractionAttribute)methodAttrs[0];
- if (attr.Kind is InteractorKind.Server or InteractorKind.Hybrid)
+
+ if (attribute.Kind == this.kind || this.kind == InteractorKind.Hybrid)
{
- this.serverSubscriptions.Add(attr.Type);
+ this.subscribers[attribute.Type].Add(method);
+ Console.WriteLine("Subscribed!");
}
- if (attr.Kind is InteractorKind.Client)
- {
- this.clientOnlySubscriptions.Add(attr.Type);
- }
- if (attr.Kind != this.kind && this.kind != InteractorKind.Hybrid)
- {
- continue;
- }
- var del = method.GetParameters().Length == 0 ?
- Delegate.CreateDelegate(typeof(Action), method) :
- Delegate.CreateDelegate(
- typeof(Action<>).MakeGenericTypeSafely(method.GetParameters()[0].ParameterType),
- method
- );
- this.Subscribe(attr.Type, del);
- }
- }
- this.clientOnlySubscriptions.ExceptWith(this.serverSubscriptions);
+
+ Console.WriteLine();
+ });
}
- private void Subscribe(string type, Delegate callback)
+ public void Publish(Packet packet)
{
- if (!this.subscribers.ContainsKey(type))
- {
- this.subscribers[type] = new HashSet();
- }
- this.subscribers[type].Add(callback);
+ if (packet.Type != PacketType.Tick)
+ Console.WriteLine($"[{nameof(Publisher)}] Publishing {packet.Type}");
+
+ this.subscribers[packet.Type]
+ .ForEach(handler =>
+ {
+ var parameterCount = handler.GetParameters().Length;
+ handler.Invoke(null, parameterCount > 0 ? new object[] { packet } : null);
+ });
}
+ public bool IsClientOnlyPacket(Packet packet)
+ => this.clientOnlySubscriptions.Contains(packet.Type);
+
+ public bool IsServerPacket(Packet packet)
+ => this.serverSubscriptions.Contains(packet.Type);
+
public void Dump()
{
foreach (var pair in this.subscribers)
@@ -84,41 +92,4 @@ public class Publisher
}
}
}
-
- public void Publish(ValueType packet)
- {
- var type = PacketUtils.GetType(packet);
- if (type != "tick")
- {
- Console.WriteLine("Publishing packet: " + type);
- }
- if (this.subscribers.ContainsKey(type))
- {
- if (type != "tick")
- {
- Console.WriteLine("Found " + this.subscribers[type].Count + " subscribers");
- }
- foreach (var del in this.subscribers[type])
- {
- if (del.Method.GetParameters().Length == 0)
- {
- del.DynamicInvoke();
- }
- else
- {
- del.DynamicInvoke(packet);
- }
- }
- }
- }
-
- public bool IsClientOnlyPacket(string type)
- {
- return this.clientOnlySubscriptions.Contains(type);
- }
-
- public bool IsServerPacket(string type)
- {
- return this.serverSubscriptions.Contains(type);
- }
-}
+}
\ No newline at end of file
diff --git a/Mine2d/engine/TextureFactory.cs b/Mine2d/engine/TextureFactory.cs
index befb031..617229d 100644
--- a/Mine2d/engine/TextureFactory.cs
+++ b/Mine2d/engine/TextureFactory.cs
@@ -1,5 +1,3 @@
-using Mine2d.game;
-
namespace Mine2d.engine;
public class TextureFactory
diff --git a/Mine2d/engine/extensions/EnumerableExtensions.cs b/Mine2d/engine/extensions/EnumerableExtensions.cs
new file mode 100644
index 0000000..d9d1eae
--- /dev/null
+++ b/Mine2d/engine/extensions/EnumerableExtensions.cs
@@ -0,0 +1,12 @@
+namespace Mine2d.engine.extensions;
+
+public static class EnumerableExtensions
+{
+ public static void ForEach(this IEnumerable source, Action action)
+ {
+ foreach (var item in source)
+ {
+ action(item);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Mine2d/engine/extensions/MethodInfoExtensions.cs b/Mine2d/engine/extensions/MethodInfoExtensions.cs
new file mode 100644
index 0000000..a3c0fae
--- /dev/null
+++ b/Mine2d/engine/extensions/MethodInfoExtensions.cs
@@ -0,0 +1,9 @@
+using System.Reflection;
+
+namespace Mine2d.engine.extensions;
+
+public static class MethodInfoExtensions
+{
+ public static bool HasAttribute(this MethodInfo methodInfo) where T : Attribute
+ => methodInfo.GetCustomAttributes(typeof(T), false).Length > 0;
+}
\ No newline at end of file
diff --git a/Mine2d/engine/extensions/TypeExtensions.cs b/Mine2d/engine/extensions/TypeExtensions.cs
new file mode 100644
index 0000000..a9b733d
--- /dev/null
+++ b/Mine2d/engine/extensions/TypeExtensions.cs
@@ -0,0 +1,7 @@
+namespace Mine2d.engine.extensions;
+
+public static class TypeExtensions
+{
+ public static bool HasAttribute(this Type type) where T : Attribute
+ => type.GetCustomAttributes(typeof(T), false).Length > 0;
+}
\ No newline at end of file
diff --git a/Mine2d/engine/networking/Backend.cs b/Mine2d/engine/networking/Backend.cs
index 8b1c87e..f635ba5 100644
--- a/Mine2d/engine/networking/Backend.cs
+++ b/Mine2d/engine/networking/Backend.cs
@@ -1,8 +1,8 @@
using System.Text;
using Mine2d.engine.system.annotations;
using Mine2d.game;
-using Mine2d.game.backend.data;
using Mine2d.game.backend.network;
+using Mine2d.game.backend.network.packets;
using Newtonsoft.Json;
using WatsonTcp;
@@ -12,22 +12,25 @@ public class Backend : IBackend
{
private WatsonTcpServer server;
private Publisher publisher;
- private readonly Queue pendingPackets = new();
+ private readonly Queue pendingPackets = new();
private uint tick;
public void Process(double dt)
{
- this.ProcessPacket(new TickPacket(this.tick++));
+ this.ProcessPacket(new TickPacket
+ {
+ Tick = ++this.tick
+ });
+
Context.Get().GameState.Tick = this.tick;
while (this.pendingPackets.Count > 0)
{
- var packet = this.pendingPackets.Dequeue();
- this.publisher.Publish(packet);
+ this.publisher.Publish(this.pendingPackets.Dequeue());
}
this.SendGameState();
}
- public void ProcessPacket(ValueType packet)
+ public void ProcessPacket(Packet packet)
{
this.pendingPackets.Enqueue(packet);
}
@@ -36,6 +39,7 @@ public class Backend : IBackend
{
Task.Run(this.Run);
this.publisher = new Publisher(InteractorKind.Hybrid);
+ this.publisher.Dump();
}
public void Run()
@@ -65,15 +69,12 @@ public class Backend : IBackend
private void MessageReceived(object sender, MessageReceivedEventArgs args)
{
- var time = DateTime.Now;
Console.WriteLine("Message Received: " + args.IpPort);
+
var packet = Converter.ParsePacket(args.Data);
- Console.WriteLine("Received packet: " + packet);
- if (packet != null)
- {
- this.pendingPackets.Enqueue(packet);
- }
- Console.WriteLine(DateTime.Now - time);
+ Console.WriteLine($"Received packet: {packet.Type}");
+
+ this.pendingPackets.Enqueue(packet);
}
private void SendGameState()
diff --git a/Mine2d/engine/networking/Frontend.cs b/Mine2d/engine/networking/Frontend.cs
index dfc33a1..d882f46 100644
--- a/Mine2d/engine/networking/Frontend.cs
+++ b/Mine2d/engine/networking/Frontend.cs
@@ -1,5 +1,5 @@
using Mine2d.game;
-using Mine2d.game.backend.data;
+using Mine2d.game.backend.network.packets;
using Mine2d.game.frontend.renderer;
namespace Mine2d.engine.networking;
@@ -14,7 +14,11 @@ public class Frontend : IFrontend
ctx.FrontendGameState.PlayerName = ctx.IsHost ? "Host" : "Client";
var guid = Guid.NewGuid();
ctx.FrontendGameState.PlayerGuid = guid;
- var connectPacket = new ConnectPacket(ctx.FrontendGameState.PlayerName, guid);
+ var connectPacket = new ConnectPacket
+ {
+ PlayerName = ctx.FrontendGameState.PlayerName,
+ PlayerGuid = guid
+ };
ctx.Backend.ProcessPacket(connectPacket);
ctx.TileRegistry.RegisterTile();
ctx.ItemRegistry.RegisterItems();
diff --git a/Mine2d/engine/networking/IBackend.cs b/Mine2d/engine/networking/IBackend.cs
index 9718ae2..51937c8 100644
--- a/Mine2d/engine/networking/IBackend.cs
+++ b/Mine2d/engine/networking/IBackend.cs
@@ -1,8 +1,10 @@
+using Mine2d.game.backend.network.packets;
+
namespace Mine2d.engine.networking;
public interface IBackend
{
public void Process(double dt);
- public void ProcessPacket(ValueType packet);
+ public void ProcessPacket(Packet packet);
public void Init();
}
diff --git a/Mine2d/engine/networking/PacketUtils.cs b/Mine2d/engine/networking/PacketUtils.cs
deleted file mode 100644
index 585702a..0000000
--- a/Mine2d/engine/networking/PacketUtils.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using Mine2d.game.backend.data;
-
-namespace Mine2d.engine.networking;
-
-public static class PacketUtils
-{
- public static string GetType(ValueType packet)
- {
- var t = packet.GetType();
- var p = t.GetProperty(nameof(IPacket.Type));
- if (p == null)
- {
- throw new ArgumentNullException(nameof(p), "p undef");
- }
- var v = p.GetValue(packet);
- if (v == null)
- {
- throw new ArgumentNullException(nameof(v), "v undef");
- }
- return (string)v;
- }
-}
diff --git a/Mine2d/engine/networking/RemoteBackend.cs b/Mine2d/engine/networking/RemoteBackend.cs
index 9177c8d..fd2c825 100644
--- a/Mine2d/engine/networking/RemoteBackend.cs
+++ b/Mine2d/engine/networking/RemoteBackend.cs
@@ -1,7 +1,7 @@
using System.Text;
using Mine2d.engine.system.annotations;
using Mine2d.game;
-using Mine2d.game.backend.data;
+using Mine2d.game.backend.network.packets;
using Mine2d.game.state;
using Newtonsoft.Json;
using WatsonTcp;
@@ -12,12 +12,16 @@ public class RemoteBackend : IBackend
{
private WatsonTcpClient client;
private Publisher publisher;
- private readonly Queue pendingPackets = new();
+ private readonly Queue pendingPackets = new();
private uint tick;
public void Process(double dt)
{
- this.ProcessPacket(new TickPacket(this.tick++));
+ this.ProcessPacket(new TickPacket
+ {
+ Tick = ++this.tick
+ });
+
while (this.pendingPackets.Count > 0)
{
var packet = this.pendingPackets.Dequeue();
@@ -25,13 +29,12 @@ public class RemoteBackend : IBackend
}
}
- public void ProcessPacket(ValueType packet)
+ public void ProcessPacket(Packet packet)
{
this.publisher.Publish(packet);
- if (this.publisher.IsClientOnlyPacket(PacketUtils.GetType(packet)))
- {
+ if (this.publisher.IsClientOnlyPacket(packet))
return;
- }
+
var json = JsonConvert.SerializeObject(packet);
var bytes = Encoding.UTF8.GetBytes(json);
this.client.Send(bytes);
diff --git a/Mine2d/engine/system/annotations/Interactor.cs b/Mine2d/engine/system/annotations/Interactor.cs
index 6896c33..40bd0e6 100644
--- a/Mine2d/engine/system/annotations/Interactor.cs
+++ b/Mine2d/engine/system/annotations/Interactor.cs
@@ -1,3 +1,5 @@
+using Mine2d.game.backend.network.packets;
+
namespace Mine2d.engine.system.annotations;
public enum InteractorKind
@@ -13,10 +15,10 @@ public class InteractorAttribute : Attribute { }
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class InteractionAttribute : Attribute
{
- public string Type { get; set; }
+ public PacketType Type { get; set; }
public InteractorKind Kind { get; set; }
- public InteractionAttribute(InteractorKind kind, string type)
+ public InteractionAttribute(InteractorKind kind, PacketType type)
{
this.Type = type;
this.Kind = kind;
diff --git a/Mine2d/game/backend/data/Packet.cs b/Mine2d/game/backend/data/Packet.cs
deleted file mode 100644
index 2b79525..0000000
--- a/Mine2d/game/backend/data/Packet.cs
+++ /dev/null
@@ -1,98 +0,0 @@
-using Mine2d.game.core.data;
-
-namespace Mine2d.game.backend.data;
-
-public interface IPacket
-{
- public string Type { get; }
-}
-
-public struct MovePacket : IPacket
-{
- public readonly string Type => "move";
-
- public readonly string PlayerName { get; }
- public readonly Vector2 Movement { get; }
-
- public MovePacket(string playerName, Vector2 movement)
- {
- this.PlayerName = playerName;
- this.Movement = movement;
- }
-}
-
-public readonly struct ConnectPacket : IPacket
-{
- public readonly string Type => "connect";
- public readonly string PlayerName { get; }
- public readonly Guid PlayerGuid { get; }
-
- public ConnectPacket(string playerName, Guid playerGuid)
- {
- this.PlayerName = playerName;
- this.PlayerGuid = playerGuid;
- }
-}
-
-public readonly struct TickPacket : IPacket
-{
- public readonly string Type => "tick";
- public readonly uint Tick { get; }
-
- public TickPacket(uint tick)
- {
- this.Tick = tick;
- }
-}
-
-public readonly struct SelfMovedPacket : IPacket
-{
- public readonly string Type => "selfMoved";
- public readonly Vector2 Target { get; }
-
- public SelfMovedPacket(Vector2 target)
- {
- this.Target = target;
- }
-}
-
-public readonly struct BreakPacket : IPacket
-{
- public readonly string Type => "break";
- public readonly Guid PlayerGuid { get; }
- public readonly Vector2 Target { get; }
-
- public BreakPacket(Guid playerGuid, Vector2 target)
- {
- this.PlayerGuid = playerGuid;
- this.Target = target;
- }
-}
-
-public readonly struct PlayerMovedPacket : IPacket
-{
- public readonly string Type => "playerMoved";
- public readonly Guid PlayerId { get; }
- public readonly Vector2 Target { get; }
-
- public PlayerMovedPacket(Guid playerId, Vector2 target)
- {
- this.PlayerId = playerId;
- this.Target = target;
- }
-}
-
-public readonly struct BlockBrokenPacket : IPacket
-{
- public readonly string Type => "blockBroken";
- public readonly Guid PlayerId { get; }
- public readonly Vector2 Target { get; }
- public readonly STile Tile { get; }
-
- public BlockBrokenPacket(Guid playerId, Vector2 target, STile tile)
- {
- this.PlayerId = playerId;
- this.Target = target;
- this.Tile = tile;
- }
-}
diff --git a/Mine2d/game/backend/interactor/Audio.cs b/Mine2d/game/backend/interactor/Audio.cs
index 207c676..3fff16b 100644
--- a/Mine2d/game/backend/interactor/Audio.cs
+++ b/Mine2d/game/backend/interactor/Audio.cs
@@ -1,12 +1,13 @@
using Mine2d.engine;
using Mine2d.engine.system.annotations;
+using Mine2d.game.backend.network.packets;
namespace Mine2d.game.backend.interactor;
[Interactor]
public class Audio
{
- [Interaction(InteractorKind.Client, "blockBroken")]
+ [Interaction(InteractorKind.Client, PacketType.BlockBroken)]
public static void BlockBroken()
{
var ctx = Context.Get();
diff --git a/Mine2d/game/backend/interactor/Breaking.cs b/Mine2d/game/backend/interactor/Breaking.cs
index 37475b9..7f9626d 100644
--- a/Mine2d/game/backend/interactor/Breaking.cs
+++ b/Mine2d/game/backend/interactor/Breaking.cs
@@ -1,6 +1,5 @@
-using Mine2d.engine;
using Mine2d.engine.system.annotations;
-using Mine2d.game.backend.data;
+using Mine2d.game.backend.network.packets;
using Mine2d.game.core;
using Mine2d.game.core.data;
@@ -9,7 +8,7 @@ namespace Mine2d.game.backend.interactor;
[Interactor]
public class Breaking
{
- [Interaction(InteractorKind.Hybrid, "tick")]
+ [Interaction(InteractorKind.Hybrid, PacketType.Tick)]
public static void TickHybrid()
{
var ctx = Context.Get();
@@ -45,7 +44,12 @@ public class Breaking
if (tile.Hits >= hardness)
{
var blockPos = new Vector2((int)Math.Floor(player.Mining.X / 16) * 16, (int)Math.Floor(player.Mining.Y / 16) * 16);
- ctx.Backend.ProcessPacket(new BlockBrokenPacket(player.Id, blockPos, tile));
+ ctx.Backend.ProcessPacket(new BlockBrokenPacket
+ {
+ PlayerGuid = player.Id,
+ Target = blockPos,
+ Tile = tile
+ });
chunk.SetTileAt(player.Mining, STile.From(0));
}
}
@@ -53,7 +57,7 @@ public class Breaking
}
}
- [Interaction(InteractorKind.Server, "break")]
+ [Interaction(InteractorKind.Server, PacketType.Break)]
public static void BreakServer(BreakPacket packet)
{
var ctx = Context.Get();
@@ -65,7 +69,7 @@ public class Breaking
player.Mining = packet.Target;
}
- [Interaction(InteractorKind.Server, "blockBroken")]
+ [Interaction(InteractorKind.Server, PacketType.BlockBroken)]
public static void BreakServer(BlockBrokenPacket packet)
{
var ctx = Context.Get();
diff --git a/Mine2d/game/backend/interactor/Connect.cs b/Mine2d/game/backend/interactor/Connect.cs
index 7e46436..f0f62d3 100644
--- a/Mine2d/game/backend/interactor/Connect.cs
+++ b/Mine2d/game/backend/interactor/Connect.cs
@@ -1,5 +1,5 @@
using Mine2d.engine.system.annotations;
-using Mine2d.game.backend.data;
+using Mine2d.game.backend.network.packets;
using Mine2d.game.state;
namespace Mine2d.game.backend.interactor;
@@ -7,7 +7,7 @@ namespace Mine2d.game.backend.interactor;
[Interactor]
public class Connect
{
- [Interaction(InteractorKind.Server, "connect")]
+ [Interaction(InteractorKind.Server, PacketType.Connect)]
public static void ConnectServer(ConnectPacket packet)
{
var ctx = Context.Get();
diff --git a/Mine2d/game/backend/interactor/ItemPhysics.cs b/Mine2d/game/backend/interactor/ItemPhysics.cs
index 2316d3e..bb4886a 100644
--- a/Mine2d/game/backend/interactor/ItemPhysics.cs
+++ b/Mine2d/game/backend/interactor/ItemPhysics.cs
@@ -1,6 +1,6 @@
using Mine2d.engine;
using Mine2d.engine.system.annotations;
-using Mine2d.game.backend.data;
+using Mine2d.game.backend.network.packets;
using Mine2d.game.core.data;
using Mine2d.game.core.data.entities;
@@ -10,8 +10,8 @@ namespace Mine2d.game.backend.interactor;
public class ItemPhysics
{
- [Interaction(InteractorKind.Hybrid, "tick")]
- public static void TickHybrid()
+ [Interaction(InteractorKind.Hybrid, PacketType.Tick)]
+ public static void TickHybrid(TickPacket packet)
{
var gameState = Context.Get().GameState;
var world = gameState.World;
@@ -36,8 +36,8 @@ public class ItemPhysics
}
}
- [Interaction(InteractorKind.Hybrid, "tick")]
- public static void Pickup(TickPacket tickPacket)
+ [Interaction(InteractorKind.Hybrid, PacketType.Tick)]
+ public static void Pickup(TickPacket packet)
{
var gameState = Context.Get().GameState;
var world = gameState.World;
@@ -51,12 +51,12 @@ public class ItemPhysics
Console.WriteLine("Where");
return e is ItemEntity itemEntity &&
(player.Position + new Vector2(7, 3) - itemEntity.Position).LengthSquared() < 8 * 8 &&
- player.inventory.PickupItemStack(new ItemStack { Id = itemEntity.ItemId, Count = 1 });
- });
+ player.Inventory.PickupItemStack(new ItemStack { Id = itemEntity.ItemId, Count = 1 });
+ }).ToList();
if (items.Any())
{
Context.Get().GameAudio.Play(Sound.ItemPickup);
- Console.WriteLine(tickPacket.Tick + " " + items.Count());
+ Console.WriteLine(packet.Tick + " " + items.Count());
}
_ = chunk.Value.Entities.RemoveAll(e => items.Contains(e));
}
diff --git a/Mine2d/game/backend/interactor/Move.cs b/Mine2d/game/backend/interactor/Move.cs
index 4e67f42..1bbbb75 100644
--- a/Mine2d/game/backend/interactor/Move.cs
+++ b/Mine2d/game/backend/interactor/Move.cs
@@ -1,5 +1,5 @@
using Mine2d.engine.system.annotations;
-using Mine2d.game.backend.data;
+using Mine2d.game.backend.network.packets;
using Mine2d.game.core;
namespace Mine2d.game.backend.interactor;
@@ -7,7 +7,7 @@ namespace Mine2d.game.backend.interactor;
[Interactor]
public class Move
{
- [Interaction(InteractorKind.Hybrid, "move")]
+ [Interaction(InteractorKind.Hybrid, PacketType.Move)]
public static void MoveHybrid(MovePacket packet)
{
var ctx = Context.Get();
@@ -18,7 +18,7 @@ public class Move
}
}
- [Interaction(InteractorKind.Hybrid, "tick")]
+ [Interaction(InteractorKind.Hybrid, PacketType.Tick)]
public static void TickHybrid()
{
var ctx = Context.Get();
@@ -33,12 +33,16 @@ public class Move
{
if (player.Position != fromPositions[player.Id])
{
- ctx.Backend.ProcessPacket(new PlayerMovedPacket(player.Id, player.Position));
+ ctx.Backend.ProcessPacket(new PlayerMovedPacket
+ {
+ PlayerGuid = player.Id,
+ Target = player.Position
+ });
}
}
}
-
- [Interaction(InteractorKind.Client, "tick")]
+
+ [Interaction(InteractorKind.Client, PacketType.Tick)]
public static void SelfMovedClient()
{
var camera = Context.Get().FrontendGameState.Camera;
diff --git a/Mine2d/game/backend/interactor/WorldGeneration.cs b/Mine2d/game/backend/interactor/WorldGeneration.cs
index 2f76edf..356f471 100644
--- a/Mine2d/game/backend/interactor/WorldGeneration.cs
+++ b/Mine2d/game/backend/interactor/WorldGeneration.cs
@@ -1,5 +1,5 @@
using Mine2d.engine.system.annotations;
-using Mine2d.game.backend.data;
+using Mine2d.game.backend.network.packets;
using Mine2d.game.core.data;
using Mine2d.game.core.world;
@@ -19,7 +19,7 @@ public class WorldGeneration
new(-1, 1)
};
- [Interaction(InteractorKind.Server, "playerMoved")]
+ [Interaction(InteractorKind.Server, PacketType.PlayerMoved)]
public static void PlayerMovedServer(PlayerMovedPacket packet)
{
var ctx = Context.Get();
@@ -28,7 +28,7 @@ public class WorldGeneration
{
var generationTarget = packet.Target + direction * 16 * 32;
var hasChunkGenerated = world.HasChunkAt(generationTarget);
-
+
if (!hasChunkGenerated)
{
var chunkPos = World.ToChunkPos(generationTarget);
diff --git a/Mine2d/game/backend/network/Converter.cs b/Mine2d/game/backend/network/Converter.cs
index 665f502..4b234e9 100644
--- a/Mine2d/game/backend/network/Converter.cs
+++ b/Mine2d/game/backend/network/Converter.cs
@@ -1,34 +1,43 @@
using System.Text;
-using Mine2d.game.backend.data;
+using Mine2d.game.backend.network.packets;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
+using ConnectPacket = Mine2d.game.backend.network.packets.ConnectPacket;
+using TickPacket = Mine2d.game.backend.network.packets.TickPacket;
namespace Mine2d.game.backend.network;
public class Converter
{
- public static ValueType ParsePacket(byte[] bytes)
+ public static Packet ParsePacket(byte[] bytes)
{
var jsonString = Encoding.UTF8.GetString(bytes);
return ParsePacket(jsonString);
}
- public static ValueType ParsePacket(string jsonString)
+ public static Packet ParsePacket(string jsonString)
{
var parsedRaw = JObject.Parse(jsonString);
- var type = parsedRaw.GetValue("type");
- if (type == null)
- {
+ var packetType = parsedRaw
+ .GetValue("type")?
+ .Value();
+
+ if (packetType == null)
throw new PacketException("Packet has no type");
- }
- var packetType = type.Value();
+
Console.WriteLine("Packet type: " + packetType);
- return packetType switch
+ Packet packet = packetType switch
{
- "move" => parsedRaw.ToObject(),
- "connect" => parsedRaw.ToObject(),
- _ => throw new PacketException("Unknown packet type")
+ PacketType.Connect => parsedRaw.ToObject(),
+ PacketType.Disconnect => parsedRaw.ToObject(),
+ PacketType.Tick => parsedRaw.ToObject(),
+ _ => throw new PacketException($"Unknown packet type: {packetType}")
};
+
+ if (packet is null)
+ throw new PacketException($"Failed to parse packet of type: {packetType}");
+
+ return packet;
}
public static byte[] SerializePacket(ValueType packet)
diff --git a/Mine2d/game/backend/network/packets/BlockBrokenPacket.cs b/Mine2d/game/backend/network/packets/BlockBrokenPacket.cs
new file mode 100644
index 0000000..b110194
--- /dev/null
+++ b/Mine2d/game/backend/network/packets/BlockBrokenPacket.cs
@@ -0,0 +1,12 @@
+using Mine2d.game.core.data;
+
+namespace Mine2d.game.backend.network.packets;
+
+public class BlockBrokenPacket : Packet
+{
+ public override PacketType Type => PacketType.BlockBroken;
+
+ public Guid PlayerGuid { get; init; }
+ public Vector2 Target { get; init; }
+ public STile Tile { get; init; }
+}
\ No newline at end of file
diff --git a/Mine2d/game/backend/network/packets/BreakPacket.cs b/Mine2d/game/backend/network/packets/BreakPacket.cs
new file mode 100644
index 0000000..7af6709
--- /dev/null
+++ b/Mine2d/game/backend/network/packets/BreakPacket.cs
@@ -0,0 +1,9 @@
+namespace Mine2d.game.backend.network.packets;
+
+public class BreakPacket : Packet
+{
+ public override PacketType Type => PacketType.Break;
+
+ public Guid PlayerGuid { get; init; }
+ public Vector2 Target { get; init; }
+}
\ No newline at end of file
diff --git a/Mine2d/game/backend/network/packets/ConnectPacket.cs b/Mine2d/game/backend/network/packets/ConnectPacket.cs
new file mode 100644
index 0000000..490a6d0
--- /dev/null
+++ b/Mine2d/game/backend/network/packets/ConnectPacket.cs
@@ -0,0 +1,9 @@
+namespace Mine2d.game.backend.network.packets;
+
+public class ConnectPacket : Packet
+{
+ public override PacketType Type => PacketType.Connect;
+
+ public string PlayerName { get; init; }
+ public Guid PlayerGuid { get; init; }
+}
\ No newline at end of file
diff --git a/Mine2d/game/backend/network/packets/DisconnectPacket.cs b/Mine2d/game/backend/network/packets/DisconnectPacket.cs
new file mode 100644
index 0000000..68ac71e
--- /dev/null
+++ b/Mine2d/game/backend/network/packets/DisconnectPacket.cs
@@ -0,0 +1,9 @@
+namespace Mine2d.game.backend.network.packets;
+
+public class DisconnectPacket : Packet
+{
+ public override PacketType Type => PacketType.Disconnect;
+
+ public string PlayerName { get; init; }
+ public string PlayerGuid { get; init; }
+}
\ No newline at end of file
diff --git a/Mine2d/game/backend/network/packets/MovePacket.cs b/Mine2d/game/backend/network/packets/MovePacket.cs
new file mode 100644
index 0000000..7c03e0f
--- /dev/null
+++ b/Mine2d/game/backend/network/packets/MovePacket.cs
@@ -0,0 +1,9 @@
+namespace Mine2d.game.backend.network.packets;
+
+public class MovePacket : Packet
+{
+ public override PacketType Type => PacketType.Move;
+
+ public string PlayerName { get; init; }
+ public Vector2 Movement { get; init; }
+}
\ No newline at end of file
diff --git a/Mine2d/game/backend/network/packets/Packet.cs b/Mine2d/game/backend/network/packets/Packet.cs
new file mode 100644
index 0000000..4d8d6d0
--- /dev/null
+++ b/Mine2d/game/backend/network/packets/Packet.cs
@@ -0,0 +1,6 @@
+namespace Mine2d.game.backend.network.packets;
+
+public abstract class Packet
+{
+ public abstract PacketType Type { get; }
+}
\ No newline at end of file
diff --git a/Mine2d/game/backend/network/packets/PacketType.cs b/Mine2d/game/backend/network/packets/PacketType.cs
new file mode 100644
index 0000000..26bdd5a
--- /dev/null
+++ b/Mine2d/game/backend/network/packets/PacketType.cs
@@ -0,0 +1,13 @@
+namespace Mine2d.game.backend.network.packets;
+
+public enum PacketType
+{
+ Connect,
+ Disconnect,
+ Tick,
+ Move,
+ SelfMoved,
+ Break,
+ PlayerMoved,
+ BlockBroken
+}
\ No newline at end of file
diff --git a/Mine2d/game/backend/network/packets/PlayerInputPacket.cs b/Mine2d/game/backend/network/packets/PlayerInputPacket.cs
new file mode 100644
index 0000000..b2b714d
--- /dev/null
+++ b/Mine2d/game/backend/network/packets/PlayerInputPacket.cs
@@ -0,0 +1,6 @@
+namespace Mine2d.game.backend.network.packets;
+
+public class PlayerInputPacket
+{
+ public Vector2 InputVector { get; set; }
+}
\ No newline at end of file
diff --git a/Mine2d/game/backend/network/packets/PlayerMovedPacket.cs b/Mine2d/game/backend/network/packets/PlayerMovedPacket.cs
new file mode 100644
index 0000000..e34c45f
--- /dev/null
+++ b/Mine2d/game/backend/network/packets/PlayerMovedPacket.cs
@@ -0,0 +1,9 @@
+namespace Mine2d.game.backend.network.packets;
+
+public class PlayerMovedPacket : Packet
+{
+ public override PacketType Type => PacketType.PlayerMoved;
+
+ public Guid PlayerGuid { get; init; }
+ public Vector2 Target { get; init; }
+}
\ No newline at end of file
diff --git a/Mine2d/game/backend/network/packets/SelfMovedPacked.cs b/Mine2d/game/backend/network/packets/SelfMovedPacked.cs
new file mode 100644
index 0000000..d584a6b
--- /dev/null
+++ b/Mine2d/game/backend/network/packets/SelfMovedPacked.cs
@@ -0,0 +1,8 @@
+namespace Mine2d.game.backend.network.packets;
+
+public class SelfMovedPacked : Packet
+{
+ public override PacketType Type => PacketType.SelfMoved;
+
+ public Vector2 Target { get; init; }
+}
\ No newline at end of file
diff --git a/Mine2d/game/backend/network/packets/TickPacket.cs b/Mine2d/game/backend/network/packets/TickPacket.cs
new file mode 100644
index 0000000..cbafeef
--- /dev/null
+++ b/Mine2d/game/backend/network/packets/TickPacket.cs
@@ -0,0 +1,8 @@
+namespace Mine2d.game.backend.network.packets;
+
+public class TickPacket : Packet
+{
+ public override PacketType Type => PacketType.Tick;
+
+ public uint Tick { get; init; }
+}
\ No newline at end of file
diff --git a/Mine2d/game/core/tiles/OreTile.cs b/Mine2d/game/core/tiles/OreTile.cs
index c09c124..84dff0b 100644
--- a/Mine2d/game/core/tiles/OreTile.cs
+++ b/Mine2d/game/core/tiles/OreTile.cs
@@ -1,4 +1,3 @@
-using Mine2d.engine;
using Mine2d.game.core.data;
namespace Mine2d.game.core.tiles;
diff --git a/Mine2d/game/frontend/events/PlayerBreakInput.cs b/Mine2d/game/frontend/events/PlayerBreakInput.cs
index 63825e7..b7537c4 100644
--- a/Mine2d/game/frontend/events/PlayerBreakInput.cs
+++ b/Mine2d/game/frontend/events/PlayerBreakInput.cs
@@ -1,6 +1,6 @@
using Mine2d.engine.system;
using Mine2d.engine.system.annotations;
-using Mine2d.game.backend.data;
+using Mine2d.game.backend.network.packets;
namespace Mine2d.game.frontend.events;
@@ -18,7 +18,12 @@ public class PlayerBreakInput
var amp = ctx.FrontendGameState.MousePosition
/ ctx.FrontendGameState.Settings.GameScale
+ ctx.FrontendGameState.Camera.Position;
- ctx.Backend.ProcessPacket(new BreakPacket(ctx.FrontendGameState.PlayerGuid, amp));
+
+ ctx.Backend.ProcessPacket(new BreakPacket
+ {
+ PlayerGuid = ctx.FrontendGameState.PlayerGuid,
+ Target = amp
+ });
}
}
@@ -31,8 +36,15 @@ public class PlayerBreakInput
}
var ctx = Context.Get();
- var amp = ctx.FrontendGameState.MousePosition / ctx.FrontendGameState.Settings.GameScale + ctx.FrontendGameState.Camera.Position;
- ctx.Backend.ProcessPacket(new BreakPacket(ctx.FrontendGameState.PlayerGuid, amp));
+ var amp = ctx.FrontendGameState.MousePosition
+ / ctx.FrontendGameState.Settings.GameScale
+ + ctx.FrontendGameState.Camera.Position;
+
+ ctx.Backend.ProcessPacket(new BreakPacket
+ {
+ PlayerGuid = ctx.FrontendGameState.PlayerGuid,
+ Target = amp
+ });
}
[EventListener(EventType.MouseButtonUp)]
@@ -44,6 +56,10 @@ public class PlayerBreakInput
}
var ctx = Context.Get();
- ctx.Backend.ProcessPacket(new BreakPacket(ctx.FrontendGameState.PlayerGuid, Vector2.Zero));
+ ctx.Backend.ProcessPacket(new BreakPacket
+ {
+ PlayerGuid = ctx.FrontendGameState.PlayerGuid,
+ Target = Vector2.Zero
+ });
}
}
diff --git a/Mine2d/game/frontend/events/PlayerController.cs b/Mine2d/game/frontend/events/PlayerController.cs
new file mode 100644
index 0000000..ad69da5
--- /dev/null
+++ b/Mine2d/game/frontend/events/PlayerController.cs
@@ -0,0 +1,48 @@
+using Mine2d.engine.system;
+using Mine2d.engine.system.annotations;
+
+namespace Mine2d.game.frontend.events;
+
+public class PlayerController
+{
+ [EventListener(EventType.KeyDown)]
+ public static void OnKeyDown(SDL_Event e)
+ {
+ if (!IsMovementKey(e.key.keysym.scancode))
+ return;
+
+ // Context
+ // .Get()
+ // .Backend
+ // .ProcessPacket(new PlayerInputPacket
+ // {
+ // InputVector = e.key.keysym.scancode switch
+ // {
+ // SDL_Scancode.SDL_SCANCODE_A
+ // => new Vector2(-1, 0),
+ // SDL_Scancode.SDL_SCANCODE_D
+ // => new Vector2(1, 0),
+ // SDL_Scancode.SDL_SCANCODE_W or SDL_Scancode.SDL_SCANCODE_SPACE
+ // => new Vector2(0, 1),
+ // SDL_Scancode.SDL_SCANCODE_S
+ // => new Vector2(0, -1)
+ // }
+ // });
+ }
+
+ [EventListener(EventType.KeyUp)]
+ public static void OnKeyUp(SDL_Event e)
+ {
+ if (!IsMovementKey(e.key.keysym.scancode))
+ return;
+ }
+
+ private static bool IsMovementKey(SDL_Scancode scancode)
+ {
+ return scancode
+ is SDL_Scancode.SDL_SCANCODE_A
+ or SDL_Scancode.SDL_SCANCODE_D
+ or SDL_Scancode.SDL_SCANCODE_W
+ or SDL_Scancode.SDL_SCANCODE_S;
+ }
+}
diff --git a/Mine2d/game/frontend/events/PlayerInput.cs b/Mine2d/game/frontend/events/PlayerInput.cs
index ab178c5..da74733 100644
--- a/Mine2d/game/frontend/events/PlayerInput.cs
+++ b/Mine2d/game/frontend/events/PlayerInput.cs
@@ -1,6 +1,6 @@
using Mine2d.engine.system;
using Mine2d.engine.system.annotations;
-using Mine2d.game.backend.data;
+using Mine2d.game.backend.network.packets;
namespace Mine2d.game.frontend.events;
@@ -80,6 +80,10 @@ public class PlayerInput
{
movement = Vector2.Normalize(movement);
}
- ctx.Backend.ProcessPacket(new MovePacket(ctx.FrontendGameState.PlayerName, movement));
+ ctx.Backend.ProcessPacket(new MovePacket
+ {
+ PlayerName = ctx.FrontendGameState.PlayerName,
+ Movement = movement
+ });
}
}
diff --git a/Mine2d/game/frontend/renderer/HudRenderer.cs b/Mine2d/game/frontend/renderer/HudRenderer.cs
index 7ce683e..20bc58b 100644
--- a/Mine2d/game/frontend/renderer/HudRenderer.cs
+++ b/Mine2d/game/frontend/renderer/HudRenderer.cs
@@ -30,9 +30,9 @@ public class HudRenderer : IRenderer
var (hotbarWidth, hotbarHeight) = renderer.GetTextureSize(this.hotbarTexture);
var player = PlayerEntity.GetSelf();
renderer.DrawTexture(this.hotbarTexture, 0, 0, hotbarWidth * uiScale, hotbarHeight * uiScale);
- for (var i = 0; i < player?.inventory.Hotbar.Length; i++)
+ for (var i = 0; i < player?.Inventory.Hotbar.Length; i++)
{
- var stack = player.inventory.Hotbar[i];
+ var stack = player.Inventory.Hotbar[i];
if (stack == null)
{
continue;
diff --git a/Mine2d/game/frontend/renderer/ItemRenderer.cs b/Mine2d/game/frontend/renderer/ItemRenderer.cs
index 0d91e7c..86ac6c8 100644
--- a/Mine2d/game/frontend/renderer/ItemRenderer.cs
+++ b/Mine2d/game/frontend/renderer/ItemRenderer.cs
@@ -12,23 +12,23 @@ public class ItemRenderer : IRenderer
var world = gameState.World;
foreach (var chunk in world.Chunks)
{
- renderChunk(chunk.Value);
+ RenderChunk(chunk.Value);
}
}
- private static void renderChunk(Chunk chunk)
+ private static void RenderChunk(Chunk chunk)
{
var entities = chunk.Entities;
foreach (var entity in entities)
{
if (entity is ItemEntity itemEntity)
{
- renderItem(itemEntity);
+ RenderItem(itemEntity);
}
}
}
- private static void renderItem(ItemEntity itemEntity)
+ private static void RenderItem(ItemEntity itemEntity)
{
var item = itemEntity.ItemId;
var position = itemEntity.Position;
diff --git a/Mine2d/game/state/Player.cs b/Mine2d/game/state/Player.cs
index 18c3ac8..c19cbd0 100644
--- a/Mine2d/game/state/Player.cs
+++ b/Mine2d/game/state/Player.cs
@@ -8,7 +8,7 @@ public class Player
public Guid Id { get; set; }
public Vector2 Mining { get; set; }
public int MiningCooldown { get; set; }
- public PlayerInventory inventory { get; set; } = new();
+ public PlayerInventory Inventory { get; set; } = new();
public Vector2 GetCenter()
{