87 lines
3.7 KiB
C#
87 lines
3.7 KiB
C#
#nullable enable
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using Cysharp.Threading.Tasks;
|
|
using ShrinkNetwork;
|
|
|
|
namespace ShrinkCommand.Integration
|
|
{
|
|
public static class ShrinkNetworkCommandBridge
|
|
{
|
|
public const string ExecuteRoute = "command/execute";
|
|
|
|
private static readonly object SyncRoot = new();
|
|
private static readonly HashSet<ShrinkNetworkService> RegisteredServices = new();
|
|
|
|
public static void RegisterService(
|
|
ShrinkNetworkService networkService,
|
|
ShrinkCommandService commandService,
|
|
ShrinkNetworkCommandBridgeOptions? options = null)
|
|
{
|
|
if (networkService == null)
|
|
throw new ArgumentNullException(nameof(networkService));
|
|
if (commandService == null)
|
|
throw new ArgumentNullException(nameof(commandService));
|
|
|
|
lock (SyncRoot)
|
|
{
|
|
if (RegisteredServices.Contains(networkService))
|
|
return;
|
|
RegisteredServices.Add(networkService);
|
|
}
|
|
|
|
options ??= new ShrinkNetworkCommandBridgeOptions();
|
|
|
|
EnsureMessagesRegistered(networkService);
|
|
var requirement = new ShrinkNetworkPermissionRequirement(options.Authority, options.Permission);
|
|
networkService.RegisterRequestHandler<ShrinkNetworkCommandRequest, ShrinkNetworkCommandResponse>(
|
|
(context, request) => HandleExecuteAsync(commandService, options, context, request),
|
|
requirement);
|
|
}
|
|
|
|
public static void EnsureMessagesRegistered(ShrinkNetworkService service)
|
|
{
|
|
if (!service.MessageRegistry.TryGetMeta(typeof(ShrinkNetworkCommandRequest), out _))
|
|
{
|
|
var requestAttribute = (ShrinkNetworkMessageAttribute)Attribute.GetCustomAttribute(
|
|
typeof(ShrinkNetworkCommandRequest),
|
|
typeof(ShrinkNetworkMessageAttribute),
|
|
false)!;
|
|
service.RegisterMessage(typeof(ShrinkNetworkCommandRequest), requestAttribute.Opcode, requestAttribute.Route);
|
|
}
|
|
|
|
if (!service.MessageRegistry.TryGetMeta(typeof(ShrinkNetworkCommandResponse), out _))
|
|
{
|
|
var responseAttribute = (ShrinkNetworkMessageAttribute)Attribute.GetCustomAttribute(
|
|
typeof(ShrinkNetworkCommandResponse),
|
|
typeof(ShrinkNetworkMessageAttribute),
|
|
false)!;
|
|
service.RegisterMessage(typeof(ShrinkNetworkCommandResponse), responseAttribute.Opcode, responseAttribute.Route);
|
|
}
|
|
}
|
|
|
|
private static async UniTask<ShrinkNetworkCommandResponse> HandleExecuteAsync(
|
|
ShrinkCommandService commandService,
|
|
ShrinkNetworkCommandBridgeOptions options,
|
|
ShrinkNetworkContext context,
|
|
ShrinkNetworkCommandRequest request)
|
|
{
|
|
var source = options.SourceFactory?.Invoke(context, request) ?? new ShrinkNetworkCommandSource(context, request);
|
|
var result = await commandService.ExecuteAsync(source, request.CommandLine);
|
|
var output = source is ShrinkNetworkCommandSource networkSource
|
|
? networkSource.BuildOutputMessage(result.Message)
|
|
: result.Message;
|
|
|
|
return new ShrinkNetworkCommandResponse
|
|
{
|
|
ServiceName = string.IsNullOrWhiteSpace(request.ServiceName) ? options.ServiceName : request.ServiceName.Trim(),
|
|
CommandLine = request.CommandLine ?? string.Empty,
|
|
OutputMessage = output,
|
|
ErrorCode = result.IsSuccess ? 0 : ShrinkRpcErrorCode.HandlerException,
|
|
ErrorMessage = result.IsSuccess ? string.Empty : output
|
|
};
|
|
}
|
|
}
|
|
}
|