feat(cordis): 接入上下文组合与模组事务热替换
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
#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
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user