initialize repo
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
using Civilization.Shared.Packets.ServerMessages;
|
||||
|
||||
namespace Civilization.Server.Networking.Interfaces;
|
||||
|
||||
public interface IClientConnection
|
||||
{
|
||||
int PlayerId { get; }
|
||||
Task SendAsync(BaseServerMessage message);
|
||||
}
|
@@ -0,0 +1,8 @@
|
||||
using Civilization.Server.Game;
|
||||
|
||||
namespace Civilization.Server.Networking.Interfaces;
|
||||
|
||||
public interface ITransport
|
||||
{
|
||||
Task StartAsync(GameSessionCoordinator coordinator, CancellationToken cancellationToken = default);
|
||||
}
|
25
Lib/Civilization.Server/Networking/TcpClientConnection.cs
Normal file
25
Lib/Civilization.Server/Networking/TcpClientConnection.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using System.Text.Json;
|
||||
using Civilization.Server.Networking.Interfaces;
|
||||
using Civilization.Shared;
|
||||
using Civilization.Shared.Packets.ServerMessages;
|
||||
|
||||
namespace Civilization.Server.Networking;
|
||||
|
||||
public class TcpClientConnection : IClientConnection
|
||||
{
|
||||
private readonly StreamWriter _writer;
|
||||
|
||||
public int PlayerId { get; }
|
||||
|
||||
public TcpClientConnection(int playerId, Stream stream)
|
||||
{
|
||||
PlayerId = playerId;
|
||||
_writer = new StreamWriter(stream) { AutoFlush = true };
|
||||
}
|
||||
|
||||
public Task SendAsync(BaseServerMessage message)
|
||||
{
|
||||
var json = JsonSerializer.Serialize(message, SharedJson.Options);
|
||||
return _writer.WriteLineAsync(json);
|
||||
}
|
||||
}
|
@@ -0,0 +1,74 @@
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text.Json;
|
||||
using Civilization.Server.Game;
|
||||
using Civilization.Server.Networking.Interfaces;
|
||||
using Civilization.Shared;
|
||||
using Civilization.Shared.Packets;
|
||||
|
||||
namespace Civilization.Server.Networking.Transports;
|
||||
|
||||
public class TcpTransport : ITransport
|
||||
{
|
||||
private readonly int _port;
|
||||
|
||||
public TcpTransport(int port = 9000)
|
||||
{
|
||||
_port = port;
|
||||
}
|
||||
|
||||
public async Task StartAsync(GameSessionCoordinator coordinator, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var listener = new TcpListener(IPAddress.Any, _port);
|
||||
listener.Start();
|
||||
Console.WriteLine($"TCP transport listening on port {_port}");
|
||||
|
||||
var nextPlayerId = 0;
|
||||
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
var client = await listener.AcceptTcpClientAsync(cancellationToken);
|
||||
_ = HandleClientAsync(client, nextPlayerId++, coordinator, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task HandleClientAsync(
|
||||
TcpClient client,
|
||||
int playerId,
|
||||
GameSessionCoordinator coordinator,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
Console.WriteLine($"Client {playerId} connected.");
|
||||
var stream = client.GetStream();
|
||||
var reader = new StreamReader(stream);
|
||||
var writer = new StreamWriter(stream) { AutoFlush = true };
|
||||
|
||||
await writer.WriteLineAsync($"{{\"info\": \"You are Player {playerId}\"}}");
|
||||
|
||||
var connection = new TcpClientConnection(playerId, stream);
|
||||
|
||||
await coordinator.RegisterPlayerAsync(playerId, connection);
|
||||
|
||||
while (!cancellationToken.IsCancellationRequested && client.Connected)
|
||||
{
|
||||
var line = await reader.ReadLineAsync(cancellationToken);
|
||||
if (line is null)
|
||||
break;
|
||||
|
||||
try
|
||||
{
|
||||
var message = JsonSerializer.Deserialize<ClientMessage>(line, SharedJson.Options);
|
||||
if (message is not null)
|
||||
{
|
||||
await coordinator.ReceiveCommandAsync(message);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"[Player {playerId}] Failed to process message: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine($"Client {playerId} disconnected.");
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user