diff --git a/src/char/char.c b/src/char/char.c index 9b2652d0440..6107b509e9d 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -51,6 +51,7 @@ #include "common/apipackets.h" #include "common/cbasetypes.h" #include "common/charloginpackets.h" +#include "common/mapcharpackets.h" #include "common/chunked.h" #include "common/conf.h" #include "common/console.h" @@ -204,12 +205,16 @@ static struct DBData char_create_online_char_data(union DBKey key, va_list args) return DB->ptr2data(character); } -static void char_set_account_online(int account_id) +static void char_set_account_online(int account_id, bool standalone) { - WFIFOHEAD(chr->login_fd,6); - WFIFOW(chr->login_fd,0) = 0x272b; - WFIFOL(chr->login_fd,2) = account_id; - WFIFOSET(chr->login_fd,6); + WFIFOHEAD(chr->login_fd, sizeof(struct PACKET_CHARLOGIN_SET_ACCOUNT_ONLINE)); + + struct PACKET_CHARLOGIN_SET_ACCOUNT_ONLINE *p = WFIFOP(chr->login_fd, 0); + p->packetType = HEADER_CHARLOGIN_SET_ACCOUNT_ONLINE; + p->account_id = account_id; + p->standalone = standalone ? 1 : 0; + + WFIFOSET(chr->login_fd, sizeof(*p)); } static void char_set_account_offline(int account_id) @@ -243,10 +248,10 @@ static void char_set_char_charselect(int account_id) } if (chr->login_fd > 0 && !sockt->session[chr->login_fd]->flag.eof) - chr->set_account_online(account_id); + chr->set_account_online(account_id, false); } -static void char_set_char_online(bool is_initializing, int char_id, int account_id) +static void char_set_char_online(bool is_initializing, int char_id, int account_id, bool standalone) { struct online_char_data* character; struct mmo_charstatus *cp; @@ -280,7 +285,7 @@ static void char_set_char_online(bool is_initializing, int char_id, int account_ //Notify login server if (chr->login_fd > 0 && !sockt->session[chr->login_fd]->flag.eof) - chr->set_account_online(account_id); + chr->set_account_online(account_id, standalone); } static void char_set_char_offline(int char_id, int account_id) @@ -3275,7 +3280,7 @@ static void char_parse_frommap_save_character(int fd) } else { //This may be valid on char-server reconnection, when re-sending characters that already logged off. ShowError("parse_from_map (save-char): Received data for non-existing/offline character (%d:%d).\n", aid, cid); - chr->set_char_online(false, cid, aid); + chr->set_char_online(false, cid, aid, false); } if (RFIFOB(fd,12)) { @@ -3677,7 +3682,7 @@ static void char_parse_frommap_set_all_offline(int fd) static void char_parse_frommap_set_char_online(int fd) { - chr->set_char_online(false, RFIFOL(fd, 2), RFIFOL(fd, 6)); + chr->set_char_online(false, RFIFOL(fd, 2), RFIFOL(fd, 6), false); RFIFOSKIP(fd,10); } @@ -3781,13 +3786,16 @@ static void char_parse_frommap_auth_request(int fd) struct char_auth_node* node; struct mmo_charstatus* cd; - int account_id = RFIFOL(fd,2); - int char_id = RFIFOL(fd,6); - int login_id1 = RFIFOL(fd,10); - char sex = RFIFOB(fd,14); - uint32 ip = ntohl(RFIFOL(fd,15)); - char standalone = RFIFOB(fd, 19); - RFIFOSKIP(fd,20); + const struct PACKET_MAPCHAR_AUTH_REQ *p = RFIFOP(fd, 0); + + int account_id = p->account_id; + int char_id = p->char_id; + int login_id1 = p->login_id1; + char sex = p->sex; + uint32 ip = ntohl(p->client_addr); + uint8 standalone = p->standalone; + + RFIFOSKIP(fd, sizeof(struct PACKET_MAPCHAR_AUTH_REQ)); node = (struct char_auth_node*)idb_get(auth_db, account_id); cd = (struct mmo_charstatus*)uidb_get(chr->char_db_,char_id); @@ -3797,11 +3805,11 @@ static void char_parse_frommap_auth_request(int fd) cd = (struct mmo_charstatus*)uidb_get(chr->char_db_,char_id); } - if( core->runflag == CHARSERVER_ST_RUNNING && cd && standalone ) { + if (core->runflag == CHARSERVER_ST_RUNNING && cd != NULL && standalone != 0) { cd->sex = sex; chr->map_auth_ok(fd, account_id, NULL, cd); - chr->set_char_online(false, char_id, account_id); + chr->set_char_online(false, char_id, account_id, true); return; } @@ -3820,7 +3828,7 @@ static void char_parse_frommap_auth_request(int fd) chr->map_auth_ok(fd, account_id, node, cd); // only use the auth once and mark user online idb_remove(auth_db, account_id); - chr->set_char_online(false, char_id, account_id); + chr->set_char_online(false, char_id, account_id, (standalone != 0)); } else {// auth failed @@ -4040,8 +4048,8 @@ static int char_parse_frommap(int fd) chr->parse_frommap_ping(fd); break; - case 0x2b26: // auth request from map-server - if (RFIFOREST(fd) < 20) + case HEADER_MAPCHAR_AUTH_REQ: // auth request from map-server + if (RFIFOREST(fd) < sizeof(struct PACKET_MAPCHAR_AUTH_REQ)) return 0; { @@ -4576,7 +4584,7 @@ static void char_parse_char_select(int fd, struct char_session_data *sd, uint32 } /* set char as online prior to loading its data so 3rd party applications will realize the sql data is not reliable */ - chr->set_char_online(true, char_id, sd->account_id); + chr->set_char_online(true, char_id, sd->account_id, false); loginif->set_char_online(char_id, sd->account_id); if (!chr->mmo_char_fromsql(char_id, &char_dat, true)) { /* failed? set it back offline */ chr->set_char_offline(char_id, sd->account_id); diff --git a/src/char/char.h b/src/char/char.h index bb697bb609a..325b964840e 100644 --- a/src/char/char.h +++ b/src/char/char.h @@ -140,10 +140,10 @@ struct char_interface { int (*waiting_disconnect) (int tid, int64 tick, int id, intptr_t data); int (*delete_char_sql) (int char_id); struct DBData (*create_online_char_data) (union DBKey key, va_list args); - void (*set_account_online) (int account_id); + void (*set_account_online) (int account_id, bool standalone); void (*set_account_offline) (int account_id); void (*set_char_charselect) (int account_id); - void (*set_char_online) (bool is_initializing, int char_id, int account_id); + void (*set_char_online) (bool is_initializing, int char_id, int account_id, bool standalone); void (*set_char_offline) (int char_id, int account_id); int (*db_setoffline) (union DBKey key, struct DBData *data, va_list ap); int (*db_kickoffline) (union DBKey key, struct DBData *data, va_list ap); diff --git a/src/char/packets_hc_struct.h b/src/char/packets_hc_struct.h index 08ae5b83ffb..3a4fe27c3f4 100644 --- a/src/char/packets_hc_struct.h +++ b/src/char/packets_hc_struct.h @@ -23,6 +23,7 @@ #include "common/hercules.h" #include "common/mmo.h" #include "common/packetsstatic_len.h" +#include "common/packetsmacro.h" /* Packets Structs */ #if !defined(sun) && (!defined(__NETBSD__) || __NetBSD_Version__ >= 600000000) // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute diff --git a/src/common/HPMDataCheck.h b/src/common/HPMDataCheck.h index e9043d3b509..5d4bd1fdf25 100644 --- a/src/common/HPMDataCheck.h +++ b/src/common/HPMDataCheck.h @@ -256,6 +256,7 @@ HPExport const struct s_HPMDataCheck HPMDataCheck[] = { #endif // COMMON_BASE62_H #ifdef COMMON_CHARLOGINPACKETS_H { "PACKET_CHARLOGIN_ONLINE_ACCOUNTS", sizeof(struct PACKET_CHARLOGIN_ONLINE_ACCOUNTS), SERVER_TYPE_ALL }, + { "PACKET_CHARLOGIN_SET_ACCOUNT_ONLINE", sizeof(struct PACKET_CHARLOGIN_SET_ACCOUNT_ONLINE), SERVER_TYPE_ALL }, #else #define COMMON_CHARLOGINPACKETS_H #endif // COMMON_CHARLOGINPACKETS_H @@ -263,6 +264,8 @@ HPExport const struct s_HPMDataCheck HPMDataCheck[] = { { "PACKET_CHARMAP_AGENCY_JOIN_PARTY", sizeof(struct PACKET_CHARMAP_AGENCY_JOIN_PARTY), SERVER_TYPE_ALL }, { "PACKET_CHARMAP_GUILD_EMBLEM", sizeof(struct PACKET_CHARMAP_GUILD_EMBLEM), SERVER_TYPE_ALL }, { "PACKET_CHARMAP_GUILD_INFO", sizeof(struct PACKET_CHARMAP_GUILD_INFO), SERVER_TYPE_ALL }, + { "PACKET_CHARMAP_GUILD_INFO_EMBLEM", sizeof(struct PACKET_CHARMAP_GUILD_INFO_EMBLEM), SERVER_TYPE_ALL }, + { "PACKET_CHARMAP_GUILD_INFO_EMPTY", sizeof(struct PACKET_CHARMAP_GUILD_INFO_EMPTY), SERVER_TYPE_ALL }, #else #define COMMON_CHARMAPPACKETS_H #endif // COMMON_CHARMAPPACKETS_H @@ -327,6 +330,7 @@ HPExport const struct s_HPMDataCheck HPMDataCheck[] = { #endif // COMMON_HPMI_H #ifdef COMMON_MAPCHARPACKETS_H { "PACKET_MAPCHAR_AGENCY_JOIN_PARTY_REQ", sizeof(struct PACKET_MAPCHAR_AGENCY_JOIN_PARTY_REQ), SERVER_TYPE_ALL }, + { "PACKET_MAPCHAR_AUTH_REQ", sizeof(struct PACKET_MAPCHAR_AUTH_REQ), SERVER_TYPE_ALL }, { "PACKET_MAPCHAR_GUILD_EMBLEM", sizeof(struct PACKET_MAPCHAR_GUILD_EMBLEM), SERVER_TYPE_ALL }, #else #define COMMON_MAPCHARPACKETS_H diff --git a/src/common/charloginpackets.h b/src/common/charloginpackets.h index bdfda7c7d1f..4e22047840f 100644 --- a/src/common/charloginpackets.h +++ b/src/common/charloginpackets.h @@ -24,12 +24,20 @@ // Packets sent by Char-Server to Login-Server #include "common/hercules.h" +#include "common/packetsmacro.h" /* 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 +struct PACKET_CHARLOGIN_SET_ACCOUNT_ONLINE { + int16 packetType; + int account_id; + uint8 standalone; // 0 - real player (false) / 1 - standalone/server generated (true) +} __attribute__((packed)); +DEFINE_PACKET_ID(CHARLOGIN_SET_ACCOUNT_ONLINE, 0x272b) + struct PACKET_CHARLOGIN_ONLINE_ACCOUNTS { int16 packetType; uint16 packetLength; diff --git a/src/common/charmappackets.h b/src/common/charmappackets.h index 16b0de4650d..1166bb6d7f3 100644 --- a/src/common/charmappackets.h +++ b/src/common/charmappackets.h @@ -23,6 +23,7 @@ #define COMMON_CHARMAPPACKETS_H #include "common/hercules.h" +#include "common/packetsmacro.h" /* Packets Structs */ #if !defined(sun) && (!defined(__NETBSD__) || __NetBSD_Version__ >= 600000000) // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute diff --git a/src/common/mapcharpackets.h b/src/common/mapcharpackets.h index 4f4b5ac5512..fe997208ecd 100644 --- a/src/common/mapcharpackets.h +++ b/src/common/mapcharpackets.h @@ -23,12 +23,24 @@ #define COMMON_MAPCHARPACKETS_H #include "common/hercules.h" +#include "common/packetsmacro.h" /* 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 +struct PACKET_MAPCHAR_AUTH_REQ { + int16 packetType; + int account_id; + int char_id; + int login_id1; + uint8 sex; + int client_addr; + uint8 standalone; // 0 - real player (false) / 1 - standalone/server generated (true) +} __attribute__((packed)); +DEFINE_PACKET_ID(MAPCHAR_AUTH_REQ, 0x2b26) + struct PACKET_MAPCHAR_AGENCY_JOIN_PARTY_REQ { int16 packetType; int char_id; diff --git a/src/login/login.c b/src/login/login.c index 20ad72d7d33..206d01b07ac 100644 --- a/src/login/login.c +++ b/src/login/login.c @@ -663,9 +663,16 @@ static void login_fromchar_parse_unban(int fd, int id, const char *const ip) static void login_fromchar_parse_account_online(int fd, int id) { - login->add_online_user(id, RFIFOL(fd,2)); - lapiif->connect_user_char(id, RFIFOL(fd, 2)); - RFIFOSKIP(fd, 6); + const struct PACKET_CHARLOGIN_SET_ACCOUNT_ONLINE *p = RFIFOP(fd, 0); + + login->add_online_user(id, p->account_id); + + // "standalone" players (such as autotraders) does not exists in API server, so we should not send data about them + // or we will get errors from API server + if (p->standalone == 0) + lapiif->connect_user_char(id, p->account_id); + + RFIFOSKIP(fd, sizeof(*p)); } static void login_fromchar_parse_account_offline(int fd) @@ -939,8 +946,8 @@ static int login_parse_fromchar(int fd) } break; - case 0x272b: // Set account_id to online [Wizputer] - if( RFIFOREST(fd) < 6 ) + case HEADER_CHARLOGIN_SET_ACCOUNT_ONLINE: // Set account_id to online [Wizputer] + if (RFIFOREST(fd) < sizeof(struct PACKET_CHARLOGIN_SET_ACCOUNT_ONLINE)) return 0; login->fromchar_parse_account_online(fd, id); break; diff --git a/src/map/chrif.c b/src/map/chrif.c index caebf6981fb..d0f576b61f1 100644 --- a/src/map/chrif.c +++ b/src/map/chrif.c @@ -42,6 +42,7 @@ #include "common/HPM.h" #include "common/cbasetypes.h" #include "common/ers.h" +#include "common/mapcharpackets.h" #include "common/memmgr.h" #include "common/msgtable.h" #include "common/nullpo.h" @@ -470,15 +471,17 @@ static void chrif_authreq(struct map_session_data *sd, bool hstandalone) return; } - WFIFOHEAD(chrif->fd,20); - WFIFOW(chrif->fd,0) = 0x2b26; - WFIFOL(chrif->fd,2) = sd->status.account_id; - WFIFOL(chrif->fd,6) = sd->status.char_id; - WFIFOL(chrif->fd,10) = sd->login_id1; - WFIFOB(chrif->fd,14) = sd->status.sex; - WFIFOL(chrif->fd,15) = htonl(sockt->session[sd->fd]->client_addr); - WFIFOB(chrif->fd,19) = hstandalone ? 1 : 0; - WFIFOSET(chrif->fd,20); + WFIFOHEAD(chrif->fd, sizeof(struct PACKET_MAPCHAR_AUTH_REQ)); + struct PACKET_MAPCHAR_AUTH_REQ *p = WFIFOP(chrif->fd, 0); + p->packetType = HEADER_MAPCHAR_AUTH_REQ; + p->account_id = sd->status.account_id; + p->char_id = sd->status.char_id; + p->login_id1 = sd->login_id1; + p->sex = sd->status.sex; + p->client_addr = htonl(sockt->session[sd->fd]->client_addr); + p->standalone = hstandalone ? 1 : 0; + WFIFOSET(chrif->fd, sizeof(struct PACKET_MAPCHAR_AUTH_REQ)); + chrif->sd_to_auth(sd, ST_LOGIN); } diff --git a/src/map/packets_struct.h b/src/map/packets_struct.h index 698401d6da7..ddaaa7cb05e 100644 --- a/src/map/packets_struct.h +++ b/src/map/packets_struct.h @@ -26,6 +26,7 @@ #include "common/cbasetypes.h" #include "common/mmo.h" #include "common/packetsstatic_len.h" +#include "common/packetsmacro.h" // Packet DB #define MAX_PACKET_POS 20 diff --git a/src/plugins/HPMHooking/HPMHooking.Defs.inc b/src/plugins/HPMHooking/HPMHooking.Defs.inc index 7f45d7957fd..d61e0fc3c46 100644 --- a/src/plugins/HPMHooking/HPMHooking.Defs.inc +++ b/src/plugins/HPMHooking/HPMHooking.Defs.inc @@ -744,14 +744,14 @@ typedef int (*HPMHOOK_pre_chr_delete_char_sql) (int *char_id); typedef int (*HPMHOOK_post_chr_delete_char_sql) (int retVal___, int char_id); typedef struct DBData (*HPMHOOK_pre_chr_create_online_char_data) (union DBKey *key, va_list args); typedef struct DBData (*HPMHOOK_post_chr_create_online_char_data) (struct DBData retVal___, union DBKey key, va_list args); -typedef void (*HPMHOOK_pre_chr_set_account_online) (int *account_id); -typedef void (*HPMHOOK_post_chr_set_account_online) (int account_id); +typedef void (*HPMHOOK_pre_chr_set_account_online) (int *account_id, bool *standalone); +typedef void (*HPMHOOK_post_chr_set_account_online) (int account_id, bool standalone); typedef void (*HPMHOOK_pre_chr_set_account_offline) (int *account_id); typedef void (*HPMHOOK_post_chr_set_account_offline) (int account_id); typedef void (*HPMHOOK_pre_chr_set_char_charselect) (int *account_id); typedef void (*HPMHOOK_post_chr_set_char_charselect) (int account_id); -typedef void (*HPMHOOK_pre_chr_set_char_online) (bool *is_initializing, int *char_id, int *account_id); -typedef void (*HPMHOOK_post_chr_set_char_online) (bool is_initializing, int char_id, int account_id); +typedef void (*HPMHOOK_pre_chr_set_char_online) (bool *is_initializing, int *char_id, int *account_id, bool *standalone); +typedef void (*HPMHOOK_post_chr_set_char_online) (bool is_initializing, int char_id, int account_id, bool standalone); typedef void (*HPMHOOK_pre_chr_set_char_offline) (int *char_id, int *account_id); typedef void (*HPMHOOK_post_chr_set_char_offline) (int char_id, int account_id); typedef int (*HPMHOOK_pre_chr_db_setoffline) (union DBKey *key, struct DBData **data, va_list ap); diff --git a/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc index bf085d7fd66..b4b3b34645b 100644 --- a/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc +++ b/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc @@ -719,14 +719,14 @@ struct DBData HP_chr_create_online_char_data(union DBKey key, va_list args) { } return retVal___; } -void HP_chr_set_account_online(int account_id) { +void HP_chr_set_account_online(int account_id, bool standalone) { int hIndex = 0; if (HPMHooks.count.HP_chr_set_account_online_pre > 0) { - void (*preHookFunc) (int *account_id); + void (*preHookFunc) (int *account_id, bool *standalone); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_chr_set_account_online_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_chr_set_account_online_pre[hIndex].func; - preHookFunc(&account_id); + preHookFunc(&account_id, &standalone); } if (*HPMforce_return) { *HPMforce_return = false; @@ -734,13 +734,13 @@ void HP_chr_set_account_online(int account_id) { } } { - HPMHooks.source.chr.set_account_online(account_id); + HPMHooks.source.chr.set_account_online(account_id, standalone); } if (HPMHooks.count.HP_chr_set_account_online_post > 0) { - void (*postHookFunc) (int account_id); + void (*postHookFunc) (int account_id, bool standalone); for (hIndex = 0; hIndex < HPMHooks.count.HP_chr_set_account_online_post; hIndex++) { postHookFunc = HPMHooks.list.HP_chr_set_account_online_post[hIndex].func; - postHookFunc(account_id); + postHookFunc(account_id, standalone); } } return; @@ -797,14 +797,14 @@ void HP_chr_set_char_charselect(int account_id) { } return; } -void HP_chr_set_char_online(bool is_initializing, int char_id, int account_id) { +void HP_chr_set_char_online(bool is_initializing, int char_id, int account_id, bool standalone) { int hIndex = 0; if (HPMHooks.count.HP_chr_set_char_online_pre > 0) { - void (*preHookFunc) (bool *is_initializing, int *char_id, int *account_id); + void (*preHookFunc) (bool *is_initializing, int *char_id, int *account_id, bool *standalone); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_chr_set_char_online_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_chr_set_char_online_pre[hIndex].func; - preHookFunc(&is_initializing, &char_id, &account_id); + preHookFunc(&is_initializing, &char_id, &account_id, &standalone); } if (*HPMforce_return) { *HPMforce_return = false; @@ -812,13 +812,13 @@ void HP_chr_set_char_online(bool is_initializing, int char_id, int account_id) { } } { - HPMHooks.source.chr.set_char_online(is_initializing, char_id, account_id); + HPMHooks.source.chr.set_char_online(is_initializing, char_id, account_id, standalone); } if (HPMHooks.count.HP_chr_set_char_online_post > 0) { - void (*postHookFunc) (bool is_initializing, int char_id, int account_id); + void (*postHookFunc) (bool is_initializing, int char_id, int account_id, bool standalone); for (hIndex = 0; hIndex < HPMHooks.count.HP_chr_set_char_online_post; hIndex++) { postHookFunc = HPMHooks.list.HP_chr_set_char_online_post[hIndex].func; - postHookFunc(is_initializing, char_id, account_id); + postHookFunc(is_initializing, char_id, account_id, standalone); } } return;