summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhemagx <hemagx2@gmail.com>2016-03-28 21:54:46 +0200
committerHaru <haru@dotalux.com>2016-04-16 07:37:52 +0200
commit9defceef6a3371d09b580ac8f2cffd0476033ea6 (patch)
tree4cfad7c25c28624795b30c3cc44478319b2963f9
parent480e959347ac5903d9c0b659376db139792eb44b (diff)
downloadhercules-9defceef6a3371d09b580ac8f2cffd0476033ea6.tar.gz
hercules-9defceef6a3371d09b580ac8f2cffd0476033ea6.tar.bz2
hercules-9defceef6a3371d09b580ac8f2cffd0476033ea6.tar.xz
hercules-9defceef6a3371d09b580ac8f2cffd0476033ea6.zip
Rewrite client interface for login server (part 2)
Split login packet-related code into functions Signed-off-by: Haru <haru@dotalux.com>
-rw-r--r--src/login/login.c362
1 files changed, 203 insertions, 159 deletions
diff --git a/src/login/login.c b/src/login/login.c
index 27cdb1fa3..f20959979 100644
--- a/src/login/login.c
+++ b/src/login/login.c
@@ -1385,13 +1385,64 @@ void login_kick(struct login_session_data* sd)
charif_sendallwos(-1, buf, 6);
}
+bool login_send_server_list(struct login_session_data *sd)
+{
+ int server_num = 0, i, n, length;
+ uint32 ip;
+ struct packet_AC_ACCEPT_LOGIN *packet = NULL;
+
+ for (i = 0; i < ARRAYLENGTH(server); ++i) {
+ if (sockt->session_is_active(server[i].fd))
+ server_num++;
+ }
+ if (server_num == 0)
+ return false;
+
+ length = sizeof(*packet) + sizeof(packet->server_list[0]) * server_num;
+ ip = sockt->session[sd->fd]->client_addr;
+
+ // Allocate the packet
+ WFIFOHEAD(sd->fd, length);
+ packet = WP2PTR(sd->fd);
+
+ packet->packet_id = PACKET_ID_AC_ACCEPT_LOGIN;
+ packet->packet_len = length;
+ packet->auth_code = sd->login_id1;
+ packet->aid = sd->account_id;
+ packet->user_level = sd->login_id2;
+ packet->last_login_ip = 0; // Not used anymore
+ memset(packet->last_login_time, '\0', sizeof(packet->last_login_time)); // not used anymore
+ packet->sex = sex_str2num(sd->sex);
+ for (i = 0, n = 0; i < ARRAYLENGTH(server); ++i) {
+ uint32 subnet_char_ip;
+
+ if (!sockt->session_is_valid(server[i].fd))
+ continue;
+
+ subnet_char_ip = login->lan_subnet_check(ip);
+ packet->server_list[n].ip = htonl((subnet_char_ip) ? subnet_char_ip : server[i].ip);
+ packet->server_list[n].port = sockt->ntows(htons(server[i].port)); // [!] LE byte order here [!]
+ safestrncpy(packet->server_list[n].name, server[i].name, 20);
+ packet->server_list[n].usercount = server[i].users;
+
+ if (server[i].type == CST_PAYING && sd->expiration_time > time(NULL))
+ packet->server_list[n].property = CST_NORMAL;
+ else
+ packet->server_list[n].property = server[i].type;
+
+ packet->server_list[n].state = server[i].new_;
+ ++n;
+ }
+ WFIFOSET(sd->fd, length);
+
+ return true;
+}
+
void login_auth_ok(struct login_session_data* sd)
{
int fd = 0;
uint32 ip;
- uint8 server_num, n;
struct login_auth_node* node;
- int i;
nullpo_retv(sd);
fd = sd->fd;
@@ -1413,18 +1464,6 @@ void login_auth_ok(struct login_session_data* sd)
return;
}
- server_num = 0;
- for( i = 0; i < ARRAYLENGTH(server); ++i )
- if (sockt->session_is_active(server[i].fd))
- server_num++;
-
- if( server_num == 0 )
- {// if no char-server, don't send void list of servers, just disconnect the player with proper message
- ShowStatus("Connection refused: there is no char-server online (account: %s).\n", sd->userid);
- login->connection_problem(fd, 1); // 01 = server closed
- return;
- }
-
{
struct online_login_data* data = (struct online_login_data*)idb_get(login->online_db, sd->account_id);
if( data )
@@ -1450,49 +1489,16 @@ void login_auth_ok(struct login_session_data* sd)
}
}
+ if (!login_send_server_list(sd)) {
+ // if no char-server, don't send void list of servers, just disconnect the player with proper message
+ ShowStatus("Connection refused: there is no char-server online (account: %s).\n", sd->userid);
+ login->connection_problem(fd, 1); // 01 = server closed
+ return;
+ }
+
login_log(ip, sd->userid, 100, "login ok");
ShowStatus("Connection of the account '%s' accepted.\n", sd->userid);
- {
- struct packet_AC_ACCEPT_LOGIN *packet = NULL;
- int length = sizeof(*packet) + sizeof(packet->server_list[0]) * server_num;
- ip = sockt->session[sd->fd]->client_addr;
-
- // Allocate the packet
- WFIFOHEAD(sd->fd, length);
- packet = WP2PTR(sd->fd);
-
- packet->packet_id = PACKET_ID_AC_ACCEPT_LOGIN;
- packet->packet_len = length;
- packet->auth_code = sd->login_id1;
- packet->aid = sd->account_id;
- packet->user_level = sd->login_id2;
- packet->last_login_ip = 0; // Not used anymore
- memset(packet->last_login_time, '\0', sizeof(packet->last_login_time)); // not used anymore
- packet->sex = sex_str2num(sd->sex);
- for (i = 0, n = 0; i < ARRAYLENGTH(server); ++i) {
- uint32 subnet_char_ip;
-
- if (!sockt->session_is_valid(server[i].fd))
- continue;
-
- subnet_char_ip = login->lan_subnet_check(ip);
- packet->server_list[n].ip = htonl((subnet_char_ip) ? subnet_char_ip : server[i].ip);
- packet->server_list[n].port = sockt->ntows(htons(server[i].port)); // [!] LE byte order here [!]
- safestrncpy(packet->server_list[n].name, server[i].name, 20);
- packet->server_list[n].usercount = server[i].users;
-
- if (server[i].type == CST_PAYING && sd->expiration_time > time(NULL))
- packet->server_list[n].property = CST_NORMAL;
- else
- packet->server_list[n].property = server[i].type;
-
- packet->server_list[n].state = server[i].new_;
- ++n;
- }
- WFIFOSET(sd->fd, length);
- }
-
// create temporary auth entry
CREATE(node, struct login_auth_node, 1);
node->account_id = sd->account_id;
@@ -1608,134 +1614,171 @@ void login_parse_client_md5(int fd, struct login_session_data* sd)
RFIFOSKIP(fd,sizeof(*packet));
}
-bool login_parse_client_login(int fd, struct login_session_data* sd, const char *const ip) __attribute__((nonnull (2)));
-bool login_parse_client_login(int fd, struct login_session_data* sd, const char *const ip)
+// CA_LOGIN
+void login_parse_CA_LOGIN(int fd, struct login_session_data *sd) __attribute__((nonnull (2)));
+void login_parse_CA_LOGIN(int fd, struct login_session_data *sd)
{
- int result;
- uint16 command = RFIFOW(fd,0);
+ const struct packet_CA_LOGIN *packet = RP2PTR(fd);
- switch (command) {
- case PACKET_ID_CA_SSO_LOGIN_REQ:
- {
- const struct packet_CA_SSO_LOGIN_REQ *packet = RP2PTR(fd);
- int tokenlen = (int)RFIFOREST(fd) - (int)sizeof(*packet);
+ sd->version = packet->version;
+ sd->clienttype = packet->clienttype;
+ safestrncpy(sd->userid, packet->id, NAME_LENGTH);
+ safestrncpy(sd->passwd, packet->password, PASSWD_LEN);
- if (tokenlen > PASSWD_LEN || tokenlen < 1) {
- RFIFOSKIP(fd, RFIFOREST(fd)); // assume no other packet was sent
- login->auth_failed(sd, 3);
- return true;
- }
+ RFIFOSKIP(fd, sizeof(*packet));
- sd->clienttype = packet->clienttype;
- sd->version = packet->version;
- safestrncpy(sd->userid, packet->id, NAME_LENGTH);
- safestrncpy(sd->passwd, packet->t1, min(tokenlen + 1, PASSWD_LEN)); // Variable-length field, don't copy more than necessary
+ if (login->config->use_md5_passwds)
+ MD5_String(sd->passwd, sd->passwd);
+ sd->passwdenc = PWENC_NONE;
+}
- RFIFOSKIP(fd, sizeof(*packet));
+// CA_LOGIN2
+void login_parse_CA_LOGIN2(int fd, struct login_session_data *sd) __attribute__((nonnull (2)));
+void login_parse_CA_LOGIN2(int fd, struct login_session_data *sd)
+{
+ const struct packet_CA_LOGIN2 *packet = RP2PTR(fd);
- if (login->config->use_md5_passwds)
- MD5_String(sd->passwd, sd->passwd);
- sd->passwdenc = PWENC_NONE;
- }
- break;
- case PACKET_ID_CA_LOGIN:
- {
- const struct packet_CA_LOGIN *packet = RP2PTR(fd);
+ sd->version = packet->version;
+ sd->clienttype = packet->clienttype;
+ safestrncpy(sd->userid, packet->id, NAME_LENGTH);
+ bin2hex(sd->passwd, packet->password_md5, 16);
+ sd->passwdenc = PASSWORDENC;
- sd->version = packet->version;
- sd->clienttype = packet->clienttype;
- safestrncpy(sd->userid, packet->id, NAME_LENGTH);
- safestrncpy(sd->passwd, packet->password, PASSWD_LEN);
+ RFIFOSKIP(fd, sizeof(*packet));
+}
- RFIFOSKIP(fd, sizeof(*packet));
+// CA_LOGIN3
+void login_parse_CA_LOGIN3(int fd, struct login_session_data *sd) __attribute__((nonnull (2)));
+void login_parse_CA_LOGIN3(int fd, struct login_session_data *sd)
+{
+ const struct packet_CA_LOGIN3 *packet = RP2PTR(fd);
- if (login->config->use_md5_passwds)
- MD5_String(sd->passwd, sd->passwd);
- sd->passwdenc = PWENC_NONE;
- }
- break;
- case PACKET_ID_CA_LOGIN2:
- {
- const struct packet_CA_LOGIN2 *packet = RP2PTR(fd);
+ sd->version = packet->version;
+ sd->clienttype = packet->clienttype;
+ /* unused */
+ /* sd->clientinfo = packet->clientinfo; */
+ safestrncpy(sd->userid, packet->id, NAME_LENGTH);
+ bin2hex(sd->passwd, packet->password_md5, 16);
+ sd->passwdenc = PASSWORDENC;
- sd->version = packet->version;
- sd->clienttype = packet->clienttype;
- safestrncpy(sd->userid, packet->id, NAME_LENGTH);
- bin2hex(sd->passwd, packet->password_md5, 16);
- sd->passwdenc = PASSWORDENC;
+ RFIFOSKIP(fd, sizeof(*packet));
+}
- RFIFOSKIP(fd, sizeof(*packet));
- }
- break;
- case PACKET_ID_CA_LOGIN3:
- {
- const struct packet_CA_LOGIN3 *packet = RP2PTR(fd);
+// CA_LOGIN4
+void login_parse_CA_LOGIN4(int fd, struct login_session_data *sd) __attribute__((nonnull (2)));
+void login_parse_CA_LOGIN4(int fd, struct login_session_data *sd)
+{
+ const struct packet_CA_LOGIN4 *packet = RP2PTR(fd);
- sd->version = packet->version;
- sd->clienttype = packet->clienttype;
- /* unused */
- /* sd->clientinfo = packet->clientinfo; */
- safestrncpy(sd->userid, packet->id, NAME_LENGTH);
- bin2hex(sd->passwd, packet->password_md5, 16);
- sd->passwdenc = PASSWORDENC;
+ sd->version = packet->version;
+ sd->clienttype = packet->clienttype;
+ /* unused */
+ /* safestrncpy(sd->mac_address, packet->mac_address, sizeof(sd->mac_address)); */
+ safestrncpy(sd->userid, packet->id, NAME_LENGTH);
+ bin2hex(sd->passwd, packet->password_md5, 16);
+ sd->passwdenc = PASSWORDENC;
- RFIFOSKIP(fd, sizeof(*packet));
- }
- break;
- case PACKET_ID_CA_LOGIN4:
- {
- const struct packet_CA_LOGIN4 *packet = RP2PTR(fd);
+ RFIFOSKIP(fd, sizeof(*packet));
+}
- sd->version = packet->version;
- sd->clienttype = packet->clienttype;
- /* unused */
- /* safestrncpy(sd->mac_address, packet->mac_address, sizeof(sd->mac_address)); */
- safestrncpy(sd->userid, packet->id, NAME_LENGTH);
- bin2hex(sd->passwd, packet->password_md5, 16);
- sd->passwdenc = PASSWORDENC;
+// CA_LOGIN_PCBANG
+void login_parse_CA_LOGIN_PCBANG(int fd, struct login_session_data *sd) __attribute__((nonnull (2)));
+void login_parse_CA_LOGIN_PCBANG(int fd, struct login_session_data *sd)
+{
+ const struct packet_CA_LOGIN_PCBANG *packet = RP2PTR(fd);
- RFIFOSKIP(fd, sizeof(*packet));
- }
- break;
- case PACKET_ID_CA_LOGIN_PCBANG:
- {
- const struct packet_CA_LOGIN_PCBANG *packet = RP2PTR(fd);
+ sd->version = packet->version;
+ sd->clienttype = packet->clienttype;
+ /* unused */
+ /* safestrncpy(sd->ip, packet->ip, sizeof(sd->ip)); */
+ /* safestrncpy(sd->mac_address, packet->mac_address, sizeof(sd->mac_address)); */
+ safestrncpy(sd->userid, packet->id, NAME_LENGTH);
+ safestrncpy(sd->passwd, packet->password, PASSWD_LEN);
- sd->version = packet->version;
- sd->clienttype = packet->clienttype;
- /* unused */
- /* safestrncpy(sd->ip, packet->ip, sizeof(sd->ip)); */
- /* safestrncpy(sd->mac_address, packet->mac_address, sizeof(sd->mac_address)); */
- safestrncpy(sd->userid, packet->id, NAME_LENGTH);
- safestrncpy(sd->passwd, packet->password, PASSWD_LEN);
+ RFIFOSKIP(fd, sizeof(*packet));
- RFIFOSKIP(fd, sizeof(*packet));
+ if (login->config->use_md5_passwds)
+ MD5_String(sd->passwd, sd->passwd);
+ sd->passwdenc = PWENC_NONE;
+}
- if (login->config->use_md5_passwds)
- MD5_String(sd->passwd, sd->passwd);
- sd->passwdenc = PWENC_NONE;
- }
- break;
+// CA_LOGIN_HAN
+void login_parse_CA_LOGIN_HAN(int fd, struct login_session_data *sd) __attribute__((nonnull (2)));
+void login_parse_CA_LOGIN_HAN(int fd, struct login_session_data *sd)
+{
+ const struct packet_CA_LOGIN_HAN *packet = RP2PTR(fd);
- case PACKET_ID_CA_LOGIN_HAN:
- {
- const struct packet_CA_LOGIN_HAN *packet = RP2PTR(fd);
+ sd->version = packet->version;
+ sd->clienttype = packet->clienttype;
+ /* unused */
+ /* safestrncpy(sd->ip, packet->ip, sizeof(sd->ip)); */
+ /* safestrncpy(sd->mac_address, packet->mac_address, sizeof(sd->mac_address)); */
+ /* sd->ishan = packet->is_han_game_user; */
+ safestrncpy(sd->userid, packet->id, NAME_LENGTH);
+ safestrncpy(sd->passwd, packet->password, PASSWD_LEN);
+
+ RFIFOSKIP(fd, sizeof(*packet));
- sd->version = packet->version;
- sd->clienttype = packet->clienttype;
- /* unused */
- /* safestrncpy(sd->ip, packet->ip, sizeof(sd->ip)); */
- /* safestrncpy(sd->mac_address, packet->mac_address, sizeof(sd->mac_address)); */
- /* sd->ishan = packet->is_han_game_user; */
- safestrncpy(sd->userid, packet->id, NAME_LENGTH);
- safestrncpy(sd->passwd, packet->password, PASSWD_LEN);
+ if (login->config->use_md5_passwds)
+ MD5_String(sd->passwd, sd->passwd);
+ sd->passwdenc = PWENC_NONE;
+}
- RFIFOSKIP(fd, sizeof(*packet));
+// CA_SSO_LOGIN_REQ
+bool login_parse_CA_SSO_LOGIN_REQ(int fd, struct login_session_data *sd) __attribute__((nonnull (2)));
+bool login_parse_CA_SSO_LOGIN_REQ(int fd, struct login_session_data *sd)
+{
+ const struct packet_CA_SSO_LOGIN_REQ *packet = RP2PTR(fd);
+ int tokenlen = (int)RFIFOREST(fd) - (int)sizeof(*packet);
- if (login->config->use_md5_passwds)
- MD5_String(sd->passwd, sd->passwd);
- sd->passwdenc = PWENC_NONE;
+ if (tokenlen > PASSWD_LEN || tokenlen < 1) {
+ RFIFOSKIP(fd, RFIFOREST(fd)); // assume no other packet was sent
+ return false;
}
+
+ sd->clienttype = packet->clienttype;
+ sd->version = packet->version;
+ safestrncpy(sd->userid, packet->id, NAME_LENGTH);
+ safestrncpy(sd->passwd, packet->t1, min(tokenlen + 1, PASSWD_LEN)); // Variable-length field, don't copy more than necessary
+
+ RFIFOSKIP(fd, sizeof(*packet));
+
+ if (login->config->use_md5_passwds)
+ MD5_String(sd->passwd, sd->passwd);
+ sd->passwdenc = PWENC_NONE;
+ return true;
+}
+
+bool login_parse_client_login(int fd, struct login_session_data* sd, const char *const ip) __attribute__((nonnull (2)));
+bool login_parse_client_login(int fd, struct login_session_data* sd, const char *const ip)
+{
+ int result;
+ uint16 command = RFIFOW(fd,0);
+
+ switch (command) {
+ case PACKET_ID_CA_SSO_LOGIN_REQ:
+ if (!login_parse_CA_SSO_LOGIN_REQ(fd, sd)) {
+ login->auth_failed(sd, 3);
+ return true;
+ }
+ break;
+ case PACKET_ID_CA_LOGIN:
+ login_parse_CA_LOGIN(fd, sd);
+ break;
+ case PACKET_ID_CA_LOGIN2:
+ login_parse_CA_LOGIN2(fd, sd);
+ break;
+ case PACKET_ID_CA_LOGIN3:
+ login_parse_CA_LOGIN3(fd, sd);
+ break;
+ case PACKET_ID_CA_LOGIN4:
+ login_parse_CA_LOGIN4(fd, sd);
+ break;
+ case PACKET_ID_CA_LOGIN_PCBANG:
+ login_parse_CA_LOGIN_PCBANG(fd, sd);
+ break;
+ case PACKET_ID_CA_LOGIN_HAN:
+ login_parse_CA_LOGIN_HAN(fd, sd);
break;
default:
RFIFOSKIP(fd,RFIFOREST(fd)); // assume no other packet was sent
@@ -1794,6 +1837,7 @@ void login_char_server_connection_status(int fd, struct login_session_data* sd,
WFIFOSET(fd,3);
}
+// CA_CHARSERVERCONNECT
void login_parse_request_connection(int fd, struct login_session_data* sd, const char *const ip, uint32 ipl) __attribute__((nonnull (2, 3)));
void login_parse_request_connection(int fd, struct login_session_data* sd, const char *const ip, uint32 ipl)
{