KCP gameserver with packet dispatch, scene streaming, combat, gacha and the shop, plus a small HTTP server for the login flow and the wish history page. Game data under assets is pulled out of the client instead of being typed by hand. The excel tables come from the packed bin container and the spawn points from the compiled scene scripts.
48 lines
1.6 KiB
C#
48 lines
1.6 KiB
C#
using Yuanshen.Common.Security;
|
|
using Yuanshen.Gameserver.Controllers.Dispatching;
|
|
using Yuanshen.Gameserver.Network.Session;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace Yuanshen.Gameserver.Network.Kcp;
|
|
internal class KcpSession : NetSession
|
|
{
|
|
private const int MaxPacketSize = 32768;
|
|
private const int ReadTimeout = 30;
|
|
private const int WriteTimeout = 30;
|
|
|
|
private readonly byte[] _recvBuffer;
|
|
private readonly byte[] _sendBuffer;
|
|
|
|
public KcpSession(ILogger<NetSession> logger, NetSessionManager sessionManager, NetCommandDispatcher commandDispatcher) : base(logger, sessionManager, commandDispatcher)
|
|
{
|
|
_recvBuffer = GC.AllocateUninitializedArray<byte>(MaxPacketSize);
|
|
_sendBuffer = GC.AllocateUninitializedArray<byte>(MaxPacketSize);
|
|
}
|
|
|
|
public override async ValueTask RunAsync()
|
|
{
|
|
Memory<byte> buffer = _recvBuffer.AsMemory();
|
|
|
|
while (true)
|
|
{
|
|
int readAmount = await ReadWithTimeoutAsync(buffer, ReadTimeout);
|
|
if (readAmount <= 0)
|
|
break;
|
|
|
|
MhySecurity.Xor(buffer[..readAmount].Span, EncryptionKey);
|
|
int consumedBytes = await ConsumePacketsAsync(buffer[..readAmount]);
|
|
if (consumedBytes == -1)
|
|
break;
|
|
}
|
|
}
|
|
|
|
public override async ValueTask SendAsync(NetPacket packet)
|
|
{
|
|
Memory<byte> buffer = _sendBuffer.AsMemory();
|
|
|
|
int length = packet.EncodeTo(buffer);
|
|
MhySecurity.Xor(buffer[..length].Span, EncryptionKey);
|
|
|
|
await WriteWithTimeoutAsync(buffer[..length], WriteTimeout);
|
|
}
|
|
}
|