/* * Copyright 2023 Eduard Kargin * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using Ragon.Protocol; using Ragon.Server.IO; using Ragon.Server.Lobby; using Ragon.Server.Logging; using Ragon.Server.Plugin; namespace Ragon.Server.Handler { public sealed class AuthorizationOperation : BaseOperation { private readonly IRagonLogger _logger = LoggerManager.GetLogger(nameof(AuthorizationOperation)); private readonly IServerPlugin _serverPlugin; private readonly RagonContextObserver _observer; private readonly RagonServerConfiguration _configuration; private readonly RagonBuffer _writer; public AuthorizationOperation(RagonBuffer reader, RagonBuffer writer, IServerPlugin serverPlugin, RagonContextObserver observer, RagonServerConfiguration configuration) : base(reader, writer) { _serverPlugin = serverPlugin; _configuration = configuration; _observer = observer; _writer = writer; } public override void Handle(RagonContext context, NetworkChannel channel) { if (context.ConnectionStatus == ConnectionStatus.Authorized) { _logger.Warning("Player already authorized!"); return; } if (context.ConnectionStatus == ConnectionStatus.InProcess) { _logger.Warning("Player already request authorization!"); return; } var configuration = _configuration; var key = Reader.ReadString(); var name = Reader.ReadString(); var payload = Reader.ReadString(); if (key == configuration.ServerKey) { var authorizeViaWebHook = _serverPlugin.OnAuthorize(new ConnectionRequest() { PeerID = context.Connection.Id }); if (authorizeViaWebHook) return; var lobbyPlayer = new RagonLobbyPlayer(context.Connection, Guid.NewGuid().ToString(), name, payload); context.SetPlayer(lobbyPlayer); Approve(context); } else { Reject(context); } } public void Approve(RagonContext context) { context.ConnectionStatus = ConnectionStatus.Authorized; _observer.OnAuthorized(context); var playerId = context.LobbyPlayer.Id; var playerName = context.LobbyPlayer.Name; var playerPayload = context.LobbyPlayer.Payload; _writer.Clear(); _writer.WriteOperation(RagonOperation.AUTHORIZED_SUCCESS); _writer.WriteString(playerId); _writer.WriteString(playerName); _writer.WriteString(playerPayload); var sendData = _writer.ToArray(); context.Connection.Reliable.Send(sendData); _logger.Trace($"Connection {context.Connection.Id} as {playerId}|{context.LobbyPlayer.Name} authorized"); } public void Reject(RagonContext context) { _writer.Clear(); _writer.WriteOperation(RagonOperation.AUTHORIZED_FAILED); var sendData = _writer.ToArray(); context.Connection.Reliable.Send(sendData); context.Connection.Close(); _logger.Trace($"Connection {context.Connection.Id}"); } } }