Skip to content

Commit 88cefad

Browse files
committed
Clean up player manager message routing
1 parent 883f383 commit 88cefad

File tree

4 files changed

+110
-87
lines changed

4 files changed

+110
-87
lines changed

src/MHServerEmu.Games/Network/PlayerConnection.cs

+46-11
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using Google.ProtocolBuffers;
33
using MHServerEmu.Core.Logging;
44
using MHServerEmu.Core.Network;
5+
using MHServerEmu.Core.System;
56
using MHServerEmu.Core.VectorMath;
67
using MHServerEmu.DatabaseAccess.Models;
78
using MHServerEmu.Frontend;
@@ -203,11 +204,6 @@ public void ReceiveMessage(GameMessage message)
203204
OnAdminCommand(adminCommand);
204205
break;
205206

206-
case ClientToGameServerMessage.NetMessageChangeCameraSettings:
207-
if (message.TryDeserialize<NetMessageChangeCameraSettings>(out var cameraSettings))
208-
OnChangeCameraSettings(cameraSettings);
209-
break;
210-
211207
case ClientToGameServerMessage.NetMessageUseInteractableObject:
212208
if (message.TryDeserialize<NetMessageUseInteractableObject>(out var useInteractableObject))
213209
OnUseInteractableObject(useInteractableObject);
@@ -261,6 +257,10 @@ public void ReceiveMessage(GameMessage message)
261257
OnAbilitySwapInAbilityBar(swapInAbilityBar);
262258
break;
263259

260+
case ClientToGameServerMessage.NetMessageGracefulDisconnect:
261+
OnGracefulDisconnect();
262+
break;
263+
264264
case ClientToGameServerMessage.NetMessageSetPlayerGameplayOptions:
265265
if (message.TryDeserialize<NetMessageSetPlayerGameplayOptions>(out var setPlayerGameplayOptions))
266266
OnSetPlayerGameplayOptions(setPlayerGameplayOptions);
@@ -281,17 +281,42 @@ public void ReceiveMessage(GameMessage message)
281281
OnOmegaBonusAllocationCommit(omegaBonusAllocationCommit);
282282
break;
283283

284+
case ClientToGameServerMessage.NetMessageChangeCameraSettings:
285+
if (message.TryDeserialize<NetMessageChangeCameraSettings>(out var cameraSettings))
286+
OnChangeCameraSettings(cameraSettings);
287+
break;
288+
289+
// Grouping Manager
290+
case ClientToGameServerMessage.NetMessageChat:
291+
case ClientToGameServerMessage.NetMessageTell:
292+
case ClientToGameServerMessage.NetMessageReportPlayer:
293+
case ClientToGameServerMessage.NetMessageChatBanVote:
294+
ServerManager.Instance.RouteMessage(_frontendClient, message, ServerType.GroupingManager);
295+
break;
296+
297+
// Billing
298+
case ClientToGameServerMessage.NetMessageGetCatalog:
299+
case ClientToGameServerMessage.NetMessageGetCurrencyBalance:
300+
case ClientToGameServerMessage.NetMessageBuyItemFromCatalog:
301+
case ClientToGameServerMessage.NetMessageBuyGiftForOtherPlayer:
302+
case ClientToGameServerMessage.NetMessagePurchaseUnlock:
303+
case ClientToGameServerMessage.NetMessageGetGiftHistory:
304+
ServerManager.Instance.RouteMessage(_frontendClient, message, ServerType.Billing);
305+
break;
306+
307+
// Leaderboards
308+
case ClientToGameServerMessage.NetMessageLeaderboardRequest:
309+
case ClientToGameServerMessage.NetMessageLeaderboardArchivedInstanceListRequest:
310+
case ClientToGameServerMessage.NetMessageLeaderboardInitializeRequest:
311+
ServerManager.Instance.RouteMessage(_frontendClient, message, ServerType.Leaderboard);
312+
break;
313+
284314
default:
285-
Logger.Warn($"HandleQueuedMessage(): Unhandled message [{message.Id}] {(ClientToGameServerMessage)message.Id}");
315+
Logger.Warn($"ReceiveMessage(): Unhandled {(ClientToGameServerMessage)message.Id} [{message.Id}]");
286316
break;
287317
}
288318
}
289319

290-
private void OnChangeCameraSettings(NetMessageChangeCameraSettings cameraSettings)
291-
{
292-
AOI.InitPlayerView((PrototypeId)cameraSettings.CameraSettings);
293-
}
294-
295320
private void OnUpdateAvatarState(NetMessageUpdateAvatarState updateAvatarState)
296321
{
297322
UpdateAvatarStateArchive avatarState = new(updateAvatarState.ArchiveData);
@@ -517,6 +542,11 @@ private void OnAbilitySwapInAbilityBar(NetMessageAbilitySwapInAbilityBar swapInA
517542
abilityKeyMapping.SetAbilityInAbilitySlot(prototypeA, slotB);
518543
}
519544

545+
private void OnGracefulDisconnect()
546+
{
547+
SendMessage(NetMessageGracefulDisconnectAck.DefaultInstance);
548+
}
549+
520550
private void OnSetPlayerGameplayOptions(NetMessageSetPlayerGameplayOptions setPlayerGameplayOptions)
521551
{
522552
Logger.Info($"Received SetPlayerGameplayOptions message");
@@ -543,6 +573,11 @@ private void OnOmegaBonusAllocationCommit(NetMessageOmegaBonusAllocationCommit o
543573
Logger.Debug(omegaBonusAllocationCommit.ToString());
544574
}
545575

576+
private void OnChangeCameraSettings(NetMessageChangeCameraSettings cameraSettings)
577+
{
578+
AOI.InitPlayerView((PrototypeId)cameraSettings.CameraSettings);
579+
}
580+
546581
#endregion
547582
}
548583
}

src/MHServerEmu.PlayerManagement/ClientSession.cs

-2
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ public enum ClientDownloader
1919
/// </summary>
2020
public class ClientSession : IFrontendSession
2121
{
22-
private static readonly Logger Logger = LogManager.CreateLogger();
23-
2422
public ulong Id { get; set; }
2523
public DBAccount Account { get; }
2624

src/MHServerEmu.PlayerManagement/Configs/PlayerManagerConfig.cs

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
namespace MHServerEmu.PlayerManagement.Configs
44
{
5+
/// <summary>
6+
/// Contains configuration for the <see cref="PlayerManagerService"/>.
7+
/// </summary>
58
public class PlayerManagerConfig : ConfigContainer
69
{
710
public bool BypassAuth { get; private set; } = false;

src/MHServerEmu.PlayerManagement/PlayerManagerService.cs

+61-74
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313

1414
namespace MHServerEmu.PlayerManagement
1515
{
16+
/// <summary>
17+
/// An <see cref="IGameService"/> that manages connected players and routes messages to relevant <see cref="Game"/> instances.
18+
/// </summary>
1619
public class PlayerManagerService : IGameService, IFrontendService
1720
{
1821
private const ushort MuxChannel = 1; // All messages come to and from PlayerManager over mux channel 1
@@ -29,6 +32,9 @@ public class PlayerManagerService : IGameService, IFrontendService
2932

3033
public PlayerManagerConfig Config { get; }
3134

35+
/// <summary>
36+
/// Constructs a new <see cref="PlayerManagerService"/> instance.
37+
/// </summary>
3238
public PlayerManagerService()
3339
{
3440
_sessionManager = new(this);
@@ -59,10 +65,9 @@ public void Handle(ITcpClient tcpClient, GameMessage message)
5965
message.DateTimeReceived = Clock.UnixTime;
6066
}
6167

68+
// Self-handle or route messages
6269
switch ((ClientToGameServerMessage)message.Id)
6370
{
64-
// Self-handled messages
65-
6671
case ClientToGameServerMessage.NetMessageReadyForGameJoin:
6772
// NetMessageReadyForGameJoin contains a bug where wipesDataIfMismatchedInDb is marked as required but the client
6873
// doesn't include it. To avoid an exception we build a partial message from the data we receive.
@@ -73,9 +78,8 @@ public void Handle(ITcpClient tcpClient, GameMessage message)
7378
}
7479
catch
7580
{
76-
Logger.Error("Failed to deserialize NetMessageReadyForGameJoin");
81+
Logger.Error("Handle(): Failed to deserialize NetMessageReadyForGameJoin");
7782
}
78-
7983
break;
8084

8185
case ClientToGameServerMessage.NetMessageSyncTimeRequest:
@@ -93,68 +97,17 @@ public void Handle(ITcpClient tcpClient, GameMessage message)
9397
OnFps(client, fps);
9498
break;
9599

96-
case ClientToGameServerMessage.NetMessageGracefulDisconnect:
97-
OnGracefulDisconnect(client);
98-
break;
99-
100-
// Routed messages
101-
102-
// Game
103-
case ClientToGameServerMessage.NetMessageUpdateAvatarState:
104-
case ClientToGameServerMessage.NetMessageCellLoaded:
105-
case ClientToGameServerMessage.NetMessageAdminCommand:
106-
case ClientToGameServerMessage.NetMessageChangeCameraSettings:
107-
case ClientToGameServerMessage.NetMessagePerformPreInteractPower:
108-
case ClientToGameServerMessage.NetMessageTryActivatePower:
109-
case ClientToGameServerMessage.NetMessagePowerRelease:
110-
case ClientToGameServerMessage.NetMessageTryCancelPower:
111-
case ClientToGameServerMessage.NetMessageTryCancelActivePower:
112-
case ClientToGameServerMessage.NetMessageContinuousPowerUpdateToServer:
113-
case ClientToGameServerMessage.NetMessageTryInventoryMove:
114-
case ClientToGameServerMessage.NetMessageThrowInteraction:
115-
case ClientToGameServerMessage.NetMessageUseInteractableObject:
116-
case ClientToGameServerMessage.NetMessageUseWaypoint:
117-
case ClientToGameServerMessage.NetMessageSwitchAvatar:
118-
case ClientToGameServerMessage.NetMessageAbilitySlotToAbilityBar:
119-
case ClientToGameServerMessage.NetMessageAbilityUnslotFromAbilityBar:
120-
case ClientToGameServerMessage.NetMessageAbilitySwapInAbilityBar:
121-
case ClientToGameServerMessage.NetMessageSetPlayerGameplayOptions:
122-
case ClientToGameServerMessage.NetMessageRequestInterestInInventory:
123-
case ClientToGameServerMessage.NetMessageRequestInterestInAvatarEquipment:
124-
case ClientToGameServerMessage.NetMessageSelectOmegaBonus: // This should be within NetMessageOmegaBonusAllocationCommit only in theory
125-
case ClientToGameServerMessage.NetMessageOmegaBonusAllocationCommit:
126-
case ClientToGameServerMessage.NetMessageRespecOmegaBonus:
127-
case ClientToGameServerMessage.NetMessageAssignStolenPower:
128-
GetGameByPlayer(client).Handle(client, message);
129-
break;
130-
131-
// Grouping Manager
132-
case ClientToGameServerMessage.NetMessageChat:
133-
case ClientToGameServerMessage.NetMessageTell:
134-
case ClientToGameServerMessage.NetMessageReportPlayer:
135-
case ClientToGameServerMessage.NetMessageChatBanVote:
136-
ServerManager.Instance.RouteMessage(tcpClient, message, ServerType.GroupingManager);
137-
break;
138-
139-
// Billing
140-
case ClientToGameServerMessage.NetMessageGetCatalog:
141-
case ClientToGameServerMessage.NetMessageGetCurrencyBalance:
142-
case ClientToGameServerMessage.NetMessageBuyItemFromCatalog:
143-
case ClientToGameServerMessage.NetMessageBuyGiftForOtherPlayer:
144-
case ClientToGameServerMessage.NetMessagePurchaseUnlock:
145-
case ClientToGameServerMessage.NetMessageGetGiftHistory:
146-
ServerManager.Instance.RouteMessage(tcpClient, message, ServerType.Billing);
147-
break;
100+
default:
101+
// Route the rest of messages to the game the player is currently in
102+
Game game = GetGameByPlayer(client);
148103

149-
// Leaderboards
150-
case ClientToGameServerMessage.NetMessageLeaderboardRequest:
151-
case ClientToGameServerMessage.NetMessageLeaderboardArchivedInstanceListRequest:
152-
case ClientToGameServerMessage.NetMessageLeaderboardInitializeRequest:
153-
ServerManager.Instance.RouteMessage(tcpClient, message, ServerType.Leaderboard);
154-
break;
104+
if (game == null)
105+
{
106+
Logger.Warn($"Handle(): Cannot route {(ClientToGameServerMessage)message.Id}, the player {client.Session.Account} is not in a game");
107+
return;
108+
}
155109

156-
default:
157-
Logger.Warn($"Handle(): Unhandled message [{message.Id}] {(ClientToGameServerMessage)message.Id}");
110+
game.Handle(client, message);
158111
break;
159112
}
160113
}
@@ -224,7 +177,29 @@ public bool RemoveFrontendClient(FrontendClient client)
224177

225178
#region Player Management
226179

227-
public void BroadcastMessage(GameMessage message)
180+
/// <summary>
181+
/// Retrieves the <see cref="ClientSession"/> for the specified session id. Returns <see langword="true"/> if successful.
182+
/// </summary>
183+
public bool TryGetSession(ulong sessionId, out ClientSession session) => _sessionManager.TryGetSession(sessionId, out session);
184+
185+
/// <summary>
186+
/// Retrieves the <see cref="FrontendClient"/> for the specified session id. Returns <see langword="true"/> if successful.
187+
/// </summary>
188+
public bool TryGetClient(ulong sessionId, out FrontendClient client) => _sessionManager.TryGetClient(sessionId, out client);
189+
190+
/// <summary>
191+
/// Retrieves the <see cref="Game"/> instance that the provided <see cref="FrontendClient"/> is in. Returns <see langword="null"/> if not found.
192+
/// </summary>
193+
public Game GetGameByPlayer(FrontendClient client)
194+
{
195+
// TODO: Keep track of this inside PlayerManagerService rather than relying on a client property
196+
return _gameManager.GetGameById(client.GameId);
197+
}
198+
199+
/// <summary>
200+
/// Sends an <see cref="IMessage"/> to all connected <see cref="FrontendClient"/> instances.
201+
/// </summary>
202+
public void BroadcastMessage(IMessage message)
228203
{
229204
lock (_playerLock)
230205
{
@@ -233,14 +208,13 @@ public void BroadcastMessage(GameMessage message)
233208
}
234209
}
235210

236-
public bool TryGetSession(ulong sessionId, out ClientSession session) => _sessionManager.TryGetSession(sessionId, out session);
237-
public bool TryGetClient(ulong sessionId, out FrontendClient client) => _sessionManager.TryGetClient(sessionId, out client);
238-
public Game GetGameByPlayer(FrontendClient client) => _gameManager.GetGameById(client.GameId);
239-
240211
#endregion
241212

242213
#region Message Handling
243214

215+
/// <summary>
216+
/// Handles <see cref="LoginDataPB"/>.
217+
/// </summary>
244218
public AuthStatusCode OnLoginDataPB(LoginDataPB loginDataPB, out AuthTicket authTicket)
245219
{
246220
authTicket = AuthTicket.DefaultInstance;
@@ -265,6 +239,9 @@ public AuthStatusCode OnLoginDataPB(LoginDataPB loginDataPB, out AuthTicket auth
265239
return statusCode;
266240
}
267241

242+
/// <summary>
243+
/// Handles <see cref="InitialClientHandshake"/>.
244+
/// </summary>
268245
private void OnInitialClientHandshake(FrontendClient client, InitialClientHandshake handshake)
269246
{
270247
client.FinishedPlayerManagerHandshake = true;
@@ -277,6 +254,9 @@ private void OnInitialClientHandshake(FrontendClient client, InitialClientHandsh
277254
// NetMessageQueryIsRegionAvailable regionPrototype: 9833127629697912670 should go in the same packet as AchievementDatabaseDump
278255
}
279256

257+
/// <summary>
258+
/// Handles <see cref="ClientCredentials"/>.
259+
/// </summary>
280260
private void OnClientCredentials(FrontendClient client, ClientCredentials credentials)
281261
{
282262
Logger.Info($"Received ClientCredentials");
@@ -307,6 +287,9 @@ private void OnClientCredentials(FrontendClient client, ClientCredentials creden
307287
}
308288
}
309289

290+
/// <summary>
291+
/// Handles <see cref="NetMessageReadyForGameJoin"/>.
292+
/// </summary>
310293
private void OnReadyForGameJoin(FrontendClient client, NetMessageReadyForGameJoin readyForGameJoin)
311294
{
312295
Logger.Info($"Received NetMessageReadyForGameJoin from {client.Session.Account}");
@@ -323,6 +306,9 @@ private void OnReadyForGameJoin(FrontendClient client, NetMessageReadyForGameJoi
323306
.Build());
324307
}
325308

309+
/// <summary>
310+
/// Handles <see cref="NetMessageSyncTimeRequest"/>.
311+
/// </summary>
326312
private void OnSyncTimeRequest(FrontendClient client, NetMessageSyncTimeRequest request, TimeSpan gameTimeReceived, TimeSpan dateTimeReceived)
327313
{
328314
//Logger.Debug($"NetMessageSyncTimeRequest:\n{request}");
@@ -344,6 +330,9 @@ private void OnSyncTimeRequest(FrontendClient client, NetMessageSyncTimeRequest
344330
client.SendMessage(MuxChannel, reply);
345331
}
346332

333+
/// <summary>
334+
/// Handles <see cref="NetMessagePing"/>.
335+
/// </summary>
347336
private void OnPing(FrontendClient client, NetMessagePing ping, TimeSpan gameTimeReceived)
348337
{
349338
//Logger.Debug($"NetMessagePing:\n{ping}");
@@ -364,16 +353,14 @@ private void OnPing(FrontendClient client, NetMessagePing ping, TimeSpan gameTim
364353
client.SendMessage(MuxChannel, response);
365354
}
366355

356+
/// <summary>
357+
/// Handles <see cref="NetMessageFPS"/>.
358+
/// </summary>
367359
private void OnFps(FrontendClient client, NetMessageFPS fps)
368360
{
369361
//Logger.Debug($"NetMessageFPS:\n{fps}");
370362
}
371363

372-
private void OnGracefulDisconnect(FrontendClient client)
373-
{
374-
client.SendMessage(MuxChannel, NetMessageGracefulDisconnectAck.DefaultInstance);
375-
}
376-
377364
#endregion
378365
}
379366
}

0 commit comments

Comments
 (0)