35
35
36
36
using boost::asio::ip::tcp;
37
37
38
- enum eAuthCmd
38
+ enum eAuthCmd : uint8
39
39
{
40
40
AUTH_LOGON_CHALLENGE = 0x00 ,
41
41
AUTH_LOGON_PROOF = 0x01 ,
@@ -49,6 +49,12 @@ enum eAuthCmd
49
49
XFER_CANCEL = 0x34
50
50
};
51
51
52
+ // perfect hash function for all valid values of eAuthCmd
53
+ inline constexpr std::size_t GetOpcodeArrayIndex (eAuthCmd c)
54
+ {
55
+ return (c & 0x7 ) + ((c & 0x10 ) >> 2 ) + ((c & 0x20 ) >> 5 );
56
+ }
57
+
52
58
#pragma pack(push, 1)
53
59
54
60
typedef struct AUTH_LOGON_CHALLENGE_C
@@ -120,20 +126,50 @@ std::array<uint8, 16> VersionChallenge = { { 0xBA, 0xA3, 0x1E, 0x99, 0xA0, 0x0B,
120
126
#define AUTH_LOGON_CHALLENGE_INITIAL_SIZE 4
121
127
#define REALM_LIST_PACKET_SIZE 5
122
128
123
- std::unordered_map<uint8, AuthHandler > AuthSession::InitHandlers ()
129
+ consteval std::array<AuthHandler, 10 > AuthSession::InitHandlers ()
124
130
{
125
- std::unordered_map<uint8, AuthHandler > handlers;
131
+ std::array<AuthHandler, 10 > handlers = { } ;
126
132
127
- handlers[AUTH_LOGON_CHALLENGE] = { STATUS_CHALLENGE, AUTH_LOGON_CHALLENGE_INITIAL_SIZE, &AuthSession::HandleLogonChallenge };
128
- handlers[AUTH_LOGON_PROOF] = { STATUS_LOGON_PROOF, sizeof (AUTH_LOGON_PROOF_C), &AuthSession::HandleLogonProof };
129
- handlers[AUTH_RECONNECT_CHALLENGE] = { STATUS_CHALLENGE, AUTH_LOGON_CHALLENGE_INITIAL_SIZE, &AuthSession::HandleReconnectChallenge };
130
- handlers[AUTH_RECONNECT_PROOF] = { STATUS_RECONNECT_PROOF, sizeof (AUTH_RECONNECT_PROOF_C), &AuthSession::HandleReconnectProof };
131
- handlers[REALM_LIST] = { STATUS_AUTHED, REALM_LIST_PACKET_SIZE, &AuthSession::HandleRealmList };
133
+ handlers[GetOpcodeArrayIndex (AUTH_LOGON_CHALLENGE)] =
134
+ {
135
+ .cmd = AUTH_LOGON_CHALLENGE,
136
+ .status = STATUS_CHALLENGE,
137
+ .packetSize = AUTH_LOGON_CHALLENGE_INITIAL_SIZE,
138
+ .handler = &AuthSession::HandleLogonChallenge
139
+ };
140
+ handlers[GetOpcodeArrayIndex (AUTH_LOGON_PROOF)] =
141
+ {
142
+ .cmd = AUTH_LOGON_PROOF,
143
+ .status = STATUS_LOGON_PROOF,
144
+ .packetSize = sizeof (AUTH_LOGON_PROOF_C),
145
+ .handler = &AuthSession::HandleLogonProof
146
+ };
147
+ handlers[GetOpcodeArrayIndex (AUTH_RECONNECT_CHALLENGE)] =
148
+ {
149
+ .cmd = AUTH_RECONNECT_CHALLENGE,
150
+ .status = STATUS_CHALLENGE,
151
+ .packetSize = AUTH_LOGON_CHALLENGE_INITIAL_SIZE,
152
+ .handler = &AuthSession::HandleReconnectChallenge
153
+ };
154
+ handlers[GetOpcodeArrayIndex (AUTH_RECONNECT_PROOF)] =
155
+ {
156
+ .cmd = AUTH_RECONNECT_PROOF,
157
+ .status = STATUS_RECONNECT_PROOF,
158
+ .packetSize = sizeof (AUTH_RECONNECT_PROOF_C),
159
+ .handler = &AuthSession::HandleReconnectProof
160
+ };
161
+ handlers[GetOpcodeArrayIndex (REALM_LIST)] =
162
+ {
163
+ .cmd = REALM_LIST,
164
+ .status = STATUS_AUTHED,
165
+ .packetSize = REALM_LIST_PACKET_SIZE,
166
+ .handler = &AuthSession::HandleRealmList
167
+ };
132
168
133
169
return handlers;
134
170
}
135
171
136
- std::unordered_map<uint8, AuthHandler> const Handlers = AuthSession::InitHandlers();
172
+ constexpr std::array<AuthHandler, 10 > Handlers = AuthSession::InitHandlers();
137
173
138
174
void AccountInfo::LoadResult (Field* fields)
139
175
{
@@ -216,22 +252,23 @@ void AuthSession::ReadHandler()
216
252
MessageBuffer& packet = GetReadBuffer ();
217
253
while (packet.GetActiveSize ())
218
254
{
219
- uint8 cmd = packet.GetReadPointer ()[0 ];
220
- auto itr = Handlers. find (cmd);
221
- if (itr == Handlers.end () )
255
+ eAuthCmd cmd = eAuthCmd ( packet.GetReadPointer ()[0 ]) ;
256
+ std:: size_t index = GetOpcodeArrayIndex (cmd);
257
+ if (index >= Handlers.size () || Handlers[index]. cmd != cmd )
222
258
{
223
259
// well we dont handle this, lets just ignore it
224
260
packet.Reset ();
225
261
break ;
226
262
}
227
263
228
- if (_status != itr->second .status )
264
+ AuthHandler const * itr = &Handlers[index];
265
+ if (_status != itr->status )
229
266
{
230
267
CloseSocket ();
231
268
return ;
232
269
}
233
270
234
- uint16 size = uint16 ( itr->second . packetSize ) ;
271
+ std:: size_t size = itr->packetSize ;
235
272
if (packet.GetActiveSize () < size)
236
273
break ;
237
274
@@ -249,7 +286,7 @@ void AuthSession::ReadHandler()
249
286
if (packet.GetActiveSize () < size)
250
287
break ;
251
288
252
- if (!(* this . *itr->second . handler )())
289
+ if (!(this -> *itr->handler )())
253
290
{
254
291
CloseSocket ();
255
292
return ;
0 commit comments