feat: wip: support list server req and resp
This commit is contained in:
parent
acb1e43b08
commit
fb863fb7e0
5 changed files with 171 additions and 80 deletions
|
@ -1,5 +1,6 @@
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
|
using GServer.Common.Game.Entities;
|
||||||
using GServer.Common.Networking.Core;
|
using GServer.Common.Networking.Core;
|
||||||
using GServer.Common.Networking.Enums;
|
using GServer.Common.Networking.Enums;
|
||||||
using GServer.Common.Networking.Messages.Client;
|
using GServer.Common.Networking.Messages.Client;
|
||||||
|
@ -7,10 +8,12 @@ using GServer.Common.Networking.Messages.Server;
|
||||||
|
|
||||||
namespace GServer.Client;
|
namespace GServer.Client;
|
||||||
|
|
||||||
public class Program
|
public static class Program
|
||||||
{
|
{
|
||||||
private const int ServerPort = 11000;
|
private const int ServerPort = 11000;
|
||||||
|
|
||||||
|
private static string? _sessionToken;
|
||||||
|
|
||||||
private static void Main(string[] args)
|
private static void Main(string[] args)
|
||||||
{
|
{
|
||||||
IPEndPoint serverEp = new(IPAddress.Any, ServerPort);
|
IPEndPoint serverEp = new(IPAddress.Any, ServerPort);
|
||||||
|
@ -18,46 +21,70 @@ public class Program
|
||||||
TcpClient tcpClient = new();
|
TcpClient tcpClient = new();
|
||||||
tcpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
|
tcpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
|
||||||
tcpClient.Connect(serverEp);
|
tcpClient.Connect(serverEp);
|
||||||
|
|
||||||
Console.WriteLine("Username...");
|
|
||||||
string username = Console.ReadLine()!;
|
|
||||||
|
|
||||||
Console.WriteLine("Password...");
|
|
||||||
string password = Console.ReadLine()!;
|
|
||||||
|
|
||||||
AuthMessage authMessage = new(username, password);
|
|
||||||
_ = tcpClient.Client.Send(authMessage.Serialize());
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
while (true)
|
while (_sessionToken is null)
|
||||||
{
|
{
|
||||||
byte[] bytes = new byte[tcpClient.Client.ReceiveBufferSize];
|
Console.WriteLine("Username...");
|
||||||
_ = tcpClient.Client.Receive(bytes);
|
string username = Console.ReadLine()!;
|
||||||
|
|
||||||
MessageMemoryStream stream = new(bytes);
|
Console.WriteLine("Password...");
|
||||||
|
string password = Console.ReadLine()!;
|
||||||
|
|
||||||
ClientPacketIn packetIn = (ClientPacketIn)stream.ReadByte();
|
AuthMessage authMessage = new(username, password);
|
||||||
switch (packetIn)
|
_ = tcpClient.Client.Send(authMessage.Serialize());
|
||||||
|
|
||||||
|
while (true)
|
||||||
{
|
{
|
||||||
case ClientPacketIn.AuthResponse:
|
Console.WriteLine("Listening for message...");
|
||||||
AuthResponseMessage authResultMessage = new(stream);
|
|
||||||
|
byte[] bytes = new byte[tcpClient.Client.ReceiveBufferSize];
|
||||||
|
_ = tcpClient.Client.Receive(bytes);
|
||||||
|
|
||||||
Console.WriteLine("Success = " + authResultMessage.IsSuccessful);
|
MessageMemoryStream stream = new(bytes);
|
||||||
Console.WriteLine("SessionToken = " + authResultMessage.SessionToken);
|
|
||||||
Console.WriteLine("FailureReason = " + authResultMessage.FailureReason);
|
|
||||||
|
|
||||||
break;
|
ClientPacketIn packetIn = (ClientPacketIn)stream.ReadByte();
|
||||||
|
switch (packetIn)
|
||||||
|
{
|
||||||
|
case ClientPacketIn.AuthResponse:
|
||||||
|
AuthResponseMessage authResultMessage = new(stream);
|
||||||
|
|
||||||
case ClientPacketIn.ListServersResponse:
|
Console.WriteLine("Success = " + authResultMessage.IsSuccessful);
|
||||||
break;
|
Console.WriteLine("SessionToken = " + authResultMessage.SessionToken);
|
||||||
|
Console.WriteLine("FailureReason = " + authResultMessage.FailureReason);
|
||||||
|
|
||||||
case ClientPacketIn.Unknown:
|
// Request server list as soon as login has succeeded
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
if (authResultMessage.IsSuccessful)
|
||||||
Console.WriteLine("Received unsupported packet.");
|
{
|
||||||
break;
|
Console.WriteLine("Getting server list...");
|
||||||
|
_ = tcpClient.Client.Send(new[] { (byte)ServerPacketIn.ListServers });
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ClientPacketIn.ListServersResponse:
|
||||||
|
ListServersResponseMessage listServersResponseMessage = new(stream);
|
||||||
|
|
||||||
|
Console.WriteLine("Here are the servers!");
|
||||||
|
|
||||||
|
foreach (ServerListing server in listServersResponseMessage.ServerListings)
|
||||||
|
{
|
||||||
|
Console.WriteLine(server.Name);
|
||||||
|
Console.WriteLine($"Desc: {server.Description}");
|
||||||
|
Console.WriteLine($"Address: {server.IpAddress}:{server.Port}");
|
||||||
|
Console.WriteLine($"Tier: {server.ServerTier}");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ClientPacketIn.Unknown:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Console.WriteLine("Received unsupported packet.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,4 +97,5 @@ public class Program
|
||||||
tcpClient.Close();
|
tcpClient.Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,13 @@ public class MessageMemoryStream : MemoryStream
|
||||||
return BitConverter.ToInt16(buffer);
|
return BitConverter.ToInt16(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long ReadInt64()
|
||||||
|
{
|
||||||
|
byte[] buffer = new byte[8];
|
||||||
|
_ = Read(buffer, 0, 8);
|
||||||
|
return BitConverter.ToInt64(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
public string ReadUtf8String(int length)
|
public string ReadUtf8String(int length)
|
||||||
{
|
{
|
||||||
byte[] bytes = new byte[length];
|
byte[] bytes = new byte[length];
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
using GServer.Common.Game.Entities;
|
||||||
|
using GServer.Common.Networking.Core;
|
||||||
|
using GServer.Common.Networking.Enums;
|
||||||
|
|
||||||
|
namespace GServer.Common.Networking.Messages.Server;
|
||||||
|
|
||||||
|
public class ListServersResponseMessage : BaseMessage, IMessage<ListServersResponseMessage>
|
||||||
|
{
|
||||||
|
public ServerListing[] ServerListings;
|
||||||
|
|
||||||
|
public const int SERVER_NAME_BYTES = 50;
|
||||||
|
public const int SERVER_DESCRIPTION_BYTES = 1000;
|
||||||
|
public const int SERVER_IP_BYTES = 15;
|
||||||
|
|
||||||
|
public ListServersResponseMessage(ServerListing[] serverListings) : base((byte)ClientPacketIn.ListServersResponse)
|
||||||
|
{
|
||||||
|
ServerListings = serverListings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ListServersResponseMessage(MessageMemoryStream stream) : base((byte)ClientPacketIn.ListServersResponse)
|
||||||
|
{
|
||||||
|
List<ServerListing> serverListings = [];
|
||||||
|
|
||||||
|
while (stream.Position != stream.Length)
|
||||||
|
{
|
||||||
|
// TODO: remove this from the packet as I don't think it's needed
|
||||||
|
// long blockSize = stream.ReadInt64();
|
||||||
|
|
||||||
|
ServerListing serverListing = new()
|
||||||
|
{
|
||||||
|
Name = stream.ReadUtf8String(SERVER_NAME_BYTES),
|
||||||
|
Description = stream.ReadUtf8String(SERVER_DESCRIPTION_BYTES),
|
||||||
|
Playercount = stream.ReadUInt16(),
|
||||||
|
IpAddress = stream.ReadUtf8String(SERVER_IP_BYTES),
|
||||||
|
Port = stream.ReadUInt16(),
|
||||||
|
ServerTier = (ServerTier)stream.ReadByte()
|
||||||
|
};
|
||||||
|
|
||||||
|
serverListings.Add(serverListing);
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerListings = serverListings.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] Serialize()
|
||||||
|
{
|
||||||
|
using MessageMemoryStream stream = new();
|
||||||
|
|
||||||
|
stream.WriteByte(PacketId);
|
||||||
|
|
||||||
|
foreach (ServerListing listing in ServerListings)
|
||||||
|
{
|
||||||
|
using MessageMemoryStream listingStream = new();
|
||||||
|
|
||||||
|
listingStream.WriteUtf8StringOfSize(SERVER_NAME_BYTES, listing.Name);
|
||||||
|
listingStream.WriteUtf8StringOfSize(SERVER_DESCRIPTION_BYTES, listing.Description);
|
||||||
|
listingStream.WriteUInt16(listing.Playercount);
|
||||||
|
listingStream.WriteUtf8StringOfSize(15, listing.IpAddress);
|
||||||
|
listingStream.WriteUInt16(listing.Port);
|
||||||
|
listingStream.WriteByte((byte)listing.ServerTier);
|
||||||
|
|
||||||
|
long listingBlockSize = listingStream.Length;
|
||||||
|
stream.WriteInt64(listingBlockSize);
|
||||||
|
stream.WriteBytes(listingStream.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
return stream.ToArray();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,42 +0,0 @@
|
||||||
using GServer.Common.Game.Entities;
|
|
||||||
using GServer.Common.Networking.Core;
|
|
||||||
using GServer.Common.Networking.Enums;
|
|
||||||
|
|
||||||
namespace GServer.Common.Networking.Messages.Server;
|
|
||||||
|
|
||||||
public class ListServersMessage : BaseMessage, IMessage<ListServersMessage>
|
|
||||||
{
|
|
||||||
public ServerListing[] ServerListings;
|
|
||||||
|
|
||||||
public const int SERVER_NAME_BYTES = 50;
|
|
||||||
|
|
||||||
public ListServersMessage(ServerListing[] serverListings) : base((byte)ServerPacketIn.ListServers)
|
|
||||||
{
|
|
||||||
ServerListings = serverListings;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] Serialize()
|
|
||||||
{
|
|
||||||
using MessageMemoryStream stream = new();
|
|
||||||
|
|
||||||
stream.WriteByte(PacketId);
|
|
||||||
|
|
||||||
foreach (ServerListing listing in ServerListings)
|
|
||||||
{
|
|
||||||
using MessageMemoryStream listingStream = new();
|
|
||||||
|
|
||||||
listingStream.WriteUtf8StringOfSize(50, listing.Name);
|
|
||||||
listingStream.WriteUtf8StringOfSize(1000, listing.Description);
|
|
||||||
listingStream.WriteUInt16(listing.Playercount);
|
|
||||||
listingStream.WriteUtf8StringOfSize(15, listing.IpAddress);
|
|
||||||
listingStream.WriteUInt16(listing.Port);
|
|
||||||
listingStream.WriteByte((byte)listing.ServerTier);
|
|
||||||
|
|
||||||
long listingBlockSize = listingStream.Length;
|
|
||||||
stream.WriteInt64(listingBlockSize);
|
|
||||||
stream.WriteBytes(listingStream.ToArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
return stream.ToArray();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +1,6 @@
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
|
using GServer.Common;
|
||||||
|
using GServer.Common.Game.Entities;
|
||||||
using GServer.Common.Networking.Core;
|
using GServer.Common.Networking.Core;
|
||||||
using GServer.Common.Networking.Enums;
|
using GServer.Common.Networking.Enums;
|
||||||
using GServer.Common.Networking.Messages;
|
using GServer.Common.Networking.Messages;
|
||||||
|
@ -26,24 +28,51 @@ public class TcpMessageHandler(
|
||||||
switch (serverPacketIn)
|
switch (serverPacketIn)
|
||||||
{
|
{
|
||||||
case ServerPacketIn.Auth:
|
case ServerPacketIn.Auth:
|
||||||
|
{
|
||||||
AuthMessage msg = new(messageStream);
|
AuthMessage msg = new(messageStream);
|
||||||
|
|
||||||
bool isPasswordCorrect = authService.IsPasswordCorrect(msg.Username, msg.Password);
|
bool isPasswordCorrect = authService.IsPasswordCorrect(msg.Username, msg.Password);
|
||||||
AuthResponseMessage resp = isPasswordCorrect
|
AuthResponseMessage resp = isPasswordCorrect
|
||||||
? new(true, Guid.NewGuid().ToString(), failureReason: null)
|
? new AuthResponseMessage(true, Guid.NewGuid().ToString(), failureReason: null)
|
||||||
: new(false, null, AuthResponseFailure.IncorrectLoginOrPassword);
|
: new AuthResponseMessage(false, null, AuthResponseFailure.IncorrectLoginOrPassword);
|
||||||
|
await SendMessageAsync(resp, clientSocket);
|
||||||
byte[] buffer = resp.Serialize();
|
|
||||||
_ = await clientSocket.SendAsync(buffer);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case ServerPacketIn.ListServers:
|
case ServerPacketIn.ListServers:
|
||||||
throw new NotImplementedException();
|
{
|
||||||
|
ServerListing[] serverListings =
|
||||||
|
[
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Name = "Testbed",
|
||||||
|
Description = "A server to hone your development skills and test new ideas.",
|
||||||
|
IpAddress = "255.255.255.255",
|
||||||
|
Port = 1337,
|
||||||
|
Playercount = 12,
|
||||||
|
ServerTier = ServerTier.Default
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
ListServersResponseMessage resp = new(serverListings);
|
||||||
|
await SendMessageAsync(resp, clientSocket);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Console.WriteLine($"Received unsupported packet.");
|
Console.WriteLine($"Received unsupported packet.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
private static async Task SendMessageAsync<TMessage>(
|
||||||
|
TMessage message,
|
||||||
|
Socket clientSocket) where TMessage : IMessage<TMessage>
|
||||||
|
{
|
||||||
|
byte[] buffer = message.Serialize();
|
||||||
|
_ = await clientSocket.SendAsync(buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue