mirror of
https://github.com/NexusForever/NexusForever
synced 2026-08-14 00:26:05 -04:00
85 lines
2.9 KiB
C#
85 lines
2.9 KiB
C#
using System;
|
|
using System.Collections.Immutable;
|
|
using System.IO;
|
|
using System.Net.WebSockets;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using Newtonsoft.Json;
|
|
using Newtonsoft.Json.Linq;
|
|
using NexusForever.Shared.GameTable.Static;
|
|
using NexusForever.WorldServer.Game.Entity;
|
|
using NexusForever.WorldServer.Game.RBAC;
|
|
using NexusForever.WorldServer.Game.RBAC.Static;
|
|
using NLog;
|
|
|
|
namespace NexusForever.WorldServer.Command.Context
|
|
{
|
|
public class WebSocketCommandContext : ICommandContext
|
|
{
|
|
private static readonly ILogger log = LogManager.GetCurrentClassLogger();
|
|
|
|
public WorldEntity Invoker { get; }
|
|
public WorldEntity Target { get; }
|
|
|
|
public Language Language { get; } = Language.English;
|
|
public ImmutableHashSet<Permission> Permissions { get; }
|
|
|
|
private readonly WebSocket webSocket;
|
|
|
|
/// <summary>
|
|
/// Create a new <see cref="WebSocketCommandContext"/> with the <see cref="Permission"/>'s from the WebSocket <see cref="Role"/>.
|
|
/// </summary>
|
|
public WebSocketCommandContext(WebSocket webSocket)
|
|
{
|
|
this.webSocket = webSocket;
|
|
|
|
// console role needs to exist in order for the websocket command context to work
|
|
RBACRole role = RBACManager.Instance.GetRole(Role.WebSocket);
|
|
if (role == null)
|
|
throw new InvalidDataException("WebSocket role doesn't exist!");
|
|
|
|
Permissions = role.Permissions.Keys.ToImmutableHashSet();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Send information message containing the supplied string.
|
|
/// </summary>
|
|
public void SendMessage(string message)
|
|
{
|
|
SendWebSocketMessage(message, "info");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Send error message containing the supplied string.
|
|
/// </summary>
|
|
public void SendError(string message)
|
|
{
|
|
SendWebSocketMessage(message, "error");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Return <see cref="WorldEntity"/> target, if no target is present return the <see cref="WorldEntity"/> invoker.
|
|
/// </summary>
|
|
public T GetTargetOrInvoker<T>() where T : WorldEntity
|
|
{
|
|
return null;
|
|
}
|
|
|
|
private async void SendWebSocketMessage(string text, string type)
|
|
{
|
|
if (webSocket.State != WebSocketState.Open)
|
|
return;
|
|
|
|
try
|
|
{
|
|
string message = JObject.FromObject(new { text, type }).ToString(Formatting.None);
|
|
await webSocket.SendAsync(new ArraySegment<byte>(Encoding.UTF8.GetBytes(message)), WebSocketMessageType.Text, true, CancellationToken.None)
|
|
.ConfigureAwait(false);
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
log.Error(exception, $"Failed to send {type} message to websocket client, message was: {text}");
|
|
}
|
|
}
|
|
}
|
|
}
|