diff options
author | hemagx <hemagx2@gmail.com> | 2016-04-12 14:35:21 +0200 |
---|---|---|
committer | Haru <haru@dotalux.com> | 2016-04-16 07:39:53 +0200 |
commit | c8ff1e77501d3edd9bf79fa7ab0281092906735c (patch) | |
tree | 42317e17580b24d334440a2e2e0fa41eec677eea /src/login/login.c | |
parent | d8da35deb6afe62c9efd4a7f553832f4a596eab1 (diff) | |
download | hercules-c8ff1e77501d3edd9bf79fa7ab0281092906735c.tar.gz hercules-c8ff1e77501d3edd9bf79fa7ab0281092906735c.tar.bz2 hercules-c8ff1e77501d3edd9bf79fa7ab0281092906735c.tar.xz hercules-c8ff1e77501d3edd9bf79fa7ab0281092906735c.zip |
Rewrite client interface for login server (part 6)
Moved login clif code to lclif.c/lclif.h
Signed-off-by: Haru <haru@dotalux.com>
Diffstat (limited to 'src/login/login.c')
-rw-r--r-- | src/login/login.c | 732 |
1 files changed, 18 insertions, 714 deletions
diff --git a/src/login/login.c b/src/login/login.c index a98389f7e..38e2651c5 100644 --- a/src/login/login.c +++ b/src/login/login.c @@ -26,6 +26,7 @@ #include "login/account.h" #include "login/ipban.h" #include "login/loginlog.h" +#include "login/lclif.h" #include "common/HPM.h" #include "common/cbasetypes.h" #include "common/core.h" @@ -48,249 +49,10 @@ struct login_interface *login; struct Login_Config login_config_; struct mmo_char_server server[MAX_SERVERS]; // char server data -/// Maximum amount of packets processed at once from the same client -#define MAX_PROCESSED_PACKETS (3) - -// Packet DB -#define MIN_PACKET_DB 0x0064 -#define MAX_PACKET_DB 0x08ff - -/* Enums */ - -/// Packet IDs -enum login_packet_id { - // CA (Client to Login) - PACKET_ID_CA_LOGIN = 0x0064, - PACKET_ID_CA_LOGIN2 = 0x01dd, - PACKET_ID_CA_LOGIN3 = 0x01fa, - PACKET_ID_CA_CONNECT_INFO_CHANGED = 0x0200, - PACKET_ID_CA_EXE_HASHCHECK = 0x0204, - PACKET_ID_CA_LOGIN_PCBANG = 0x0277, - PACKET_ID_CA_LOGIN4 = 0x027c, - PACKET_ID_CA_LOGIN_HAN = 0x02b0, - PACKET_ID_CA_SSO_LOGIN_REQ = 0x0825, - PACKET_ID_CA_REQ_HASH = 0x01db, - PACKET_ID_CA_CHARSERVERCONNECT = 0x2710, // Custom Hercules Packet - //PACKET_ID_CA_SSO_LOGIN_REQa = 0x825a, /* unused */ - - // AC (Login to Client) - PACKET_ID_AC_ACCEPT_LOGIN = 0x0069, - PACKET_ID_AC_REFUSE_LOGIN = 0x006a, - PACKET_ID_SC_NOTIFY_BAN = 0x0081, - PACKET_ID_AC_ACK_HASH = 0x01dc, - PACKET_ID_AC_REFUSE_LOGIN_R2 = 0x083e, -}; - -/* Function Typedefs */ -typedef enum parsefunc_rcode (LoginParseFunc)(int fd, struct login_session_data *sd); - -/* Structs */ -/// Login packet DB entry -struct login_packet_db { - int16 len; ///< Packet length - LoginParseFunc *pFunc; ///< Packet parsing function -}; - -/* Packets Structs */ -#if !defined(sun) && (!defined(__NETBSD__) || __NetBSD_Version__ >= 600000000) // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute -#pragma pack(push, 1) -#endif // not NetBSD < 6 / Solaris - -/** - * Packet structure for CA_LOGIN. - */ -struct packet_CA_LOGIN { - int16 packet_id; ///< Packet ID (#PACKET_ID_CA_LOGIN) - uint32 version; ///< Client Version - char id[24]; ///< Username - char password[24]; ///< Password - uint8 clienttype; ///< Client Type -} __attribute__((packed)); - -/** - * Packet structure for CA_LOGIN2. - */ -struct packet_CA_LOGIN2 { - int16 packet_id; ///< Packet ID (#PACKET_ID_CA_LOGIN2) - uint32 version; ///< Client Version - char id[24]; ///< Username - uint8 password_md5[16]; ///< Password hash - uint8 clienttype; ///< Client Type -} __attribute__((packed)); - -/** - * Packet structure for CA_LOGIN3. - */ -struct packet_CA_LOGIN3 { - int16 packet_id; ///< Packet ID (#PACKET_ID_CA_LOGIN3) - uint32 version; ///< Client Version - char id[24]; ///< Username - uint8 password_md5[16]; ///< Password hash - uint8 clienttype; ///< Client Type - uint8 clientinfo; ///< Index of the connection in the clientinfo file (+10 if the command-line contains "pc") -} __attribute__((packed)); - -/** - * Packet structure for CA_LOGIN4. - */ -struct packet_CA_LOGIN4 { - int16 packet_id; ///< Packet ID (#PACKET_ID_CA_LOGIN4) - uint32 version; ///< Client Version - char id[24]; ///< Username - uint8 password_md5[16]; ///< Password hash - uint8 clienttype; ///< Client Type - char mac_address[13]; ///< MAC Address -} __attribute__((packed)); - -/** - * Packet structure for CA_LOGIN_PCBANG. - */ -struct packet_CA_LOGIN_PCBANG { - int16 packet_id; ///< Packet ID (#PACKET_ID_CA_LOGIN_PCBANG) - uint32 version; ///< Client Version - char id[24]; ///< Username - char password[24]; ///< Password - uint8 clienttype; ///< Client Type - char ip[16]; ///< IP Address - char mac_address[13]; ///< MAC Address -} __attribute__((packed)); - -/** - * Packet structure for CA_LOGIN_HAN. - */ -struct packet_CA_LOGIN_HAN { - int16 packet_id; ///< Packet ID (#PACKET_ID_CA_LOGIN_HAN) - uint32 version; ///< Client Version - char id[24]; ///< Username - char password[24]; ///< Password - uint8 clienttype; ///< Client Type - char ip[16]; ///< IP Address - char mac_address[13]; ///< MAC Address - uint8 is_han_game_user; ///< 'isGravityID' -} __attribute__((packed)); - -/** - * Packet structure for CA_SSO_LOGIN_REQ. - * - * Variable-length packet. - */ -struct packet_CA_SSO_LOGIN_REQ { - int16 packet_id; ///< Packet ID (#PACKET_ID_CA_SSO_LOGIN_REQ) - int16 packet_len; ///< Length (variable length) - uint32 version; ///< Clientver - uint8 clienttype; ///< Clienttype - char id[24]; ///< Username - char password[27]; ///< Password - int8 mac_address[17]; ///< MAC Address - char ip[15]; ///< IP Address - char t1[]; ///< SSO Login Token (variable length) -} __attribute__((packed)); - -#if 0 // Unused -struct packet_CA_SSO_LOGIN_REQa { - int16 packet_id; - int16 packet_len; - uint32 version; - uint8 clienttype; - char id[24]; - int8 mac_address[17]; - char ip[15]; - char t1[]; -} __attribute__((packed)); -#endif // unused - -/** - * Packet structure for CA_CONNECT_INFO_CHANGED. - * - * New alive packet. Used to verify if client is always alive. - */ -struct packet_CA_CONNECT_INFO_CHANGED { - int16 packet_id; ///< Packet ID (#PACKET_ID_CA_CONNECT_INFO_CHANGED) - char id[24]; ///< account.userid -} __attribute__((packed)); - -/** - * Packet structure for CA_EXE_HASHCHECK. - * - * (kRO 2004-05-31aSakexe langtype 0 and 6) - */ -struct packet_CA_EXE_HASHCHECK { - int16 packet_id; ///< Packet ID (#PACKET_ID_CA_EXE_HASHCHECK) - uint8 hash_value[16]; ///< Client MD5 hash -} __attribute__((packed)); - -/** - * Packet structure for CA_REQ_HASH. - */ -struct packet_CA_REQ_HASH { - int16 packet_id; ///< Packet ID (#PACKET_ID_CA_REQ_HASH) -} __attribute__((packed)); - -struct packet_CA_CHARSERVERCONNECT { - int16 packet_id; - char userid[24]; - char password[24]; - int32 unknown; - int32 ip; - int16 port; - char name[20]; - int16 unknown2; - int16 type; - int16 new; -} __attribute__((packed)); - -struct packet_SC_NOTIFY_BAN { - int16 packet_id; - uint8 error_code; -} __attribute__((packed)); - -struct packet_AC_REFUSE_LOGIN { - int16 packet_id; - uint8 error_code; - char block_date[20]; -} __attribute__((packed)); - -struct packet_AC_REFUSE_LOGIN_R2 { - int16 packet_id; - uint32 error_code; - char block_date[20]; -} __attribute__((packed)); - -struct packet_AC_ACCEPT_LOGIN { - int16 packet_id; - int16 packet_len; - int32 auth_code; - uint32 aid; - uint32 user_level; - uint32 last_login_ip; - char last_login_time[26]; - uint8 sex; - struct { - uint32 ip; - int16 port; - char name[20]; - uint16 usercount; - uint16 state; - uint16 property; - } server_list[]; -} __attribute__((packed)); - -struct packet_AC_ACK_HASH { - int16 packet_id; - int16 packet_len; - uint8 secret[]; -} __attribute__((packed)); - -#if !defined(sun) && (!defined(__NETBSD__) || __NetBSD_Version__ >= 600000000) // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute -#pragma pack(pop) -#endif // not NetBSD < 6 / Solaris - struct Account_engine account_engine[] = { {account_db_sql, NULL} }; -struct login_packet_db packet_db[MAX_PACKET_DB + 1]; - // account database AccountDB* accounts = NULL; @@ -1419,16 +1181,6 @@ int login_mmo_auth(struct login_session_data* sd, bool isServer) { return -1; // account OK } -void login_connection_error(int fd, uint8 error) -{ - struct packet_SC_NOTIFY_BAN *packet = NULL; - WFIFOHEAD(fd, sizeof(*packet)); - packet = WP2PTR(fd); - packet->packet_id = PACKET_ID_SC_NOTIFY_BAN; - packet->error_code = error; - WFIFOSET(fd, sizeof(*packet)); -} - void login_kick(struct login_session_data* sd) { uint8 buf[6]; @@ -1438,59 +1190,6 @@ 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; @@ -1503,17 +1202,17 @@ void login_auth_ok(struct login_session_data* sd) if( core->runflag != LOGINSERVER_ST_RUNNING ) { // players can only login while running - login->connection_error(fd, 1); // 01 = server closed + lclif->connection_error(fd, 1); // 01 = server closed return; } if (login->config->group_id_to_connect >= 0 && sd->group_id != login->config->group_id_to_connect) { ShowStatus("Connection refused: the required group id for connection is %d (account: %s, group: %d).\n", login->config->group_id_to_connect, sd->userid, sd->group_id); - login->connection_error(fd, 1); // 01 = server closed + lclif->connection_error(fd, 1); // 01 = server closed return; } else if (login->config->min_group_id_to_connect >= 0 && login->config->group_id_to_connect == -1 && sd->group_id < login->config->min_group_id_to_connect) { ShowStatus("Connection refused: the minimum group id required for connection is %d (account: %s, group: %d).\n", login->config->min_group_id_to_connect, sd->userid, sd->group_id); - login->connection_error(fd, 1); // 01 = server closed + lclif->connection_error(fd, 1); // 01 = server closed return; } @@ -1528,7 +1227,7 @@ void login_auth_ok(struct login_session_data* sd) if( data->waiting_disconnect == INVALID_TIMER ) data->waiting_disconnect = timer->add(timer->gettick()+AUTH_TIMEOUT, login->waiting_disconnect_timer, sd->account_id, 0); - login->connection_error(fd, 8); // 08 = Server still recognizes your last login + lclif->connection_error(fd, 8); // 08 = Server still recognizes your last login return; } else @@ -1542,10 +1241,10 @@ void login_auth_ok(struct login_session_data* sd) } } - if (!login_send_server_list(sd)) { + if (!lclif->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_error(fd, 1); // 01 = server closed + lclif->connection_error(fd, 1); // 01 = server closed return; } @@ -1624,188 +1323,7 @@ void login_auth_failed(struct login_session_data *sd, int result) if (accounts->load_str(accounts, &acc, sd->userid)) ban_time = acc.unban_time; } - login->send_auth_failed(fd, ban_time, result); -} - -void login_send_auth_failed(int fd, time_t ban, uint32 error) -{ -#if PACKETVER >= 20120000 /* not sure when this started */ - struct packet_AC_REFUSE_LOGIN_R2 *packet = NULL; - int packet_id = PACKET_ID_AC_REFUSE_LOGIN_R2; -#else - struct packet_AC_REFUSE_LOGIN *packet = NULL; - int packet_id = PACKET_ID_AC_REFUSE_LOGIN; -#endif - WFIFOHEAD(fd, sizeof(*packet)); - packet = WP2PTR(fd); - packet->packet_id = packet_id; - packet->error_code = error; - if (error == 6) - timestamp2string(packet->block_date, sizeof(packet->block_date), ban, login->config->date_format); - else - memset(packet->block_date, '\0', sizeof(packet->block_date)); - WFIFOSET(fd, sizeof(*packet)); -} - -void login_login_error(int fd, uint8 error) -{ - struct packet_AC_REFUSE_LOGIN *packet = NULL; - WFIFOHEAD(fd, sizeof(*packet)); - packet = WP2PTR(fd); - packet->packet_id = PACKET_ID_AC_REFUSE_LOGIN; - packet->error_code = error; - memset(packet->block_date, '\0', sizeof(packet->block_date)); - WFIFOSET(fd, sizeof(*packet)); -} - -enum parsefunc_rcode login_parse_CA_CONNECT_INFO_CHANGED(int fd, struct login_session_data *sd) __attribute__((nonnull (2))); -enum parsefunc_rcode login_parse_CA_CONNECT_INFO_CHANGED(int fd, struct login_session_data *sd) -{ - return PACKET_VALID; -} - -enum parsefunc_rcode login_parse_CA_EXE_HASHCHECK(int fd, struct login_session_data *sd) __attribute__((nonnull (2))); -enum parsefunc_rcode login_parse_CA_EXE_HASHCHECK(int fd, struct login_session_data *sd) -{ - const struct packet_CA_EXE_HASHCHECK *packet = RP2PTR(fd); - sd->has_client_hash = 1; - memcpy(sd->client_hash, packet->hash_value, 16); - return PACKET_VALID; -} - -enum parsefunc_rcode login_parse_CA_LOGIN(int fd, struct login_session_data *sd) __attribute__((nonnull (2))); -enum parsefunc_rcode login_parse_CA_LOGIN(int fd, struct login_session_data *sd) -{ - const struct packet_CA_LOGIN *packet = RP2PTR(fd); - - sd->version = packet->version; - sd->clienttype = packet->clienttype; - 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; - - login->client_login(fd, sd); - return PACKET_VALID; -} - -enum parsefunc_rcode login_parse_CA_LOGIN2(int fd, struct login_session_data *sd) __attribute__((nonnull (2))); -enum parsefunc_rcode login_parse_CA_LOGIN2(int fd, struct login_session_data *sd) -{ - const struct packet_CA_LOGIN2 *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; - - login->client_login(fd, sd); - return PACKET_VALID; -} - -enum parsefunc_rcode login_parse_CA_LOGIN3(int fd, struct login_session_data *sd) __attribute__((nonnull (2))); -enum parsefunc_rcode login_parse_CA_LOGIN3(int fd, struct login_session_data *sd) -{ - const struct packet_CA_LOGIN3 *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; - - login->client_login(fd, sd); - return PACKET_VALID; -} - -enum parsefunc_rcode login_parse_CA_LOGIN4(int fd, struct login_session_data *sd) __attribute__((nonnull (2))); -enum parsefunc_rcode 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 */ - /* 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; - - login->client_login(fd, sd); - return PACKET_VALID; -} - -enum parsefunc_rcode login_parse_CA_LOGIN_PCBANG(int fd, struct login_session_data *sd) __attribute__((nonnull (2))); -enum parsefunc_rcode login_parse_CA_LOGIN_PCBANG(int fd, struct login_session_data *sd) -{ - 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); - - if (login->config->use_md5_passwds) - MD5_String(sd->passwd, sd->passwd); - sd->passwdenc = PWENC_NONE; - - login->client_login(fd, sd); - return PACKET_VALID; -} - -enum parsefunc_rcode login_parse_CA_LOGIN_HAN(int fd, struct login_session_data *sd) __attribute__((nonnull (2))); -enum parsefunc_rcode login_parse_CA_LOGIN_HAN(int fd, struct login_session_data *sd) -{ - 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); - - if (login->config->use_md5_passwds) - MD5_String(sd->passwd, sd->passwd); - sd->passwdenc = PWENC_NONE; - - login->client_login(fd, sd); - return PACKET_VALID; -} - -enum parsefunc_rcode login_parse_CA_SSO_LOGIN_REQ(int fd, struct login_session_data *sd) __attribute__((nonnull (2))); -enum parsefunc_rcode 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 (tokenlen > PASSWD_LEN || tokenlen < 1) { - ShowError("login_parse_CA_SSO_LOGIN_REQ: Token length is not between allowed password length, kicking player ('%s')", packet->id); - sockt->eof(fd); - return PACKET_VALID; - } - - 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; - - login->client_login(fd, sd); - return PACKET_VALID; + lclif->auth_failed(fd, ban_time, result); } bool login_client_login(int fd, struct login_session_data *sd) __attribute__((nonnull (2))); @@ -1832,31 +1350,6 @@ bool login_client_login(int fd, struct login_session_data *sd) return false; } -void login_send_coding_key(int fd, struct login_session_data *sd) __attribute__((nonnull (2))); -void login_send_coding_key(int fd, struct login_session_data *sd) -{ - struct packet_AC_ACK_HASH *packet = NULL; - int16 size = sizeof(*packet) + sd->md5keylen; - - WFIFOHEAD(fd, size); - packet = WP2PTR(fd); - packet->packet_id = PACKET_ID_AC_ACK_HASH; - packet->packet_len = size; - memcpy(packet->secret, sd->md5key, sd->md5keylen); - WFIFOSET(fd, size); -} - -enum parsefunc_rcode login_parse_CA_REQ_HASH(int fd, struct login_session_data *sd) __attribute__((nonnull (2))); -enum parsefunc_rcode login_parse_CA_REQ_HASH(int fd, struct login_session_data *sd) -{ - memset(sd->md5key, '\0', sizeof(sd->md5key)); - sd->md5keylen = (uint16)(12 + rnd() % 4); - MD5_Salt(sd->md5keylen, sd->md5key); - - login->send_coding_key(fd, sd); - return PACKET_VALID; -} - void login_char_server_connection_status(int fd, struct login_session_data* sd, uint8 status) __attribute__((nonnull (2))); void login_char_server_connection_status(int fd, struct login_session_data* sd, uint8 status) { @@ -1866,18 +1359,7 @@ void login_char_server_connection_status(int fd, struct login_session_data* sd, WFIFOSET(fd,3); } -enum parsefunc_rcode login_parse_CA_CHARSERVERCONNECT(int fd, struct login_session_data *sd) __attribute__((nonnull (2))); -enum parsefunc_rcode login_parse_CA_CHARSERVERCONNECT(int fd, struct login_session_data *sd) -{ - char ip[16]; - uint32 ipl = sockt->session[fd]->client_addr; - sockt->ip2str(ipl, ip); - - login->parse_request_connection(fd, sd, ip, ipl); - - return PACKET_STOPPARSE; -} - +// 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) { @@ -1937,140 +1419,6 @@ void login_parse_request_connection(int fd, struct login_session_data* sd, const } } -struct login_packet_db *login_lclif_packet(int16 packet_id) -{ - if (packet_id == PACKET_ID_CA_CHARSERVERCONNECT) - return &packet_db[0]; - - if (packet_id > MAX_PACKET_DB || packet_id < MIN_PACKET_DB) - return NULL; - - return &packet_db[packet_id]; -} - -enum parsefunc_rcode login_parse_packet(const struct login_packet_db *lpd, int fd, struct login_session_data *sd) -{ - int result; - result = lpd->pFunc(fd, sd); - RFIFOSKIP(fd, (lpd->len == -1) ? RFIFOW(fd, 2) : lpd->len); - return result; -} - -//---------------------------------------------------------------------------------------- -// Default packet parsing (normal players or char-server connection requests) -//---------------------------------------------------------------------------------------- -int login_parse_login(int fd) -{ - struct login_session_data *sd = NULL; - int i; - char ip[16]; - uint32 ipl = sockt->session[fd]->client_addr; - sockt->ip2str(ipl, ip); - - if (sockt->session[fd]->flag.eof) { - ShowInfo("Closed connection from '"CL_WHITE"%s"CL_RESET"'.\n", ip); - sockt->close(fd); - return 0; - } - - if ((sd = sockt->session[fd]->session_data) == NULL) { - // Perform ip-ban check - if (login->config->ipban && !sockt->trusted_ip_check(ipl) && ipban_check(ipl)) { - ShowStatus("Connection refused: IP isn't authorized (deny/allow, ip: %s).\n", ip); - login_log(ipl, "unknown", -3, "ip banned"); - login->login_error(fd, 3); // 3 = Rejected from Server - sockt->eof(fd); - return 0; - } - - // create a session for this new connection - CREATE(sockt->session[fd]->session_data, struct login_session_data, 1); - sd = sockt->session[fd]->session_data; - sd->fd = fd; - } - - for (i = 0; i < MAX_PROCESSED_PACKETS; ++i) { - enum parsefunc_rcode result; - int16 packet_id = RFIFOW(fd, 0); - int packet_len = (int)RFIFOREST(fd); - - if (packet_len < 2) - return 0; - - result = login->parse_login_sub(fd, sd); - - switch (result) { - case PACKET_SKIP: - continue; - case PACKET_INCOMPLETE: - case PACKET_STOPPARSE: - return 0; - case PACKET_UNKNOWN: - ShowWarning("login_parse_login: Received unsupported packet (packet 0x%04x, %d bytes received), disconnecting session #%d.\n", (unsigned int)packet_id, packet_len, fd); -#ifdef DUMP_INVALID_PACKET - ShowDump(RFIFOP(fd, 0), RFIFOREST(fd)); -#endif - sockt->eof(fd); - return 0; - case PACKET_INVALIDLENGTH: - ShowWarning("login_parse_login: Received packet 0x%04x specifies invalid packet_len (%d), disconnecting session #%d.\n", (unsigned int)packet_id, packet_len, fd); -#ifdef DUMP_INVALID_PACKET - ShowDump(RFIFOP(fd, 0), RFIFOREST(fd)); -#endif - sockt->eof(fd); - return 0; - } - } - return 0; -} - -enum parsefunc_rcode login_parse_login_sub(int fd, struct login_session_data *sd) -{ - int packet_len = (int)RFIFOREST(fd); - int16 packet_id = RFIFOW(fd, 0); - const struct login_packet_db *lpd; - - if (VECTOR_LENGTH(HPM->packets[hpParse_Login]) > 0) { - int result = HPM->parse_packets(fd, packet_id, hpParse_Login); - if (result == 1) - return PACKET_VALID; - if (result == 2) - return PACKET_INCOMPLETE; // Packet not completed yet - } - - lpd = login_lclif_packet(packet_id); - - if (lpd == NULL) - return PACKET_UNKNOWN; - - if (lpd->len == 0) - return PACKET_UNKNOWN; - - if (lpd->len > 0 && lpd->pFunc == NULL) - return PACKET_UNKNOWN; //This Packet is defined for length purpose ? should never be sent from client ? - - if (lpd->len == -1) { - uint16 packet_var_len = 0; //Max Variable Packet length is signed int16 size - - if (packet_len < 4) - return PACKET_INCOMPLETE; //Packet incomplete - - packet_var_len = RFIFOW(fd, 2); - - if (packet_var_len < 4 || packet_var_len > SINT16_MAX) - return PACKET_INVALIDLENGTH; //Something is wrong, close connection. - - if (RFIFOREST(fd) < packet_var_len) - return PACKET_INCOMPLETE; //Packet incomplete again. - - return login->parse_packet(lpd, fd, sd); - } else if (lpd->len <= packet_len) { - return login->parse_packet(lpd, fd, sd); - } - - return PACKET_VALID; -} - void login_config_set_defaults(void) { login->config->login_ip = INADDR_ANY; @@ -2265,6 +1613,8 @@ int do_final(void) { login->fd = -1; } + lclif->final(); + HPM_login_do_final(); aFree(login->LOGIN_CONF_NAME); @@ -2338,47 +1688,6 @@ void cmdline_args_init_local(void) CMDLINEARG_DEF2(net-config, netconfig, "Alternative subnet configuration.", CMDLINE_OPT_PARAM); } -void packetdb_loaddb(void) -{ - - int i; - struct packet { - int16 packet_id; - int16 packet_len; - int (*pFunc)(int, struct login_session_data *); - } packet[] = { -#define packet_def(name) { PACKET_ID_ ## name, sizeof(struct packet_ ## name), login_parse_ ## name } -#define packet_def2(name, len) { PACKET_ID_ ## name, (len), login_parse_ ## name } - packet_def(CA_CONNECT_INFO_CHANGED), - packet_def(CA_EXE_HASHCHECK), - packet_def(CA_LOGIN), - packet_def(CA_LOGIN2), - packet_def(CA_LOGIN3), - packet_def(CA_LOGIN4), - packet_def(CA_LOGIN_PCBANG), - packet_def(CA_LOGIN_HAN), - packet_def2(CA_SSO_LOGIN_REQ, -1), - packet_def(CA_REQ_HASH), -#undef packet_def -#undef packet_def2 - }; - int length = ARRAYLENGTH(packet); - - memset(packet_db, '\0', sizeof(packet_db)); - - for (i = 0; i < length; ++i) { - int16 packet_id = packet[i].packet_id; - Assert_retb(packet_id >= MIN_PACKET_DB && packet_id < MAX_PACKET_DB); - packet_db[packet_id].len = packet[i].packet_len; - packet_db[packet_id].pFunc = packet[i].pFunc; - } - - //Explict case, we will save character login packet in position 0 which is unused and not valid by normal - packet_db[0].len = sizeof(struct packet_CA_CHARSERVERCONNECT); - packet_db[0].pFunc = login_parse_CA_CHARSERVERCONNECT; - -} - //------------------------------ // Login server initialization //------------------------------ @@ -2395,6 +1704,7 @@ int do_init(int argc, char** argv) } login_defaults(); + lclif_defaults(); // read login-server configuration login->config_set_defaults(); @@ -2402,6 +1712,8 @@ int do_init(int argc, char** argv) login->LOGIN_CONF_NAME = aStrdup("conf/login-server.conf"); login->NET_CONF_NAME = aStrdup("conf/network.conf"); + lclif->init(); + HPM_login_do_init(); cmdline->exec(argc, argv, CMDLINE_OPT_PREINIT); HPM->config_read(); @@ -2411,8 +1723,6 @@ int do_init(int argc, char** argv) login_config_read(login->LOGIN_CONF_NAME); sockt->net_config_read(login->NET_CONF_NAME); - packetdb_loaddb(); - for( i = 0; i < ARRAYLENGTH(server); ++i ) chrif_server_init(i); @@ -2430,8 +1740,8 @@ int do_init(int argc, char** argv) // Interserver auth init login->auth_db = idb_alloc(DB_OPT_RELEASE_DATA); - // set default parser as login_parse_login function - sockt->set_defaultparse(login->parse_login); + // set default parser as lclif->parse function + sockt->set_defaultparse(lclif->parse); // every 10 minutes cleanup online account db. timer->add_func_list(login->online_data_cleanup, "login->online_data_cleanup"); @@ -2523,21 +1833,15 @@ void login_defaults(void) { login->fromchar_parse_accinfo = login_fromchar_parse_accinfo; login->parse_fromchar = login_parse_fromchar; - login->parse_login = login_parse_login; + login->client_login = login_client_login; + login->parse_request_connection = login_parse_request_connection; login->auth_ok = login_auth_ok; login->auth_failed = login_auth_failed; - login->send_auth_failed = login_send_auth_failed; login->char_server_connection_status = login_char_server_connection_status; - login->connection_error = login_connection_error; login->kick = login_kick; - login->login_error = login_login_error; - login->send_coding_key = login_send_coding_key; login->config_set_defaults = login_config_set_defaults; login->config_read = login_config_read; login->LOGIN_CONF_NAME = NULL; login->NET_CONF_NAME = NULL; - - login->parse_packet = login_parse_packet; - login->parse_login_sub = login_parse_login_sub; } |