RpcClient.cs
using System;
using System.Threading.Tasks;
using Sandbox;

namespace Orizon;

/// <summary>
/// Provides a way to send RPC requests from the client to the server.
/// </summary>
public static class RpcClient
{
	/// <summary>
	/// Sends a request to the server and waits for the response.
	/// </summary>
	/// <typeparam name="TRequest">The type of the request.</typeparam>
	/// <typeparam name="TResponse">The type of the response.</typeparam>
	/// <param name="request">The request to send.</param>
	/// <returns>The response from the server.</returns>
	[ClientOnly]
	public static async Task<TResponse> SendRpc<TRequest, TResponse>( TRequest request )
		where TRequest : struct, IRpcRequest
		where TResponse : struct, IRpcResponse
	{
		request.CallbackId = Guid.NewGuid();

		RpcTransport.SendToServer( request );
		return await RpcCallbackManager.WaitForResponse<TResponse>( request.CallbackId );
	}

	/// <summary>
	/// Called by the RPC system when a response is received from the server.
	/// </summary>
	/// <param name="response">The response received from the server.</param>
	[Rpc.Broadcast(NetFlags.Reliable | NetFlags.HostOnly)]
	internal static void OnRpcResponse( IRpcResponse response )
	{
		RpcCallbackManager.CompleteResponse( response.CallbackId, response );
	}
}