mirror of
https://github.com/thebreaddev/Supercell.GUT.git
synced 2024-11-10 07:44:37 +00:00
281d2789ea
not finished. early wip state
99 lines
2.9 KiB
C#
99 lines
2.9 KiB
C#
using Supercell.GUT.Logic;
|
|
using Supercell.GUT.Logic.Avatar;
|
|
using Supercell.GUT.Server.Protocol;
|
|
using Supercell.GUT.Titan.Logic.Message;
|
|
|
|
namespace Supercell.GUT.Server.Network.Connection;
|
|
internal class ClientConnection
|
|
{
|
|
private const int ReceiveBufferSize = 16384;
|
|
private const int ReceiveTimeoutMs = 30000;
|
|
|
|
private readonly IConnectionListener _listener;
|
|
private readonly MessageManager _messageManager;
|
|
|
|
public LogicClientAvatar? LogicClientAvatar { get; set; }
|
|
|
|
private readonly byte[] _receiveBuffer;
|
|
private IProtocolEntity? _protocolEntity;
|
|
private DateTime _lastKeepAliveTime;
|
|
|
|
public bool IsAlive => (DateTime.Now - _lastKeepAliveTime).TotalSeconds < 30.0f;
|
|
|
|
public ClientConnection(IConnectionListener listener, MessageManager messageManager)
|
|
{
|
|
_listener = listener;
|
|
_listener.OnSend = SendAsync;
|
|
_listener.RecvCallback = OnMessage;
|
|
|
|
_messageManager = messageManager;
|
|
|
|
_receiveBuffer = GC.AllocateUninitializedArray<byte>(ReceiveBufferSize);
|
|
_lastKeepAliveTime = DateTime.Now;
|
|
}
|
|
|
|
public async Task RunAsync()
|
|
{
|
|
int receiveBufferIndex = 0;
|
|
Memory<byte> receiveBufferMem = _receiveBuffer.AsMemory();
|
|
|
|
while (true)
|
|
{
|
|
int readAmount = await ReceiveAsync(receiveBufferMem[receiveBufferIndex..], ReceiveTimeoutMs);
|
|
if (readAmount == 0) break;
|
|
|
|
receiveBufferIndex += readAmount;
|
|
int consumedBytes = await _listener.OnReceive(receiveBufferMem, receiveBufferIndex);
|
|
|
|
if (consumedBytes > 0)
|
|
{
|
|
Buffer.BlockCopy(_receiveBuffer, consumedBytes, _receiveBuffer, 0, receiveBufferIndex -= consumedBytes);
|
|
}
|
|
else if (consumedBytes < 0) break;
|
|
}
|
|
}
|
|
|
|
public async Task SendMessage(PiranhaMessage message)
|
|
{
|
|
await _listener.Send(message);
|
|
}
|
|
|
|
public void RefreshKeepAliveTime()
|
|
{
|
|
_lastKeepAliveTime = DateTime.Now;
|
|
}
|
|
|
|
public void SetProtocolEntity(IProtocolEntity protocolEntity)
|
|
{
|
|
_protocolEntity = protocolEntity;
|
|
}
|
|
|
|
public IProtocolEntity ProtocolEntity
|
|
{
|
|
get
|
|
{
|
|
return _protocolEntity ?? throw new InvalidOperationException("Trying to access _protocolEntity when it's NULL!");
|
|
}
|
|
}
|
|
|
|
private async Task OnMessage(PiranhaMessage message)
|
|
{
|
|
await _messageManager.ReceiveMessage(message);
|
|
}
|
|
|
|
private async ValueTask<int> ReceiveAsync(Memory<byte> buffer, int timeoutMs)
|
|
{
|
|
CancellationTokenSource cts = new(TimeSpan.FromMilliseconds(timeoutMs));
|
|
return await ProtocolEntity.ReceiveAsync(buffer, cts.Token);
|
|
}
|
|
|
|
private async ValueTask SendAsync(Memory<byte> buffer)
|
|
{
|
|
await ProtocolEntity.SendAsync(buffer, default);
|
|
}
|
|
|
|
public void SetNonce(string nonce)
|
|
{
|
|
_listener.InitEncryption(LogicVersion.GetKey(), nonce);
|
|
}
|
|
}
|