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 Permissions { get; } private readonly WebSocket webSocket; /// /// Create a new with the 's from the WebSocket . /// 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(); } /// /// Send information message containing the supplied string. /// public void SendMessage(string message) { SendWebSocketMessage(message, "info"); } /// /// Send error message containing the supplied string. /// public void SendError(string message) { SendWebSocketMessage(message, "error"); } /// /// Return target, if no target is present return the invoker. /// public T GetTargetOrInvoker() 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(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}"); } } } }