using GenHTTP.Api.Content.Authentication; using InABox.Clients; using InABox.Core; using Microsoft.Exchange.WebServices.Data; using NPOI.SS.Formula.Functions; namespace InABox.Rpc { public abstract class RpcCommandHandler : IRpcCommandHandler where TSender : class where TCommand : IRpcCommand where TParameters : IRpcCommandParameters, new() where TResult : IRpcCommandResult { public TSender Sender { get; } private static readonly bool IsLogCommand = typeof(TCommand).IsAssignableTo(typeof(IRpcLogCommand)); public RpcCommandHandler(TSender sender) { Sender = sender ?? throw new ArgumentNullException(nameof(sender)); } protected abstract TResult Execute(IRpcSession session, TParameters parameters); public byte[] Execute(IRpcSession session, byte[] payload) { var start = DateTime.Now; var parameters = Serialization.ReadBinary(payload, BinarySerializationSettings.Latest); if (IsLogCommand) Logger.Send(LogType.Information, session.UserID, $"[{session.Platform} {session.Version}] {parameters.ShortDescription()}: {parameters.FullDescription()}"); try { var result = Execute(session, parameters); if (IsLogCommand) { Logger.Send(LogType.Information, session.UserID, string.Format( "[{0} {1}] [{2:D8}] {3} Complete: {4}", session.Platform, session.Version, (int)DateTime.Now.Subtract(start).TotalMilliseconds, parameters.ShortDescription(), result.FullDescription() ) ); } return Serialization.WriteBinary(result, BinarySerializationSettings.Latest); } catch (RpcException) { throw; } catch (Exception e) { Logger.Send(LogType.Information, session.UserID, string.Format("[{0} {1}] [{2:D8}] {3} failed: {4}\n\n{5}", session.Platform, session.Version, (int)DateTime.Now.Subtract(start).TotalMilliseconds, parameters.ShortDescription(), e.Message, e.StackTrace)); throw new RpcException(e.Message, RpcError.SERVERERROR); } } } }