@@ -41,15 +41,8 @@ public class LoginServer {
41
41
42
42
private static final Logger log = LoggerFactory .getLogger (LoginServer .class );
43
43
44
- /**
45
- * Map<accountId,Connection> for waiting request. This request is send to LoginServer and GameServer is waiting for response.
46
- */
47
- private Map <Integer , AionConnection > loginRequests = new ConcurrentHashMap <>();
48
-
49
- /**
50
- * Map<accountId,Connection> for all logged in accounts.
51
- */
52
- private Map <Integer , AionConnection > loggedInAccounts = new ConcurrentHashMap <>();
44
+ private final Map <Integer , LoginRequest > loginRequests = new ConcurrentHashMap <>();
45
+ private final Map <Integer , AionConnection > loggedInAccounts = new ConcurrentHashMap <>();
53
46
private LoginServerConnection lsCon = null ;
54
47
private NioServer nioServer = null ;
55
48
private int gameServerCount = 1 ;
@@ -98,8 +91,8 @@ public void disconnect() {
98
91
lsCon .close ();
99
92
lsCon = null ;
100
93
}
101
- for (AionConnection client : loginRequests .values ())
102
- client . close (/* closePacket */ ); // TODO! some error packet!
94
+ for (LoginRequest loginRequest : loginRequests .values ())
95
+ loginRequest . connection . close ();
103
96
loginRequests .clear ();
104
97
}
105
98
@@ -119,13 +112,13 @@ public boolean isUp() {
119
112
/**
120
113
* Notify that client is disconnected - we must clear waiting request to LoginServer if any to prevent leaks. Also notify LoginServer that this
121
114
* account is no longer on GameServer side.
122
- *
123
- * @param accountId
124
115
*/
125
- public void aionClientDisconnected (int accountId ) {
126
- loginRequests .remove (accountId );
127
- loggedInAccounts .remove (accountId );
128
- sendPacket (new SM_ACCOUNT_DISCONNECTED (accountId ));
116
+ public void onDisconnect (AionConnection connection ) {
117
+ loginRequests .values ().removeIf (r -> r .connection == connection );
118
+ if (connection .getAccount () != null ) {
119
+ loggedInAccounts .remove (connection .getAccount ().getId ());
120
+ sendPacket (new SM_ACCOUNT_DISCONNECTED (connection .getAccount ().getId ()));
121
+ }
129
122
}
130
123
131
124
public void setGameServerCount (int gameServerCount ) {
@@ -136,18 +129,16 @@ public int getGameServerCount() {
136
129
return gameServerCount ;
137
130
}
138
131
132
+ public void registerLoginRequest (int accountId , AionConnection client , int loginOk , int playOk1 , int playOk2 ) {
133
+ loginRequests .putIfAbsent (accountId , new LoginRequest (client , new SM_ACCOUNT_AUTH (accountId , loginOk , playOk1 , playOk2 )));
134
+ }
135
+
139
136
/**
140
137
* Starts authentication procedure of this client - LoginServer will send response with information about account name if authentication is ok.
141
- *
142
- * @param accountId
143
- * @param client
144
- * @param loginOk
145
- * @param playOk1
146
- * @param playOk2
147
138
*/
148
- public void requestAuthenticationOfClient ( int accountId , AionConnection client , int loginOk , int playOk1 , int playOk2 ) {
149
- if (isUp () && loginRequests . putIfAbsent ( accountId , client ) == null )
150
- lsCon . sendPacket ( new SM_ACCOUNT_AUTH ( accountId , loginOk , playOk1 , playOk2 ));
139
+ public void authenticateClient ( AionConnection client ) {
140
+ if (isUp ())
141
+ loginRequests . values (). stream (). filter ( r -> r . connection == client ). findAny (). ifPresent ( r -> lsCon . sendPacket ( r . lsAuthResponse ));
151
142
else
152
143
client .close (new SM_L2AUTH_LOGIN_CHECK (false , null )); // disconnect this client since authentication will not happen
153
144
}
@@ -157,10 +148,11 @@ public void requestAuthenticationOfClient(int accountId, AionConnection client,
157
148
*/
158
149
public void accountAuthenticationResponse (int accountId , String accountName , boolean result , long creationDate , AccountTime accountTime ,
159
150
byte accessLevel , byte membership , long toll , String allowedHddSerial ) {
160
- AionConnection client = loginRequests .remove (accountId );
161
- if (client == null )
151
+ LoginRequest loginRequest = loginRequests .remove (accountId );
152
+ if (loginRequest == null )
162
153
return ;
163
154
155
+ AionConnection client = loginRequest .connection ;
164
156
if (!result || !validateMacAndHddSerial (client , allowedHddSerial )) {
165
157
client .close (new SM_L2AUTH_LOGIN_CHECK (false , accountName )); // LS sends no accName when result is false
166
158
sendPacket (new SM_ACCOUNT_DISCONNECTED (accountId )); // disconnect manually from login server because account isn't attached to connection yet
@@ -181,10 +173,7 @@ public void accountAuthenticationResponse(int accountId, String accountName, boo
181
173
}
182
174
183
175
private boolean validateMacAndHddSerial (AionConnection client , String allowedHddSerial ) {
184
- if (client .getMacAddress () == null || client .getHddSerial () == null ) {
185
- log .warn (client + " did not send CM_MAC_ADDRESS during login (modified client or hack)" );
186
- return false ;
187
- } else if (!client .getMacAddress ().matches ("^([0-9A-F]{2}-){5}[0-9A-F]{2}$" )) {
176
+ if (!client .getMacAddress ().matches ("^([0-9A-F]{2}-){5}[0-9A-F]{2}$" )) {
188
177
log .warn (client + " sent an invalid MAC address (modified client or hack): " + client .getMacAddress ());
189
178
return false ;
190
179
} else if (BannedMacManager .getInstance ().isBanned (client .getMacAddress ())) {
@@ -214,12 +203,9 @@ private void kickOnlineCharacters(Account account) {
214
203
215
204
/**
216
205
* Starts reconnection to LoginServer procedure. LoginServer in response will send reconnection key.
217
- *
218
- * @param accountId
219
- * @param client
220
206
*/
221
207
public void requestAuthReconnection (int accountId , AionConnection client ) {
222
- if (isUp () && loggedInAccounts . containsKey ( accountId ) && loginRequests . putIfAbsent (accountId , client ) == null )
208
+ if (isUp () && client . equals ( loggedInAccounts . get (accountId )) )
223
209
lsCon .sendPacket (new SM_ACCOUNT_RECONNECT_KEY (client .getAccount ().getId ()));
224
210
else
225
211
client .close (/* closePacket */ );
@@ -228,12 +214,9 @@ public void requestAuthReconnection(int accountId, AionConnection client) {
228
214
/**
229
215
* This method is called by CM_ACCOUNT_RECONNECT_KEY LoginServer packets to give GameServer reconnection key for client that was requesting
230
216
* reconnection.
231
- *
232
- * @param accountId
233
- * @param reconnectKey
234
217
*/
235
218
public void authReconnectionResponse (int accountId , int reconnectKey ) {
236
- AionConnection client = loginRequests . remove (accountId );
219
+ AionConnection client = loggedInAccounts . get (accountId );
237
220
if (client == null )
238
221
return ;
239
222
client .close (new SM_RECONNECT_KEY (reconnectKey ));
@@ -287,4 +270,6 @@ private static class SingletonHolder {
287
270
288
271
protected static final LoginServer instance = new LoginServer ();
289
272
}
273
+
274
+ private record LoginRequest (AionConnection connection , SM_ACCOUNT_AUTH lsAuthResponse ) {}
290
275
}
0 commit comments