13
13
14
14
namespace MHServerEmu . PlayerManagement
15
15
{
16
+ /// <summary>
17
+ /// An <see cref="IGameService"/> that manages connected players and routes messages to relevant <see cref="Game"/> instances.
18
+ /// </summary>
16
19
public class PlayerManagerService : IGameService , IFrontendService
17
20
{
18
21
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
29
32
30
33
public PlayerManagerConfig Config { get ; }
31
34
35
+ /// <summary>
36
+ /// Constructs a new <see cref="PlayerManagerService"/> instance.
37
+ /// </summary>
32
38
public PlayerManagerService ( )
33
39
{
34
40
_sessionManager = new ( this ) ;
@@ -59,10 +65,9 @@ public void Handle(ITcpClient tcpClient, GameMessage message)
59
65
message . DateTimeReceived = Clock . UnixTime ;
60
66
}
61
67
68
+ // Self-handle or route messages
62
69
switch ( ( ClientToGameServerMessage ) message . Id )
63
70
{
64
- // Self-handled messages
65
-
66
71
case ClientToGameServerMessage . NetMessageReadyForGameJoin :
67
72
// NetMessageReadyForGameJoin contains a bug where wipesDataIfMismatchedInDb is marked as required but the client
68
73
// 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)
73
78
}
74
79
catch
75
80
{
76
- Logger . Error ( "Failed to deserialize NetMessageReadyForGameJoin" ) ;
81
+ Logger . Error ( "Handle(): Failed to deserialize NetMessageReadyForGameJoin" ) ;
77
82
}
78
-
79
83
break ;
80
84
81
85
case ClientToGameServerMessage . NetMessageSyncTimeRequest :
@@ -93,68 +97,17 @@ public void Handle(ITcpClient tcpClient, GameMessage message)
93
97
OnFps ( client , fps ) ;
94
98
break ;
95
99
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 ) ;
148
103
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
+ }
155
109
156
- default :
157
- Logger . Warn ( $ "Handle(): Unhandled message [{ message . Id } ] { ( ClientToGameServerMessage ) message . Id } ") ;
110
+ game . Handle ( client , message ) ;
158
111
break ;
159
112
}
160
113
}
@@ -224,7 +177,29 @@ public bool RemoveFrontendClient(FrontendClient client)
224
177
225
178
#region Player Management
226
179
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 )
228
203
{
229
204
lock ( _playerLock )
230
205
{
@@ -233,14 +208,13 @@ public void BroadcastMessage(GameMessage message)
233
208
}
234
209
}
235
210
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
-
240
211
#endregion
241
212
242
213
#region Message Handling
243
214
215
+ /// <summary>
216
+ /// Handles <see cref="LoginDataPB"/>.
217
+ /// </summary>
244
218
public AuthStatusCode OnLoginDataPB ( LoginDataPB loginDataPB , out AuthTicket authTicket )
245
219
{
246
220
authTicket = AuthTicket . DefaultInstance ;
@@ -265,6 +239,9 @@ public AuthStatusCode OnLoginDataPB(LoginDataPB loginDataPB, out AuthTicket auth
265
239
return statusCode ;
266
240
}
267
241
242
+ /// <summary>
243
+ /// Handles <see cref="InitialClientHandshake"/>.
244
+ /// </summary>
268
245
private void OnInitialClientHandshake ( FrontendClient client , InitialClientHandshake handshake )
269
246
{
270
247
client . FinishedPlayerManagerHandshake = true ;
@@ -277,6 +254,9 @@ private void OnInitialClientHandshake(FrontendClient client, InitialClientHandsh
277
254
// NetMessageQueryIsRegionAvailable regionPrototype: 9833127629697912670 should go in the same packet as AchievementDatabaseDump
278
255
}
279
256
257
+ /// <summary>
258
+ /// Handles <see cref="ClientCredentials"/>.
259
+ /// </summary>
280
260
private void OnClientCredentials ( FrontendClient client , ClientCredentials credentials )
281
261
{
282
262
Logger . Info ( $ "Received ClientCredentials") ;
@@ -307,6 +287,9 @@ private void OnClientCredentials(FrontendClient client, ClientCredentials creden
307
287
}
308
288
}
309
289
290
+ /// <summary>
291
+ /// Handles <see cref="NetMessageReadyForGameJoin"/>.
292
+ /// </summary>
310
293
private void OnReadyForGameJoin ( FrontendClient client , NetMessageReadyForGameJoin readyForGameJoin )
311
294
{
312
295
Logger . Info ( $ "Received NetMessageReadyForGameJoin from { client . Session . Account } ") ;
@@ -323,6 +306,9 @@ private void OnReadyForGameJoin(FrontendClient client, NetMessageReadyForGameJoi
323
306
. Build ( ) ) ;
324
307
}
325
308
309
+ /// <summary>
310
+ /// Handles <see cref="NetMessageSyncTimeRequest"/>.
311
+ /// </summary>
326
312
private void OnSyncTimeRequest ( FrontendClient client , NetMessageSyncTimeRequest request , TimeSpan gameTimeReceived , TimeSpan dateTimeReceived )
327
313
{
328
314
//Logger.Debug($"NetMessageSyncTimeRequest:\n{request}");
@@ -344,6 +330,9 @@ private void OnSyncTimeRequest(FrontendClient client, NetMessageSyncTimeRequest
344
330
client . SendMessage ( MuxChannel , reply ) ;
345
331
}
346
332
333
+ /// <summary>
334
+ /// Handles <see cref="NetMessagePing"/>.
335
+ /// </summary>
347
336
private void OnPing ( FrontendClient client , NetMessagePing ping , TimeSpan gameTimeReceived )
348
337
{
349
338
//Logger.Debug($"NetMessagePing:\n{ping}");
@@ -364,16 +353,14 @@ private void OnPing(FrontendClient client, NetMessagePing ping, TimeSpan gameTim
364
353
client . SendMessage ( MuxChannel , response ) ;
365
354
}
366
355
356
+ /// <summary>
357
+ /// Handles <see cref="NetMessageFPS"/>.
358
+ /// </summary>
367
359
private void OnFps ( FrontendClient client , NetMessageFPS fps )
368
360
{
369
361
//Logger.Debug($"NetMessageFPS:\n{fps}");
370
362
}
371
363
372
- private void OnGracefulDisconnect ( FrontendClient client )
373
- {
374
- client . SendMessage ( MuxChannel , NetMessageGracefulDisconnectAck . DefaultInstance ) ;
375
- }
376
-
377
364
#endregion
378
365
}
379
366
}
0 commit comments