2024-11-24 18:50:58 -05:00
|
|
|
using Arrowgene.Ddon.Shared.Entity;
|
|
|
|
|
using Arrowgene.Ddon.Shared.Model;
|
|
|
|
|
using Arrowgene.Ddon.Shared.Network;
|
|
|
|
|
using Arrowgene.Logging;
|
2025-10-06 22:01:45 -07:00
|
|
|
using Npgsql;
|
2024-11-26 18:20:37 -08:00
|
|
|
using System;
|
2025-01-07 18:39:47 -08:00
|
|
|
using System.Data.SQLite;
|
2024-11-26 18:20:37 -08:00
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
2024-11-24 18:50:58 -05:00
|
|
|
|
|
|
|
|
namespace Arrowgene.Ddon.Server.Network
|
|
|
|
|
{
|
|
|
|
|
public abstract class RequestPacketQueueHandler<TClient, TReqStruct, TResStruct> : StructurePacketHandler<TClient, TReqStruct>
|
|
|
|
|
where TClient : Client
|
|
|
|
|
where TReqStruct : class, IPacketStructure, new()
|
|
|
|
|
where TResStruct : ServerResponse, new()
|
|
|
|
|
{
|
|
|
|
|
private static readonly ServerLogger Logger = LogProvider.Logger<ServerLogger>(typeof(RequestPacketQueueHandler<TClient, TReqStruct, TResStruct>));
|
|
|
|
|
|
|
|
|
|
protected RequestPacketQueueHandler(DdonServer<TClient> server) : base(server)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-26 18:20:37 -08:00
|
|
|
public abstract PacketQueue Handle(TClient client, TReqStruct request);
|
2024-11-24 18:50:58 -05:00
|
|
|
|
|
|
|
|
public sealed override void Handle(TClient client, StructurePacket<TReqStruct> request)
|
|
|
|
|
{
|
|
|
|
|
TResStruct response;
|
|
|
|
|
try
|
|
|
|
|
{
|
2024-11-26 18:20:37 -08:00
|
|
|
PacketQueue queue = Handle(client, request.Structure);
|
|
|
|
|
queue.Send();
|
2024-11-24 18:50:58 -05:00
|
|
|
}
|
2025-01-07 18:39:47 -08:00
|
|
|
catch (SQLiteException ex)
|
|
|
|
|
{
|
|
|
|
|
if (ex.ErrorCode == (int)SQLiteErrorCode.Busy)
|
|
|
|
|
{
|
|
|
|
|
response = new TResStruct();
|
|
|
|
|
response.Error = (uint)ErrorCode.ERROR_CODE_DB_DEAD_LOCK;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
response = new TResStruct();
|
|
|
|
|
response.Error = (uint)ErrorCode.ERROR_CODE_DB_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
client.Send(response);
|
|
|
|
|
client.Close(); // Do not tolerate SqLiteExceptions because of desync issues.
|
|
|
|
|
throw;
|
|
|
|
|
}
|
2025-10-06 22:01:45 -07:00
|
|
|
catch (PostgresException ex)
|
|
|
|
|
{
|
|
|
|
|
response = new TResStruct
|
|
|
|
|
{
|
|
|
|
|
Error = (uint)ErrorCode.ERROR_CODE_DB_FAILURE
|
|
|
|
|
};
|
|
|
|
|
client.Send(response);
|
|
|
|
|
client.Close();
|
|
|
|
|
throw;
|
|
|
|
|
}
|
2025-02-24 02:59:35 -08:00
|
|
|
catch (NotImplementedException ex)
|
|
|
|
|
{
|
|
|
|
|
throw new ResponseErrorException(ErrorCode.ERROR_CODE_NOT_IMPLEMENTED, ex.Message, ex);
|
|
|
|
|
}
|
2024-11-24 18:50:58 -05:00
|
|
|
catch (ResponseErrorException ex)
|
|
|
|
|
{
|
|
|
|
|
response = new TResStruct();
|
|
|
|
|
response.Error = (uint)ex.ErrorCode;
|
2024-11-26 18:20:37 -08:00
|
|
|
|
|
|
|
|
var stringBuilder = new StringBuilder();
|
|
|
|
|
stringBuilder.AppendLine($"{ex.ErrorCode} thrown when handling {typeof(TReqStruct).Name}");
|
|
|
|
|
if (ex.Message.Length > 0)
|
|
|
|
|
{
|
|
|
|
|
stringBuilder.AppendLine($"\tMessage: {ex.Message}");
|
|
|
|
|
}
|
|
|
|
|
stringBuilder.AppendLine(ex.StackTrace?.Split(Environment.NewLine).FirstOrDefault());
|
|
|
|
|
Logger.Error(client, stringBuilder.ToString());
|
|
|
|
|
|
2024-11-24 18:50:58 -05:00
|
|
|
client.Send(response);
|
2024-12-28 19:00:57 -08:00
|
|
|
|
|
|
|
|
if (ex.Critical)
|
|
|
|
|
{
|
|
|
|
|
client.Close();
|
|
|
|
|
}
|
2024-11-24 18:50:58 -05:00
|
|
|
}
|
|
|
|
|
catch (Exception)
|
|
|
|
|
{
|
|
|
|
|
response = new TResStruct();
|
|
|
|
|
response.Error = (uint)ErrorCode.ERROR_CODE_FAIL;
|
2025-01-07 18:39:47 -08:00
|
|
|
client.Send(response);
|
2024-11-24 18:50:58 -05:00
|
|
|
throw;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|