RpcServer.cs
using System;
using System.Collections.Generic;
using Sandbox;

namespace Orizon;

/// <summary>
/// Provides a way to send RPC requests from the client to the server.
/// </summary>
public static class RpcServer
{
	private static readonly Dictionary<Type, Delegate> _handlers = new();

	/// <summary>
	/// Registers a handler for an RPC request type.
	/// </summary>
	/// <typeparam name="TRequest">The type of the request.</typeparam>
	/// <typeparam name="TResponse">The type of the response.</typeparam>
	/// <param name="handler">The handler to register.</param>
	public static void RegisterHandler<TRequest, TResponse>( Func<TRequest, TResponse> handler )
		where TRequest : struct, IRpcRequest
		where TResponse : struct, IRpcResponse
	{
		_handlers[typeof(TRequest)] = handler;
	}

	/// <summary>
	/// Handles an incoming RPC request on the host.
	/// </summary>
	/// <param name="request">The request to handle.</param>
	[Rpc.Host]
	internal static void HandleRequest( IRpcRequest request )
	{
		var reqType = request.GetType();

		if ( _handlers.TryGetValue( reqType, out var handler ) )
		{
			var result = handler.DynamicInvoke( request );
			if ( result is not IRpcResponse response ) return;

			response.CallbackId = request.CallbackId;
			
			using ( Rpc.FilterInclude( Rpc.Caller ) )
				RpcTransport.SendToClient( response );
		}
		else
		{
			throw new Exception( $"Aucun handler enregistré pour le type {reqType.Name}" );
		}
	}
}