diff --git a/src/MHServerEmu.Core/Network/CoreNetworkMailbox.cs b/src/MHServerEmu.Core/Network/CoreNetworkMailbox.cs index 948978b1..ebd734c3 100644 --- a/src/MHServerEmu.Core/Network/CoreNetworkMailbox.cs +++ b/src/MHServerEmu.Core/Network/CoreNetworkMailbox.cs @@ -1,7 +1,6 @@ using Gazillion; using Google.ProtocolBuffers; using MHServerEmu.Core.Logging; -using MHServerEmu.Core.Network.Tcp; using MHServerEmu.Core.System.Time; namespace MHServerEmu.Core.Network @@ -25,7 +24,7 @@ namespace MHServerEmu.Core.Network /// /// Deserializes the provided instance and adds its contents to this as a . /// - public bool Post(ITcpClient client, MessageBuffer messageBuffer) + public bool Post(IFrontendClient client, in MessageBuffer messageBuffer) { uint messageId = messageBuffer.MessageId; diff --git a/src/MHServerEmu.Core/Network/GameServiceProtocol.cs b/src/MHServerEmu.Core/Network/GameServiceProtocol.cs index 87be2ed2..5b718741 100644 --- a/src/MHServerEmu.Core/Network/GameServiceProtocol.cs +++ b/src/MHServerEmu.Core/Network/GameServiceProtocol.cs @@ -1,6 +1,4 @@ -using MHServerEmu.Core.Network.Tcp; - -namespace MHServerEmu.Core.Network +namespace MHServerEmu.Core.Network { /// /// Marker interface for messages. @@ -16,32 +14,32 @@ namespace MHServerEmu.Core.Network // out a more performant way to send messages without overcomplicating everything // (e.g. using the visitor pattern here would probably work, but it may be too cumbersome). - public readonly struct AddClient(ITcpClient client) : IGameServiceMessage + public readonly struct AddClient(IFrontendClient client) : IGameServiceMessage { - public readonly ITcpClient Client = client; + public readonly IFrontendClient Client = client; } - public readonly struct RemoveClient(ITcpClient client) : IGameServiceMessage + public readonly struct RemoveClient(IFrontendClient client) : IGameServiceMessage { - public readonly ITcpClient Client = client; + public readonly IFrontendClient Client = client; } - public readonly struct RouteMessageBufferList(ITcpClient client, ushort muxId, IReadOnlyList messageBufferList) : IGameServiceMessage + public readonly struct RouteMessageBufferList(IFrontendClient client, ushort muxId, IReadOnlyList messageBufferList) : IGameServiceMessage { - public readonly ITcpClient Client = client; + public readonly IFrontendClient Client = client; public readonly ushort MuxId = muxId; public readonly IReadOnlyList MessageBufferList = messageBufferList; } - public readonly struct RouteMessageBuffer(ITcpClient client, MessageBuffer messageBuffer) : IGameServiceMessage + public readonly struct RouteMessageBuffer(IFrontendClient client, MessageBuffer messageBuffer) : IGameServiceMessage { - public readonly ITcpClient Client = client; + public readonly IFrontendClient Client = client; public readonly MessageBuffer MessageBuffer = messageBuffer; } - public readonly struct RouteMessage(ITcpClient client, Type protocol, MailboxMessage message) : IGameServiceMessage + public readonly struct RouteMessage(IFrontendClient client, Type protocol, MailboxMessage message) : IGameServiceMessage { - public readonly ITcpClient Client = client; + public readonly IFrontendClient Client = client; public readonly Type Protocol = protocol; public readonly MailboxMessage Message = message; } diff --git a/src/MHServerEmu.Core/Network/IFrontendClient.cs b/src/MHServerEmu.Core/Network/IFrontendClient.cs new file mode 100644 index 00000000..d79cc429 --- /dev/null +++ b/src/MHServerEmu.Core/Network/IFrontendClient.cs @@ -0,0 +1,34 @@ +using Google.ProtocolBuffers; + +namespace MHServerEmu.Core.Network +{ + /// + /// Represents a frontend's connection to a remote game client. + /// + public interface IFrontendClient + { + public bool IsConnected { get; } + + public ulong GameId { get; set; } // REMOVEME: Replace this with a service message + + /// + /// Disconnects this . + /// + public void Disconnect(); + + /// + /// Sends the provided over the specified mux channel. + /// + public void SendMuxCommand(ushort muxId, MuxCommand command); + + /// + /// Sends the provided over the specified mux channel. + /// + public void SendMessage(ushort muxId, IMessage message); + + /// + /// Sends the provided of instances over the specified mux channel. + /// + public void SendMessageList(ushort muxId, List messageList); + } +} diff --git a/src/MHServerEmu.Core/Network/MessageList.cs b/src/MHServerEmu.Core/Network/MessageList.cs index 9a8acd4e..b11a6f1d 100644 --- a/src/MHServerEmu.Core/Network/MessageList.cs +++ b/src/MHServerEmu.Core/Network/MessageList.cs @@ -1,5 +1,4 @@ using MHServerEmu.Core.Logging; -using MHServerEmu.Core.Network.Tcp; namespace MHServerEmu.Core.Network { @@ -16,7 +15,7 @@ namespace MHServerEmu.Core.Network private static readonly Logger Logger = LogManager.CreateLogger(); - private Queue<(ITcpClient, MailboxMessage)> _messageQueue = new(); + private Queue<(IFrontendClient, MailboxMessage)> _messageQueue = new(); /// /// Returns if this instance has any queued messages. @@ -26,9 +25,9 @@ namespace MHServerEmu.Core.Network // NOTE: Rather than exposing the underlying data structure like the client, we encapsulate it with Enqueue() / TransferFrom() / Clear() methods. /// - /// Enqueues the provided from an . + /// Enqueues the provided from an . /// - public void Enqueue(ITcpClient client, MailboxMessage message) + public void Enqueue(IFrontendClient client, MailboxMessage message) { // NOTE: In the client this is done by calling FastList::InsertTailList() _messageQueue.Enqueue((client, message)); @@ -68,11 +67,11 @@ namespace MHServerEmu.Core.Network /// /// Retrieves the next queued instance without removing it from the queue. /// - public (ITcpClient, MailboxMessage) PeekNextMessage() + public (IFrontendClient, MailboxMessage) PeekNextMessage() { // Do we even need peeking considering we have the HasMessages properties? if (_messageQueue.TryPeek(out var result) == false) - return Logger.WarnReturn<(ITcpClient, MailboxMessage)>(default, $"PeekNextMessage(): No messages to peek"); + return Logger.WarnReturn<(IFrontendClient, MailboxMessage)>(default, $"PeekNextMessage(): No messages to peek"); return result; } @@ -80,10 +79,10 @@ namespace MHServerEmu.Core.Network /// /// Retrieves the next queued instance. /// - public (ITcpClient, MailboxMessage) PopNextMessage() + public (IFrontendClient, MailboxMessage) PopNextMessage() { if (_messageQueue.TryDequeue(out var result) == false) - return Logger.WarnReturn<(ITcpClient, MailboxMessage)>(default, $"PopNextMessage(): No messages to pop"); + return Logger.WarnReturn<(IFrontendClient, MailboxMessage)>(default, $"PopNextMessage(): No messages to pop"); return result; } diff --git a/src/MHServerEmu.Core/Network/MuxReader.cs b/src/MHServerEmu.Core/Network/MuxReader.cs index ea566aa0..b655a176 100644 --- a/src/MHServerEmu.Core/Network/MuxReader.cs +++ b/src/MHServerEmu.Core/Network/MuxReader.cs @@ -1,5 +1,4 @@ using MHServerEmu.Core.Logging; -using MHServerEmu.Core.Network.Tcp; namespace MHServerEmu.Core.Network { @@ -10,7 +9,7 @@ namespace MHServerEmu.Core.Network } /// - /// Buffered reader for data received from . + /// Buffered reader for data received by an . /// public class MuxReader { @@ -24,7 +23,7 @@ namespace MHServerEmu.Core.Network private readonly MemoryStream _readBufferStream = new(new byte[ReadBufferSize]); private readonly List _messageBufferList = new(); - private readonly ITcpClient _client; + private readonly IFrontendClient _client; private MuxReaderState _state; private int _stateBytes; @@ -34,7 +33,7 @@ namespace MHServerEmu.Core.Network /// /// Constructs and initializes a new for the provided . /// - public MuxReader(ITcpClient client) + public MuxReader(IFrontendClient client) { _client = client; Reset(); @@ -131,7 +130,7 @@ namespace MHServerEmu.Core.Network { case MuxCommand.Connect: Logger.Trace($"Client [{_client}] connected on mux channel {header.MuxId}"); - _client.Connection.Send(new MuxPacket(header.MuxId, MuxCommand.ConnectAck)); + _client.SendMuxCommand(header.MuxId, MuxCommand.ConnectAck); Reset(); break; diff --git a/src/MHServerEmu.Core/Network/NetClient.cs b/src/MHServerEmu.Core/Network/NetClient.cs index e7f9131b..4ef0597d 100644 --- a/src/MHServerEmu.Core/Network/NetClient.cs +++ b/src/MHServerEmu.Core/Network/NetClient.cs @@ -1,5 +1,4 @@ using Google.ProtocolBuffers; -using MHServerEmu.Core.Network.Tcp; namespace MHServerEmu.Core.Network { @@ -11,23 +10,23 @@ namespace MHServerEmu.Core.Network private readonly ushort _muxChannel; private readonly List _pendingMessageList = new(); - public ITcpClient TcpClient { get; } + public IFrontendClient FrontendClient { get; } public virtual bool CanSendOrReceiveMessages { get => true; } /// - /// Constructs a new bound to the provided . + /// Constructs a new bound to the provided . /// - public NetClient(ushort muxChannel, ITcpClient tcpClient) + public NetClient(ushort muxChannel, IFrontendClient frontendClient) { - ArgumentNullException.ThrowIfNull(tcpClient); + ArgumentNullException.ThrowIfNull(frontendClient); _muxChannel = muxChannel; - TcpClient = tcpClient; + FrontendClient = frontendClient; } public void Disconnect() { - TcpClient.Disconnect(); + FrontendClient.Disconnect(); } /// @@ -46,7 +45,7 @@ namespace MHServerEmu.Core.Network if (_pendingMessageList.Count == 0) return; - TcpClient.SendMessageList(_muxChannel, _pendingMessageList); + FrontendClient.SendMessageList(_muxChannel, _pendingMessageList); _pendingMessageList.Clear(); } diff --git a/src/MHServerEmu.Core/Network/NetworkManager.cs b/src/MHServerEmu.Core/Network/NetworkManager.cs index 38890782..2cd486d0 100644 --- a/src/MHServerEmu.Core/Network/NetworkManager.cs +++ b/src/MHServerEmu.Core/Network/NetworkManager.cs @@ -1,6 +1,5 @@ using System.Collections; using MHServerEmu.Core.Logging; -using MHServerEmu.Core.Network.Tcp; namespace MHServerEmu.Core.Network { @@ -13,7 +12,7 @@ namespace MHServerEmu.Core.Network { private static readonly Logger Logger = LogManager.CreateLogger(); - private readonly Dictionary _netClientDict = new(); + private readonly Dictionary _netClientDict = new(); // Incoming messages are asynchronously posted to a mailbox where they are deserialized and stored for later retrieval. // When it's time to process messages, we copy all messages stored in our mailbox to a list. @@ -22,10 +21,10 @@ namespace MHServerEmu.Core.Network private readonly MessageList _messagesToProcessList = new(); // We swap queues with a lock when handling async client connect / disconnect events - private Queue _asyncAddClientQueue = new(); - private Queue _asyncRemoveClientQueue = new(); - private Queue _addClientQueue = new(); - private Queue _removeClientQueue = new(); + private Queue _asyncAddClientQueue = new(); + private Queue _asyncRemoveClientQueue = new(); + private Queue _addClientQueue = new(); + private Queue _removeClientQueue = new(); private SpinLock _addClientLock = new(false); private SpinLock _removeClientLock = new(false); @@ -42,10 +41,10 @@ namespace MHServerEmu.Core.Network /// /// Returns the bound to the provided . /// - public TNetClient GetNetClient(ITcpClient tcpClient) + public TNetClient GetNetClient(IFrontendClient frontendClient) { - if (_netClientDict.TryGetValue(tcpClient, out TNetClient netClient) == false) - Logger.Warn($"GetNetClient(): ITcpClient {tcpClient} is not bound to a NetClient"); + if (_netClientDict.TryGetValue(frontendClient, out TNetClient netClient) == false) + Logger.Warn($"GetNetClient(): IFrontendClient {frontendClient} is not bound to a NetClient"); return netClient; } @@ -62,9 +61,9 @@ namespace MHServerEmu.Core.Network } /// - /// Enqueues registration of a new for the provided during the next update. + /// Enqueues registration of a new for the provided during the next update. /// - public void AsyncAddClient(ITcpClient client) + public void AsyncAddClient(IFrontendClient client) { bool lockTaken = false; try @@ -80,9 +79,9 @@ namespace MHServerEmu.Core.Network } /// - /// Enqueues removal of the bound to the provided during the next update. + /// Enqueues removal of the bound to the provided during the next update. /// - public void AsyncRemoveClient(ITcpClient client) + public void AsyncRemoveClient(IFrontendClient client) { bool lockTaken = false; try @@ -100,16 +99,16 @@ namespace MHServerEmu.Core.Network /// /// Handles an incoming asynchronously. /// - public void AsyncReceiveMessageBuffer(ITcpClient tcpClient, MessageBuffer messageBuffer) + public void AsyncReceiveMessageBuffer(IFrontendClient frontendClient, in MessageBuffer messageBuffer) { // Gazillion's implementation does this in NetworkManager::ConnectionStatus() // If the message fails to deserialize it means either data got corrupted somehow or we have a hacker trying to mess things up. // In both cases it's better to bail out. - if (_mailbox.Post(tcpClient, messageBuffer) == false) + if (_mailbox.Post(frontendClient, messageBuffer) == false) { - Logger.Error($"AsyncPostMessage(): Message deserialization error for data from client, disconnecting. Client: {tcpClient}"); - tcpClient.Disconnect(); + Logger.Error($"AsyncPostMessage(): Message deserialization error for data from client, disconnecting. Client: {frontendClient}"); + frontendClient.Disconnect(); } } @@ -123,8 +122,8 @@ namespace MHServerEmu.Core.Network while (_messagesToProcessList.HasMessages) { - (ITcpClient tcpClient, MailboxMessage message) = _messagesToProcessList.PopNextMessage(); - TNetClient netClient = GetNetClient(tcpClient); + (IFrontendClient frontendClient, MailboxMessage message) = _messagesToProcessList.PopNextMessage(); + TNetClient netClient = GetNetClient(frontendClient); if (netClient != null && netClient.CanSendOrReceiveMessages) netClient.ReceiveMessage(message); @@ -145,10 +144,10 @@ namespace MHServerEmu.Core.Network protected bool RegisterNetClient(TNetClient netClient) { - return _netClientDict.TryAdd(netClient.TcpClient, netClient); + return _netClientDict.TryAdd(netClient.FrontendClient, netClient); } - protected abstract bool AcceptAndRegisterNewClient(ITcpClient tcpClient); + protected abstract bool AcceptAndRegisterNewClient(IFrontendClient tcpClient); protected abstract void OnNetClientDisconnected(TNetClient netClient); @@ -169,8 +168,8 @@ namespace MHServerEmu.Core.Network while (_addClientQueue.Count > 0) { - ITcpClient tcpClient = _addClientQueue.Dequeue(); - AcceptAndRegisterNewClient(tcpClient); + IFrontendClient frontendClient = _addClientQueue.Dequeue(); + AcceptAndRegisterNewClient(frontendClient); } } @@ -191,11 +190,11 @@ namespace MHServerEmu.Core.Network while (_removeClientQueue.Count > 0) { - ITcpClient tcpClient = _removeClientQueue.Dequeue(); + IFrontendClient frontendClient = _removeClientQueue.Dequeue(); - if (_netClientDict.Remove(tcpClient, out TNetClient netClient) == false) + if (_netClientDict.Remove(frontendClient, out TNetClient netClient) == false) { - Logger.Warn($"RemoveDisconnectedClients(): ITcpClient {tcpClient} not found"); + Logger.Warn($"RemoveDisconnectedClients(): IFrontendClient {frontendClient} not found"); continue; } @@ -206,12 +205,12 @@ namespace MHServerEmu.Core.Network /// /// A simple wrapper around - /// to iterate instances managed by this . + /// to iterate instances managed by this . /// public struct Enumerator : IEnumerator { private readonly NetworkManager _networkManager; - private Dictionary.ValueCollection.Enumerator _enumerator; + private Dictionary.ValueCollection.Enumerator _enumerator; public TNetClient Current { get => _enumerator.Current; } object IEnumerator.Current { get => Current; } diff --git a/src/MHServerEmu.Core/Network/Tcp/ITcpClient.cs b/src/MHServerEmu.Core/Network/Tcp/ITcpClient.cs index 84da1d98..90620656 100644 --- a/src/MHServerEmu.Core/Network/Tcp/ITcpClient.cs +++ b/src/MHServerEmu.Core/Network/Tcp/ITcpClient.cs @@ -1,6 +1,4 @@ -using Google.ProtocolBuffers; - -namespace MHServerEmu.Core.Network.Tcp +namespace MHServerEmu.Core.Network.Tcp { /// /// Provides access to a 's connection to a remote client. @@ -8,23 +6,5 @@ namespace MHServerEmu.Core.Network.Tcp public interface ITcpClient { public TcpClientConnection Connection { get; } - public bool IsConnected { get; } - - public ulong GameId { get; set; } // REMOVEME: Replace this with a service message - - /// - /// Disconnects this . - /// - public void Disconnect(); - - /// - /// Sends the provided over the specified mux channel. - /// - public void SendMessage(ushort muxId, IMessage message); - - /// - /// Sends the provided of instances over the specified mux channel. - /// - public void SendMessageList(ushort muxId, List messageList); } } diff --git a/src/MHServerEmu.Frontend/FrontendClient.cs b/src/MHServerEmu.Frontend/FrontendClient.cs index a2b0f8e8..aaed0e13 100644 --- a/src/MHServerEmu.Frontend/FrontendClient.cs +++ b/src/MHServerEmu.Frontend/FrontendClient.cs @@ -9,9 +9,9 @@ using MHServerEmu.DatabaseAccess.Models; namespace MHServerEmu.Frontend { /// - /// Represents an connected to the . + /// An implementation of backed by a . /// - public class FrontendClient : ITcpClient, IDBAccountOwner + public class FrontendClient : IFrontendClient, ITcpClient, IDBAccountOwner { private static readonly Logger Logger = LogManager.CreateLogger(); @@ -51,13 +51,19 @@ namespace MHServerEmu.Frontend return $"Account={Session.Account}, SessionId=0x{Session.Id:X}"; } - #region ITcpClient Implementation + #region IFrontendClient Implementation public void Disconnect() { Connection.Disconnect(); } + public void SendMuxCommand(ushort muxId, MuxCommand command) + { + MuxPacket packet = new(muxId, command); + Connection.Send(packet); + } + public void SendMessage(ushort muxId, IMessage message) { MuxPacket packet = new(muxId, MuxCommand.Data); diff --git a/src/MHServerEmu.Games/Game.cs b/src/MHServerEmu.Games/Game.cs index 20507a5b..9504af23 100644 --- a/src/MHServerEmu.Games/Game.cs +++ b/src/MHServerEmu.Games/Game.cs @@ -188,17 +188,17 @@ namespace MHServerEmu.Games IsRunning = false; } - public void AddClient(ITcpClient client) + public void AddClient(IFrontendClient client) { NetworkManager.AsyncAddClient(client); } - public void RemoveClient(ITcpClient client) + public void RemoveClient(IFrontendClient client) { NetworkManager.AsyncRemoveClient(client); } - public void ReceiveMessageBuffer(ITcpClient client, MessageBuffer messageBuffer) + public void ReceiveMessageBuffer(IFrontendClient client, in MessageBuffer messageBuffer) { NetworkManager.AsyncReceiveMessageBuffer(client, messageBuffer); } diff --git a/src/MHServerEmu.Games/Network/PlayerConnection.cs b/src/MHServerEmu.Games/Network/PlayerConnection.cs index a78d2b2e..5ee79119 100644 --- a/src/MHServerEmu.Games/Network/PlayerConnection.cs +++ b/src/MHServerEmu.Games/Network/PlayerConnection.cs @@ -5,7 +5,6 @@ using MHServerEmu.Core.Extensions; using MHServerEmu.Core.Logging; using MHServerEmu.Core.Memory; using MHServerEmu.Core.Network; -using MHServerEmu.Core.Network.Tcp; using MHServerEmu.Core.Serialization; using MHServerEmu.Core.System.Time; using MHServerEmu.Core.VectorMath; @@ -41,7 +40,7 @@ namespace MHServerEmu.Games.Network private static readonly Logger Logger = LogManager.CreateLogger(); - private readonly ITcpClient _tcpClient; + private readonly IFrontendClient _frontendClient; private readonly DBAccount _dbAccount; private bool _waitingForRegionIsAvailableResponse = false; @@ -64,13 +63,13 @@ namespace MHServerEmu.Games.Network /// /// Constructs a new . /// - public PlayerConnection(Game game, ITcpClient tcpClient) : base(MuxChannel, tcpClient) + public PlayerConnection(Game game, IFrontendClient frontendClient) : base(MuxChannel, frontendClient) { Game = game; - // The ITcpClient used by PlayerConnection also needs to implement IDBAccountOwner - _tcpClient = tcpClient; - _dbAccount = ((IDBAccountOwner)tcpClient).Account; + // IFrontendClient used by PlayerConnection also needs to implement IDBAccountOwner + _frontendClient = frontendClient; + _dbAccount = ((IDBAccountOwner)frontendClient).Account; AOI = new(this); WorldView = new(this); @@ -278,9 +277,9 @@ namespace MHServerEmu.Games.Network // Remove game id to let the player manager know that it is now safe to write to the database. // TODO: Replace this with a player manager message. - _tcpClient.GameId = 0; + _frontendClient.GameId = 0; - Logger.Info($"Removed ITcpClient [{_tcpClient}] from game [{Game}]"); + Logger.Info($"Removed frontend client [{_frontendClient}] from game [{Game}]"); } #endregion @@ -496,8 +495,7 @@ namespace MHServerEmu.Games.Network case ClientToGameServerMessage.NetMessageReportPlayer: // 66 case ClientToGameServerMessage.NetMessageChatBanVote: // 67 case ClientToGameServerMessage.NetMessageTryModifyCommunityMemberCircle: // 106, TODO: handle this in game - GameServiceProtocol.RouteMessage groupingManagerMessage = new(_tcpClient, typeof(ClientToGameServerMessage), message); - ServerManager.Instance.SendMessageToService(ServerType.GroupingManager, groupingManagerMessage); + RouteMessageToService(ServerType.GroupingManager, message); break; // Billing @@ -506,22 +504,26 @@ namespace MHServerEmu.Games.Network case ClientToGameServerMessage.NetMessageBuyItemFromCatalog: // 70 case ClientToGameServerMessage.NetMessageBuyGiftForOtherPlayer: // 71 case ClientToGameServerMessage.NetMessageGetGiftHistory: // 73 - GameServiceProtocol.RouteMessage billingMessage = new(_tcpClient, typeof(ClientToGameServerMessage), message); - ServerManager.Instance.SendMessageToService(ServerType.Billing, billingMessage); + RouteMessageToService(ServerType.Billing, message); break; // Leaderboards case ClientToGameServerMessage.NetMessageLeaderboardRequest: // 157 case ClientToGameServerMessage.NetMessageLeaderboardArchivedInstanceListRequest: // 158 case ClientToGameServerMessage.NetMessageLeaderboardInitializeRequest: // 159 - GameServiceProtocol.RouteMessage leaderboardMessage = new(_tcpClient, typeof(ClientToGameServerMessage), message); - ServerManager.Instance.SendMessageToService(ServerType.Leaderboard, leaderboardMessage); + RouteMessageToService(ServerType.Leaderboard, message); break; default: Logger.Warn($"ReceiveMessage(): Unhandled {(ClientToGameServerMessage)message.Id} [{message.Id}]"); break; } } + private void RouteMessageToService(ServerType serverType, in MailboxMessage mailboxMessage) + { + GameServiceProtocol.RouteMessage routeMessage = new(_frontendClient, typeof(ClientToGameServerMessage), mailboxMessage); + ServerManager.Instance.SendMessageToService(serverType, routeMessage); + } + private bool OnPlayerSystemMetrics(MailboxMessage message) // 1 { var playerSystemMetrics = message.As(); diff --git a/src/MHServerEmu.Games/Network/PlayerConnectionManager.cs b/src/MHServerEmu.Games/Network/PlayerConnectionManager.cs index 8aaf04f9..b8ffba2e 100644 --- a/src/MHServerEmu.Games/Network/PlayerConnectionManager.cs +++ b/src/MHServerEmu.Games/Network/PlayerConnectionManager.cs @@ -3,7 +3,6 @@ using Google.ProtocolBuffers; using MHServerEmu.Core.Logging; using MHServerEmu.Core.Memory; using MHServerEmu.Core.Network; -using MHServerEmu.Core.Network.Tcp; using MHServerEmu.Core.System.Time; using MHServerEmu.Games.Entities; using MHServerEmu.Games.Regions; @@ -215,32 +214,32 @@ namespace MHServerEmu.Games.Network #endregion - protected override bool AcceptAndRegisterNewClient(ITcpClient tcpClient) + protected override bool AcceptAndRegisterNewClient(IFrontendClient frontendClient) { // Make sure this client is still connected (it may not be if we are lagging hard) - if (tcpClient.IsConnected == false) - return Logger.WarnReturn(false, $"AcceptAndRegisterNewClient(): Client [{tcpClient}] is no longer connected"); + if (frontendClient.IsConnected == false) + return Logger.WarnReturn(false, $"AcceptAndRegisterNewClient(): Client [{frontendClient}] is no longer connected"); - // Construct a new PlayerConnection bound to this ITcpClient - PlayerConnection playerConnection = new(_game, tcpClient); + // Construct a new PlayerConnection bound to this IFrontendClient + PlayerConnection playerConnection = new(_game, frontendClient); // Make sure this client's account is not being used by another client pending disconnection. - // We do this after constructing the connection to keep the ITcpClient -> PlayerDbId retrieval in one place. + // We do this after constructing the connection to keep the IFrontendClient -> PlayerDbId retrieval in one place. ulong dbId = playerConnection.PlayerDbId; if (_playerDbIds.Add(dbId) == false) { - Logger.Warn($"AcceptAndRegisterNewClient(): Attempting to add client [{tcpClient}] to game [{_game}], but its account dbId 0x{dbId:X} is already in use"); - tcpClient.Disconnect(); + Logger.Warn($"AcceptAndRegisterNewClient(): Attempting to add client [{frontendClient}] to game [{_game}], but its account dbId 0x{dbId:X} is already in use"); + frontendClient.Disconnect(); return false; } // Register the client to allow it to receive messages if (RegisterNetClient(playerConnection) == false) - Logger.Error($"AcceptAndRegisterNewClient(): Failed to add client [{tcpClient}]"); + Logger.Error($"AcceptAndRegisterNewClient(): Failed to add client [{frontendClient}]"); // TODO: Replace this with a message to PlayerManager - tcpClient.GameId = _game.Id; + frontendClient.GameId = _game.Id; // Send time sync straight away for the client to be able to initialize its EventScheduler (needed for loading screens). // This will also make the client start sending pings, so it needs to be done after we assign game id. @@ -258,7 +257,7 @@ namespace MHServerEmu.Games.Network // This connection will be set as pending when we receive region availability query response - Logger.Info($"Accepted and registered client [{tcpClient}] to game [{_game}]"); + Logger.Info($"Accepted and registered client [{frontendClient}] to game [{_game}]"); return true; } diff --git a/src/MHServerEmu.Grouping/ChatHelper.cs b/src/MHServerEmu.Grouping/ChatHelper.cs index be9e7c7e..e94381f6 100644 --- a/src/MHServerEmu.Grouping/ChatHelper.cs +++ b/src/MHServerEmu.Grouping/ChatHelper.cs @@ -1,6 +1,6 @@ using Gazillion; using MHServerEmu.Core.Config; -using MHServerEmu.Core.Network.Tcp; +using MHServerEmu.Core.Network; namespace MHServerEmu.Grouping { @@ -38,7 +38,7 @@ namespace MHServerEmu.Grouping /// The in-game chat window does not handle well messages longer than 25-30 lines (~40 characters per line). /// If you need to send a long message, use SendMetagameMessages() or SendMetagameMessageSplit(). /// - public static void SendMetagameMessage(ITcpClient client, string text, bool showSender = true) + public static void SendMetagameMessage(IFrontendClient client, string text, bool showSender = true) { client.SendMessage(MuxChannel, ChatNormalMessage.CreateBuilder() .SetRoomType(ChatRoomTypes.CHAT_ROOM_TYPE_METAGAME) @@ -51,7 +51,7 @@ namespace MHServerEmu.Grouping /// /// Sends the specified collection of texts as metagame chat messages to the provided . /// - public static void SendMetagameMessages(ITcpClient client, IEnumerable texts, bool showSender = true) + public static void SendMetagameMessages(IFrontendClient client, IEnumerable texts, bool showSender = true) { foreach (string text in texts) { @@ -63,7 +63,7 @@ namespace MHServerEmu.Grouping /// /// Splits the specified text at line breaks and sends it as a collection of metagame chat messages to the provided . /// - public static void SendMetagameMessageSplit(ITcpClient client, string text, bool showSender = true) + public static void SendMetagameMessageSplit(IFrontendClient client, string text, bool showSender = true) { SendMetagameMessages(client, text.Split("\r\n", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries), showSender); } diff --git a/src/MHServerEmu.Grouping/GroupingManagerService.cs b/src/MHServerEmu.Grouping/GroupingManagerService.cs index c58fe0fe..7e43f738 100644 --- a/src/MHServerEmu.Grouping/GroupingManagerService.cs +++ b/src/MHServerEmu.Grouping/GroupingManagerService.cs @@ -2,7 +2,6 @@ using Google.ProtocolBuffers; using MHServerEmu.Core.Logging; using MHServerEmu.Core.Network; -using MHServerEmu.Core.Network.Tcp; using MHServerEmu.DatabaseAccess; using MHServerEmu.DatabaseAccess.Models; @@ -15,7 +14,7 @@ namespace MHServerEmu.Grouping private static readonly Logger Logger = LogManager.CreateLogger(); private readonly object _playerLock = new(); - private readonly Dictionary _playerDict = new(); // Store players in a name-client dictionary because tell messages are sent by player name + private readonly Dictionary _playerDict = new(); // Store players in a name-client dictionary because tell messages are sent by player name private ICommandParser _commandParser; @@ -72,7 +71,7 @@ namespace MHServerEmu.Grouping private void OnRouteMailboxMessage(in GameServiceProtocol.RouteMessage routeMailboxMessage) { - ITcpClient client = routeMailboxMessage.Client; + IFrontendClient client = routeMailboxMessage.Client; MailboxMessage message = routeMailboxMessage.Message; // Handle messages routed from games @@ -90,7 +89,7 @@ namespace MHServerEmu.Grouping #region Client Management - private bool AddClient(ITcpClient client) + private bool AddClient(IFrontendClient client) { lock (_playerLock) { @@ -108,7 +107,7 @@ namespace MHServerEmu.Grouping } } - private bool RemoveClient(ITcpClient client) + private bool RemoveClient(IFrontendClient client) { lock (_playerLock) { @@ -132,7 +131,7 @@ namespace MHServerEmu.Grouping } } - public bool TryGetPlayerByName(string playerName, out ITcpClient client) + public bool TryGetPlayerByName(string playerName, out IFrontendClient client) { return _playerDict.TryGetValue(playerName.ToLower(), out client); } @@ -141,7 +140,7 @@ namespace MHServerEmu.Grouping #region Message Handling - private bool OnChat(ITcpClient client, MailboxMessage message) + private bool OnChat(IFrontendClient client, MailboxMessage message) { var chat = message.As(); if (chat == null) return Logger.WarnReturn(false, $"OnChat(): Failed to retrieve message"); @@ -182,7 +181,7 @@ namespace MHServerEmu.Grouping return true; } - private bool OnTell(ITcpClient client, MailboxMessage message) + private bool OnTell(IFrontendClient client, MailboxMessage message) { var tell = message.As(); if (tell == null) return Logger.WarnReturn(false, $"OnTell(): Failed to retrieve message"); @@ -197,7 +196,7 @@ namespace MHServerEmu.Grouping return true; } - private bool OnTryModifyCommunityMemberCircle(ITcpClient client, MailboxMessage message) + private bool OnTryModifyCommunityMemberCircle(IFrontendClient client, MailboxMessage message) { // We are handling this in the grouping manager to avoid exposing the ChatHelper class // TODO: Remove this and handle it in game after we implemented social functionality there. diff --git a/src/MHServerEmu.Grouping/ICommandParser.cs b/src/MHServerEmu.Grouping/ICommandParser.cs index d834d636..94f9156d 100644 --- a/src/MHServerEmu.Grouping/ICommandParser.cs +++ b/src/MHServerEmu.Grouping/ICommandParser.cs @@ -1,4 +1,4 @@ -using MHServerEmu.Core.Network.Tcp; +using MHServerEmu.Core.Network; namespace MHServerEmu.Grouping { @@ -10,6 +10,6 @@ namespace MHServerEmu.Grouping /// /// Attempts to parse a command from the provided message. Returns if successful. /// - public bool TryParse(string message, ITcpClient client); + public bool TryParse(string message, IFrontendClient client); } } diff --git a/src/MHServerEmu.Leaderboards/LeaderboardService.cs b/src/MHServerEmu.Leaderboards/LeaderboardService.cs index 401d74d2..2c08ae26 100644 --- a/src/MHServerEmu.Leaderboards/LeaderboardService.cs +++ b/src/MHServerEmu.Leaderboards/LeaderboardService.cs @@ -1,7 +1,6 @@ using Gazillion; using MHServerEmu.Core.Logging; using MHServerEmu.Core.Network; -using MHServerEmu.Core.Network.Tcp; using MHServerEmu.DatabaseAccess; using MHServerEmu.Games.GameData; @@ -45,13 +44,13 @@ namespace MHServerEmu.Leaderboards private void OnRouteMailboxMessage(in GameServiceProtocol.RouteMessage routeMailboxMessage) { - ITcpClient tcpClient = routeMailboxMessage.Client; + IFrontendClient client = routeMailboxMessage.Client; MailboxMessage message = routeMailboxMessage.Message; switch ((ClientToGameServerMessage)message.Id) { - case ClientToGameServerMessage.NetMessageLeaderboardInitializeRequest: OnInitializeRequest(tcpClient, message); break; - case ClientToGameServerMessage.NetMessageLeaderboardRequest: OnRequest(tcpClient, message); break; + case ClientToGameServerMessage.NetMessageLeaderboardInitializeRequest: OnInitializeRequest(client, message); break; + case ClientToGameServerMessage.NetMessageLeaderboardRequest: OnRequest(client, message); break; default: Logger.Warn($"Handle(): Unhandled {(ClientToGameServerMessage)message.Id} [{message.Id}]"); break; } @@ -59,7 +58,7 @@ namespace MHServerEmu.Leaderboards #endregion - private bool OnInitializeRequest(ITcpClient client, MailboxMessage message) + private bool OnInitializeRequest(IFrontendClient client, MailboxMessage message) { var initializeRequest = message.As(); if (initializeRequest == null) return Logger.WarnReturn(false, $"OnInitializeRequest(): Failed to retrieve message"); @@ -76,7 +75,7 @@ namespace MHServerEmu.Leaderboards return true; } - private bool OnRequest(ITcpClient client, MailboxMessage message) + private bool OnRequest(IFrontendClient client, MailboxMessage message) { var request = message.As(); if (request == null) return Logger.WarnReturn(false, $"OnRequest(): Failed to retrieve message"); diff --git a/src/MHServerEmu.PlayerManagement/PlayerManagerService.cs b/src/MHServerEmu.PlayerManagement/PlayerManagerService.cs index 7dad6f25..939d7a1e 100644 --- a/src/MHServerEmu.PlayerManagement/PlayerManagerService.cs +++ b/src/MHServerEmu.PlayerManagement/PlayerManagerService.cs @@ -3,7 +3,6 @@ using Google.ProtocolBuffers; using MHServerEmu.Core.Config; using MHServerEmu.Core.Logging; using MHServerEmu.Core.Network; -using MHServerEmu.Core.Network.Tcp; using MHServerEmu.DatabaseAccess.Models; using MHServerEmu.Frontend; using MHServerEmu.Games; @@ -146,12 +145,12 @@ namespace MHServerEmu.PlayerManagement private void OnRouteMessage(in GameServiceProtocol.RouteMessage routeMessage) { - ITcpClient tcpClient = routeMessage.Client; + IFrontendClient client = routeMessage.Client; MailboxMessage message = routeMessage.Message; switch ((FrontendProtocolMessage)message.Id) { - case FrontendProtocolMessage.ClientCredentials: OnClientCredentials(tcpClient, message); break; + case FrontendProtocolMessage.ClientCredentials: OnClientCredentials(client, message); break; default: Logger.Warn($"Handle(): Unhandled {(ClientToGameServerMessage)message.Id} [{message.Id}]"); break; } @@ -421,11 +420,13 @@ namespace MHServerEmu.PlayerManagement /// /// Handles . /// - private bool OnClientCredentials(ITcpClient client, MailboxMessage message) + private bool OnClientCredentials(IFrontendClient client, MailboxMessage message) { var clientCredentials = message.As(); if (clientCredentials == null) return Logger.WarnReturn(false, "OnClientCredentials(): clientCredentials == null"); + FrontendClient frontendClient = (FrontendClient)client; + if (Config.SimulateQueue) { Logger.Debug("Responding with LoginQueueStatus message"); @@ -437,9 +438,9 @@ namespace MHServerEmu.PlayerManagement return false; } - if (_sessionManager.VerifyClientCredentials((FrontendClient)client, clientCredentials) == false) + if (_sessionManager.VerifyClientCredentials(frontendClient, clientCredentials) == false) { - Logger.Warn($"OnClientCredentials(): Failed to verify client credentials, disconnecting client on {client.Connection}"); + Logger.Warn($"OnClientCredentials(): Failed to verify client credentials, disconnecting client on {frontendClient.Connection}"); client.Disconnect(); return false; } @@ -457,7 +458,7 @@ namespace MHServerEmu.PlayerManagement /// /// Handles . /// - private bool OnReadyForGameJoin(ITcpClient client, MessageBuffer messageBuffer) + private bool OnReadyForGameJoin(IFrontendClient client, MessageBuffer messageBuffer) { // There is a client-side bug with NetMessageReadyForGameJoin that requires special handling, see DeserializeReadyForGameJoin() for more info. var readyForGameJoin = messageBuffer.DeserializeReadyForGameJoin(); diff --git a/src/MHServerEmu/Commands/CommandParser.cs b/src/MHServerEmu/Commands/CommandParser.cs index 7c7e9973..a3db258c 100644 --- a/src/MHServerEmu/Commands/CommandParser.cs +++ b/src/MHServerEmu/Commands/CommandParser.cs @@ -1,4 +1,4 @@ -using MHServerEmu.Core.Network.Tcp; +using MHServerEmu.Core.Network; using MHServerEmu.Frontend; using MHServerEmu.Grouping; @@ -9,7 +9,7 @@ namespace MHServerEmu.Commands /// public class CommandParser : ICommandParser { - public bool TryParse(string message, ITcpClient client) + public bool TryParse(string message, IFrontendClient client) { return CommandManager.Instance.TryParse(message, (FrontendClient)client); } diff --git a/src/MHServerEmu/Commands/FrontendClientChatOutput.cs b/src/MHServerEmu/Commands/FrontendClientChatOutput.cs index 84a0cefa..fe88fbf3 100644 --- a/src/MHServerEmu/Commands/FrontendClientChatOutput.cs +++ b/src/MHServerEmu/Commands/FrontendClientChatOutput.cs @@ -1,19 +1,18 @@ -using MHServerEmu.Core.Network.Tcp; -using MHServerEmu.Frontend; +using MHServerEmu.Core.Network; using MHServerEmu.Grouping; namespace MHServerEmu.Commands { /// - /// Provides output to a chat window of a . + /// Provides output to a chat window of a . /// public class FrontendClientChatOutput : IClientOutput { // TODO: Potentially move this to MHServerEmu.Grouping. - public void Output(string output, ITcpClient client) + public void Output(string output, IFrontendClient client) { - ChatHelper.SendMetagameMessage((FrontendClient)client, output); + ChatHelper.SendMetagameMessage(client, output); } } } diff --git a/src/MHServerEmu/Commands/IClientOutput.cs b/src/MHServerEmu/Commands/IClientOutput.cs index dd1a83b5..82f53ee9 100644 --- a/src/MHServerEmu/Commands/IClientOutput.cs +++ b/src/MHServerEmu/Commands/IClientOutput.cs @@ -1,15 +1,15 @@ -using MHServerEmu.Core.Network.Tcp; +using MHServerEmu.Core.Network; namespace MHServerEmu.Commands { /// - /// Exposes output for an . + /// Exposes output for an . /// public interface IClientOutput { /// - /// Outputs the provided to the specified . + /// Outputs the provided to the specified . /// - public void Output(string output, ITcpClient client); + public void Output(string output, IFrontendClient client); } } diff --git a/src/MHServerEmu/Commands/Implementations/ClientCommands.cs b/src/MHServerEmu/Commands/Implementations/ClientCommands.cs index b5ef45e0..4d47cd2a 100644 --- a/src/MHServerEmu/Commands/Implementations/ClientCommands.cs +++ b/src/MHServerEmu/Commands/Implementations/ClientCommands.cs @@ -3,7 +3,6 @@ using Gazillion; using MHServerEmu.Commands.Attributes; using MHServerEmu.Core.Config; using MHServerEmu.Core.Network; -using MHServerEmu.Core.Network.Tcp; using MHServerEmu.DatabaseAccess.Models; using MHServerEmu.Frontend; using MHServerEmu.Grouping; @@ -43,7 +42,7 @@ namespace MHServerEmu.Commands.Implementations if (groupingManager == null) return "Failed to connect to the grouping manager."; - if (groupingManager.TryGetPlayerByName(@params[0], out ITcpClient target) == false) + if (groupingManager.TryGetPlayerByName(@params[0], out IFrontendClient target) == false) return $"Player {@params[0]} not found."; target.Disconnect();