Game server admin API (#26880)
* Reapply "Game server api" (#26871)
This reverts commit 3aee197923.
* Rewrite 75% of the code it's good now
This commit is contained in:
committed by
GitHub
parent
9752746775
commit
9d0dfcf2b9
147
Content.Server/Administration/ServerApi.Utility.cs
Normal file
147
Content.Server/Administration/ServerApi.Utility.cs
Normal file
@@ -0,0 +1,147 @@
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Robust.Server.ServerStatus;
|
||||
|
||||
namespace Content.Server.Administration;
|
||||
|
||||
public sealed partial class ServerApi
|
||||
{
|
||||
private void RegisterHandler(HttpMethod method, string exactPath, Func<IStatusHandlerContext, Task> handler)
|
||||
{
|
||||
_statusHost.AddHandler(async context =>
|
||||
{
|
||||
if (context.RequestMethod != method || context.Url.AbsolutePath != exactPath)
|
||||
return false;
|
||||
|
||||
if (!await CheckAccess(context))
|
||||
return true;
|
||||
|
||||
await handler(context);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
private void RegisterActorHandler(HttpMethod method, string exactPath, Func<IStatusHandlerContext, Actor, Task> handler)
|
||||
{
|
||||
RegisterHandler(method, exactPath, async context =>
|
||||
{
|
||||
if (await CheckActor(context) is not { } actor)
|
||||
return;
|
||||
|
||||
await handler(context, actor);
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Async helper function which runs a task on the main thread and returns the result.
|
||||
/// </summary>
|
||||
private async Task<T> RunOnMainThread<T>(Func<T> func)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<T>();
|
||||
_taskManager.RunOnMainThread(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
taskCompletionSource.TrySetResult(func());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
taskCompletionSource.TrySetException(e);
|
||||
}
|
||||
});
|
||||
|
||||
var result = await taskCompletionSource.Task;
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs an action on the main thread. This does not return any value and is meant to be used for void functions. Use <see cref="RunOnMainThread{T}"/> for functions that return a value.
|
||||
/// </summary>
|
||||
private async Task RunOnMainThread(Action action)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource();
|
||||
_taskManager.RunOnMainThread(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
action();
|
||||
taskCompletionSource.TrySetResult();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
taskCompletionSource.TrySetException(e);
|
||||
}
|
||||
});
|
||||
|
||||
await taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
private async Task RunOnMainThread(Func<Task> action)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource();
|
||||
// ReSharper disable once AsyncVoidLambda
|
||||
_taskManager.RunOnMainThread(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await action();
|
||||
taskCompletionSource.TrySetResult();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
taskCompletionSource.TrySetException(e);
|
||||
}
|
||||
});
|
||||
|
||||
await taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper function to read JSON encoded data from the request body.
|
||||
/// </summary>
|
||||
private static async Task<T?> ReadJson<T>(IStatusHandlerContext context) where T : notnull
|
||||
{
|
||||
try
|
||||
{
|
||||
var json = await context.RequestBodyJsonAsync<T>();
|
||||
if (json == null)
|
||||
await RespondBadRequest(context, "Request body is null");
|
||||
|
||||
return json;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
await RespondBadRequest(context, "Unable to parse request body", ExceptionData.FromException(e));
|
||||
return default;
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task RespondError(
|
||||
IStatusHandlerContext context,
|
||||
ErrorCode errorCode,
|
||||
HttpStatusCode statusCode,
|
||||
string message,
|
||||
ExceptionData? exception = null)
|
||||
{
|
||||
await context.RespondJsonAsync(new BaseResponse(message, errorCode, exception), statusCode)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private static async Task RespondBadRequest(
|
||||
IStatusHandlerContext context,
|
||||
string message,
|
||||
ExceptionData? exception = null)
|
||||
{
|
||||
await RespondError(context, ErrorCode.BadRequest, HttpStatusCode.BadRequest, message, exception)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private static async Task RespondOk(IStatusHandlerContext context)
|
||||
{
|
||||
await context.RespondJsonAsync(new BaseResponse("OK"))
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private static string FormatLogActor(Actor actor) => $"{actor.Name} ({actor.Guid})";
|
||||
}
|
||||
Reference in New Issue
Block a user