From da6769f929be02a0b3b4d6c52b79922104cdd053 Mon Sep 17 00:00:00 2001 From: Ben Longbons Date: Mon, 23 Jun 2014 20:40:46 -0700 Subject: Use the generated char server protocol in the map server --- src/admin/ladmin.cpp | 6 + src/char/char.cpp | 14 +- src/login/login.cpp | 3 +- src/map/chrif.cpp | 525 +++++++++++++++++++++++++++++---------------------- src/map/intif.cpp | 511 +++++++++++++++++++++++++------------------------ src/map/intif.hpp | 2 +- src/map/pc.cpp | 14 +- src/map/pc.hpp | 4 +- src/net/packets.hpp | 2 +- 9 files changed, 597 insertions(+), 484 deletions(-) (limited to 'src') diff --git a/src/admin/ladmin.cpp b/src/admin/ladmin.cpp index 7b702ed..ba55d73 100644 --- a/src/admin/ladmin.cpp +++ b/src/admin/ladmin.cpp @@ -2815,6 +2815,12 @@ void parse_fromlogin(Session *s) } } + if (rv == RecvResult::Error) + { + s->set_eof(); + return; + } + // The following was almost certainly wrong and only worked because // localhost is a fast enough network to never split byte 1 vs byte 2 diff --git a/src/char/char.cpp b/src/char/char.cpp index 33ee2b9..7bc17ba 100644 --- a/src/char/char.cpp +++ b/src/char/char.cpp @@ -1188,13 +1188,7 @@ int char_delete(CharPair *cp) static void parse_tologin(Session *ls) { - // only login-server can have an access to here. - // so, if it isn't the login-server, we disconnect the session (fd != login_fd). - if (ls != login_session) - { - ls->set_eof(); - return; - } + assert (ls == login_session); char_session_data *sd = static_cast(ls->session_data.get()); @@ -1665,6 +1659,8 @@ void parse_tologin(Session *ls) } } } + if (rv == RecvResult::Error) + ls->set_eof(); } //-------------------------------- @@ -2281,6 +2277,8 @@ void parse_frommap(Session *ms) } } } + if (rv == RecvResult::Error) + ms->set_eof(); } static @@ -2770,6 +2768,8 @@ void parse_char(Session *s) return; } } + if (rv == RecvResult::Error) + s->set_eof(); } static diff --git a/src/login/login.cpp b/src/login/login.cpp index 6edaeef..7537927 100644 --- a/src/login/login.cpp +++ b/src/login/login.cpp @@ -3245,7 +3245,8 @@ void parse_login(Session *s) } } } - return; + if (rv == RecvResult::Error) + s->set_eof(); } //---------------------------------- diff --git a/src/map/chrif.cpp b/src/map/chrif.cpp index a6c11b9..2998516 100644 --- a/src/map/chrif.cpp +++ b/src/map/chrif.cpp @@ -29,9 +29,11 @@ #include "../io/cxxstdio.hpp" #include "../net/ip.hpp" +#include "../net/packets.hpp" #include "../net/socket.hpp" #include "../net/timer.hpp" -#include "../net/vomit.hpp" + +#include "../proto2/char-map.hpp" #include "../mmo/human_time_diff.hpp" #include "../mmo/mmo.hpp" @@ -48,14 +50,6 @@ #include "../poison.hpp" -static -const int packet_len_table[0x20] = -{ - 60, 3, 10, 27, 22, -1, 6, -1, // 2af8-2aff - 6, -1, 18, 7, -1, 49, 44, 0, // 2b00-2b07 - 6, 30, -1, 10, 86, 7, 44, 34, // 2b08-2b0f - -1, -1, 10, 6, 11, -1, 0, 0, // 2b10-2b17 -}; Session *char_session; static @@ -133,13 +127,12 @@ int chrif_save(dumb_ptr sd) pc_makesavestatus(sd); - WFIFOW(char_session, 0) = 0x2b01; - WFIFOW(char_session, 2) = sizeof(sd->status_key) + sizeof(sd->status) + 12; - WFIFOL(char_session, 4) = unwrap(sd->bl_id); - WFIFOL(char_session, 8) = unwrap(sd->char_id_); - WFIFO_STRUCT(char_session, 12, sd->status_key); - WFIFO_STRUCT(char_session, 12 + sizeof(sd->status_key), sd->status); - WFIFOSET(char_session, WFIFOW(char_session, 2)); + Packet_Payload<0x2b01> payload_01; + payload_01.account_id = block_to_account(sd->bl_id); + payload_01.char_id = sd->char_id_; + payload_01.char_key = sd->status_key; + payload_01.char_data = sd->status; + send_ppacket<0x2b01>(char_session, payload_01); //For data sync if (sd->state.storage_open) @@ -155,13 +148,13 @@ int chrif_save(dumb_ptr sd) static int chrif_connect(Session *s) { - WFIFOW(s, 0) = 0x2af8; - WFIFO_STRING(s, 2, userid, 24); - WFIFO_STRING(s, 26, passwd, 24); - WFIFOL(s, 50) = 0; - WFIFOIP(s, 54) = clif_getip(); - WFIFOW(s, 58) = clif_getport(); // [Valaris] thanks to fov - WFIFOSET(s, 60); + Packet_Fixed<0x2af8> fixed_f8; + fixed_f8.account_name = userid; + fixed_f8.account_pass = passwd; + fixed_f8.unused = 0; + fixed_f8.ip = clif_getip(); + fixed_f8.port = clif_getport(); + send_fpacket<0x2af8, 60>(s, fixed_f8); return 0; } @@ -173,19 +166,17 @@ int chrif_connect(Session *s) static int chrif_sendmap(Session *s) { - int i = 0; - - WFIFOW(s, 0) = 0x2afa; + std::vector> repeat_fa; for (auto& pair : maps_db) { map_abstract *ma = pair.second.get(); if (!ma->gat) continue; - WFIFO_STRING(s, 4 + i * 16, ma->name_, 16); - i++; + Packet_Repeat<0x2afa> info; + info.map_name = ma->name_; + repeat_fa.push_back(info); } - WFIFOW(s, 2) = 4 + i * 16; - WFIFOSET(s, WFIFOW(s, 2)); + send_packet_repeatonly<0x2afa, 4, 16>(s, repeat_fa); return 0; } @@ -195,23 +186,21 @@ int chrif_sendmap(Session *s) *------------------------------------------ */ static -int chrif_recvmap(Session *s) +int chrif_recvmap(Session *, Packet_Head<0x2b04> head, const std::vector>& repeat) { - int i, j; - if (chrif_state < 2) // まだ準備中 return -1; - IP4Address ip = RFIFOIP(s, 4); - uint16_t port = RFIFOW(s, 8); - for (i = 10, j = 0; i < RFIFOW(s, 2); i += 16, j++) + IP4Address ip = head.ip; + uint16_t port = head.port; + for (const Packet_Repeat<0x2b04>& i : repeat) { - MapName map = RFIFO_STRING<16>(s, i); + MapName map = i.map_name; map_setipport(map, ip, port); } if (battle_config.etc_log) - PRINTF("recv map on %s:%d (%d maps)\n"_fmt, - ip, port, j); + PRINTF("recv map on %s:%d (%zu maps)\n"_fmt, + ip, port, repeat.size()); return 0; } @@ -239,19 +228,19 @@ int chrif_changemapserver(dumb_ptr sd, } } - WFIFOW(char_session, 0) = 0x2b05; - WFIFOL(char_session, 2) = unwrap(sd->bl_id); - WFIFOL(char_session, 6) = sd->login_id1; - WFIFOL(char_session, 10) = sd->login_id2; - WFIFOL(char_session, 14) = unwrap(sd->status_key.char_id); - WFIFO_STRING(char_session, 18, name, 16); - WFIFOW(char_session, 34) = x; - WFIFOW(char_session, 36) = y; - WFIFOIP(char_session, 38) = ip; - WFIFOL(char_session, 42) = port; - WFIFOB(char_session, 44) = static_cast(sd->status.sex); - WFIFOIP(char_session, 45) = s_ip; - WFIFOSET(char_session, 49); + Packet_Fixed<0x2b05> fixed_05; + fixed_05.account_id = block_to_account(sd->bl_id); + fixed_05.login_id1 = sd->login_id1; + fixed_05.login_id2 = sd->login_id2; + fixed_05.char_id = sd->status_key.char_id; + fixed_05.map_name = name; + fixed_05.x = x; + fixed_05.y = y; + fixed_05.map_ip = ip; + fixed_05.map_port = port; + fixed_05.sex = sd->status.sex; + fixed_05.client_ip = s_ip; + send_fpacket<0x2b05, 49>(char_session, fixed_05); return 0; } @@ -261,26 +250,26 @@ int chrif_changemapserver(dumb_ptr sd, *------------------------------------------ */ static -int chrif_changemapserverack(Session *s) +int chrif_changemapserverack(Session *, const Packet_Fixed<0x2b06>& fixed) { - dumb_ptr sd = map_id2sd(account_to_block(wrap(RFIFOL(s, 2)))); + dumb_ptr sd = map_id2sd(account_to_block(fixed.account_id)); - if (sd == NULL || sd->status_key.char_id != wrap(RFIFOL(s, 14))) + if (sd == NULL || sd->status_key.char_id != fixed.char_id) return -1; // I am fairly certain that this is not possible - if (RFIFOL(s, 6) == 1) + if (fixed.error == 1) { if (battle_config.error_log) PRINTF("map server change failed.\n"_fmt); pc_authfail(sd->status_key.account_id); return 0; } - MapName mapname = RFIFO_STRING<16>(s, 18); - uint16_t x = RFIFOW(s, 34); - uint16_t y = RFIFOW(s, 36); - IP4Address ip = RFIFOIP(s, 38); - uint16_t port = RFIFOW(s, 42); + MapName mapname = fixed.map_name; + uint16_t x = fixed.x; + uint16_t y = fixed.y; + IP4Address ip = fixed.map_ip; + uint16_t port = fixed.map_port; clif_changemapserver(sd, mapname, x, y, ip, port); return 0; @@ -291,11 +280,11 @@ int chrif_changemapserverack(Session *s) *------------------------------------------ */ static -int chrif_connectack(Session *s) +int chrif_connectack(Session *s, const Packet_Fixed<0x2af9>& fixed) { - if (RFIFOB(s, 2)) + if (fixed.code) { - PRINTF("Connected to char-server failed %d.\n"_fmt, RFIFOB(s, 2)); + PRINTF("Connected to char-server failed %d.\n"_fmt, fixed.code); exit(1); } PRINTF("Connected to char-server (connection #%d).\n"_fmt, s); @@ -316,16 +305,16 @@ int chrif_connectack(Session *s) *------------------------------------------ */ static -int chrif_sendmapack(Session *s) +int chrif_sendmapack(Session *, Packet_Fixed<0x2afb> fixed) { - if (RFIFOB(s, 2)) + if (fixed.unknown) //impossible { PRINTF("chrif : send map list to char server failed %d\n"_fmt, - RFIFOB(s, 2)); + fixed.unknown); exit(1); } - wisp_server_name = stringish(RFIFO_STRING<24>(s, 3)); + wisp_server_name = fixed.whisper_name; chrif_state = 2; @@ -351,13 +340,13 @@ int chrif_authreq(dumb_ptr sd) if (dumb_ptr(static_cast(s->session_data.get())) == sd) { assert (s == sd->sess); - WFIFOW(char_session, 0) = 0x2afc; - WFIFOL(char_session, 2) = unwrap(sd->bl_id); - WFIFOL(char_session, 6) = unwrap(sd->char_id_); - WFIFOL(char_session, 10) = sd->login_id1; - WFIFOL(char_session, 14) = sd->login_id2; - WFIFOIP(char_session, 18) = s->client_ip; - WFIFOSET(char_session, 22); + Packet_Fixed<0x2afc> fixed_fc; + fixed_fc.account_id = block_to_account(sd->bl_id); + fixed_fc.char_id = sd->char_id_; + fixed_fc.login_id1 = sd->login_id1; + fixed_fc.login_id2 = sd->login_id2; + fixed_fc.ip = s->client_ip; + send_fpacket<0x2afc, 22>(char_session, fixed_fc); break; } } @@ -390,12 +379,12 @@ int chrif_charselectreq(dumb_ptr sd) } } - WFIFOW(char_session, 0) = 0x2b02; - WFIFOL(char_session, 2) = unwrap(sd->bl_id); - WFIFOL(char_session, 6) = sd->login_id1; - WFIFOL(char_session, 10) = sd->login_id2; - WFIFOIP(char_session, 14) = s_ip; - WFIFOSET(char_session, 18); + Packet_Fixed<0x2b02> fixed_02; + fixed_02.account_id = block_to_account(sd->bl_id); + fixed_02.login_id1 = sd->login_id1; + fixed_02.login_id2 = sd->login_id2; + fixed_02.ip = s_ip; + send_fpacket<0x2b02, 18>(char_session, fixed_02); return 0; } @@ -409,12 +398,9 @@ void chrif_changegm(AccountId id, ZString pass) if (battle_config.etc_log) PRINTF("chrif_changegm: account: %d, password: '%s'.\n"_fmt, id, pass); - size_t len = pass.size() + 1; - WFIFOW(char_session, 0) = 0x2b0a; - WFIFOW(char_session, 2) = len + 8; - WFIFOL(char_session, 4) = unwrap(id); - WFIFO_STRING(char_session, 8, pass, len); - WFIFOSET(char_session, len + 8); + Packet_Head<0x2b0a> head_0a; + head_0a.account_id = id; + send_vpacket<0x2b0a, 8, 1>(char_session, head_0a, pass); } /*========================================== @@ -428,11 +414,11 @@ void chrif_changeemail(AccountId id, AccountEmail actual_email, PRINTF("chrif_changeemail: account: %d, actual_email: '%s', new_email: '%s'.\n"_fmt, id, actual_email, new_email); - WFIFOW(char_session, 0) = 0x2b0c; - WFIFOL(char_session, 2) = unwrap(id); - WFIFO_STRING(char_session, 6, actual_email, 40); - WFIFO_STRING(char_session, 46, new_email, 40); - WFIFOSET(char_session, 86); + Packet_Fixed<0x2b0c> fixed_0c; + fixed_0c.account_id = id; + fixed_0c.old_email = actual_email; + fixed_0c.new_email = new_email; + send_fpacket<0x2b0c, 86>(char_session, fixed_0c); } /*========================================== @@ -449,14 +435,14 @@ void chrif_changeemail(AccountId id, AccountEmail actual_email, void chrif_char_ask_name(AccountId id, CharName character_name, short operation_type, HumanTimeDiff modif) { - WFIFOW(char_session, 0) = 0x2b0e; - WFIFOL(char_session, 2) = unwrap(id); // account_id of who ask (for answer) -1 if nobody - WFIFO_STRING(char_session, 6, character_name.to__actual(), 24); - WFIFOW(char_session, 30) = operation_type; // type of operation + Packet_Fixed<0x2b0e> fixed_0e; + fixed_0e.account_id = id; // who ask, or nobody + fixed_0e.char_name = character_name; + fixed_0e.operation = operation_type; // type of operation if (operation_type == 2) - WFIFO_STRUCT(char_session, 32, modif); + fixed_0e.ban_add = modif; PRINTF("chrif : sended 0x2b0e\n"_fmt); - WFIFOSET(char_session, 44); + send_fpacket<0x2b0e, 44>(char_session, fixed_0e); } /*========================================== @@ -476,24 +462,24 @@ void chrif_char_ask_name(AccountId id, CharName character_name, short operation_ *------------------------------------------ */ static -int chrif_char_ask_name_answer(Session *s) +int chrif_char_ask_name_answer(Session *, const Packet_Fixed<0x2b0f>& fixed) { - AccountId acc = wrap(RFIFOL(s, 2)); // account_id of who has asked (-1 if nobody) - CharName player_name = stringish(RFIFO_STRING<24>(s, 6)); + AccountId acc = fixed.account_id; // who asked, or nobody + CharName player_name = fixed.char_name; dumb_ptr sd = map_id2sd(account_to_block(acc)); if (acc && sd != NULL) { AString output; - if (RFIFOW(s, 32) == 1) // player not found + if (fixed.error == 1) // player not found output = STRPRINTF("The player '%s' doesn't exist."_fmt, player_name); else { - switch (RFIFOW(s, 30)) + switch (fixed.operation) { case 1: // block - switch (RFIFOW(s, 32)) + switch (fixed.error) { case 0: // login-server resquest done output = STRPRINTF( @@ -514,7 +500,7 @@ int chrif_char_ask_name_answer(Session *s) } break; case 2: // ban - switch (RFIFOW(s, 32)) + switch (fixed.error) { case 0: // login-server resquest done output = STRPRINTF( @@ -535,7 +521,7 @@ int chrif_char_ask_name_answer(Session *s) } break; case 3: // unblock - switch (RFIFOW(s, 32)) + switch (fixed.error) { case 0: // login-server resquest done output = STRPRINTF( @@ -556,7 +542,7 @@ int chrif_char_ask_name_answer(Session *s) } break; case 4: // unban - switch (RFIFOW(s, 32)) + switch (fixed.error) { case 0: // login-server resquest done output = STRPRINTF( @@ -577,7 +563,7 @@ int chrif_char_ask_name_answer(Session *s) } break; case 5: // changesex - switch (RFIFOW(s, 32)) + switch (fixed.error) { case 0: // login-server resquest done output = STRPRINTF( @@ -613,10 +599,10 @@ int chrif_char_ask_name_answer(Session *s) *------------------------------------------ */ static -void chrif_changedgm(Session *s) +void chrif_changedgm(Session *, const Packet_Fixed<0x2b0b>& fixed) { - AccountId acc = wrap(RFIFOL(s, 2)); - GmLevel level = GmLevel::from(RFIFOL(s, 6)); + AccountId acc = fixed.account_id; + GmLevel level = fixed.gm_level; dumb_ptr sd = map_id2sd(account_to_block(acc)); @@ -637,13 +623,13 @@ void chrif_changedgm(Session *s) *------------------------------------------ */ static -void chrif_changedsex(Session *s) +void chrif_changedsex(Session *, const Packet_Fixed<0x2b0d>& fixed) { int i; dumb_ptr sd; - AccountId acc = wrap(RFIFOL(s, 2)); - SEX sex = static_cast(RFIFOB(s, 6)); + AccountId acc = fixed.account_id; + SEX sex = fixed.sex; if (battle_config.etc_log) PRINTF("chrif_changedsex %d.\n"_fmt, acc); sd = map_id2sd(account_to_block(acc)); @@ -686,24 +672,24 @@ void chrif_changedsex(Session *s) */ int chrif_saveaccountreg2(dumb_ptr sd) { - int p, j; nullpo_retr(-1, sd); - p = 8; - for (j = 0; j < sd->status.account_reg2_num; j++) + std::vector> repeat_10; + for (size_t j = 0; j < sd->status.account_reg2_num; j++) { struct global_reg *reg = &sd->status.account_reg2[j]; if (reg->str && reg->value != 0) { - WFIFO_STRING(char_session, p, reg->str, 32); - WFIFOL(char_session, p + 32) = reg->value; - p += 36; + Packet_Repeat<0x2b10> info; + info.name = reg->str; + info.value = reg->value; + repeat_10.push_back(info); } } - WFIFOW(char_session, 0) = 0x2b10; - WFIFOW(char_session, 2) = p; - WFIFOL(char_session, 4) = unwrap(sd->bl_id); - WFIFOSET(char_session, p); + + Packet_Head<0x2b10> head_10; + head_10.account_id = block_to_account(sd->bl_id); + send_vpacket<0x2b10, 8, 36>(char_session, head_10, repeat_10); return 0; } @@ -713,20 +699,19 @@ int chrif_saveaccountreg2(dumb_ptr sd) *------------------------------------------ */ static -int chrif_accountreg2(Session *s) +int chrif_accountreg2(Session *, const Packet_Head<0x2b11>& head, const std::vector>& repeat) { - int j, p; - dumb_ptr sd = map_id2sd(account_to_block(wrap(RFIFOL(s, 4)))); + dumb_ptr sd = map_id2sd(account_to_block(head.account_id)); if (sd == NULL) return 1; - for (p = 8, j = 0; p < RFIFOW(s, 2) && j < ACCOUNT_REG2_NUM; - p += 36, j++) + size_t jlim = std::min(ACCOUNT_REG2_NUM, repeat.size()); + for (size_t j = 0; j < jlim; j++) { - sd->status.account_reg2[j].str = stringish(RFIFO_STRING<32>(s, p)); - sd->status.account_reg2[j].value = RFIFOL(s, p + 32); + sd->status.account_reg2[j].str = repeat[j].name; + sd->status.account_reg2[j].value = repeat[j].value; } - sd->status.account_reg2_num = j; + sd->status.account_reg2_num = jlim; return 0; } @@ -775,9 +760,9 @@ int chrif_send_divorce(CharId char_id) if (!char_session) return -1; - WFIFOW(char_session, 0) = 0x2b16; - WFIFOL(char_session, 2) = unwrap(char_id); - WFIFOSET(char_session, 6); + Packet_Fixed<0x2b16> fixed_16; + fixed_16.char_id = char_id; + send_fpacket<0x2b16, 6>(char_session, fixed_16); return 0; } @@ -786,11 +771,11 @@ int chrif_send_divorce(CharId char_id) *------------------------------------------ */ static -int chrif_accountdeletion(Session *s) +int chrif_accountdeletion(Session *, const Packet_Fixed<0x2b13>& fixed) { dumb_ptr sd; - AccountId acc = wrap(RFIFOL(s, 2)); + AccountId acc = fixed.account_id; if (battle_config.etc_log) PRINTF("chrif_accountdeletion %d.\n"_fmt, acc); sd = map_id2sd(account_to_block(acc)); @@ -818,11 +803,11 @@ int chrif_accountdeletion(Session *s) *------------------------------------------ */ static -int chrif_accountban(Session *s) +int chrif_accountban(Session *, const Packet_Fixed<0x2b14>& fixed) { dumb_ptr sd; - AccountId acc = wrap(RFIFOL(s, 2)); + AccountId acc = fixed.account_id; if (battle_config.etc_log) PRINTF("chrif_accountban %d.\n"_fmt, acc); sd = map_id2sd(account_to_block(acc)); @@ -831,9 +816,9 @@ int chrif_accountban(Session *s) if (sd != NULL) { sd->login_id1++; // change identify, because if player come back in char within the 5 seconds, he can change its characters - if (RFIFOB(s, 6) == 0) + if (fixed.ban_not_status == 0) { // 0: change of statut, 1: ban - switch (RFIFOL(s, 7)) + switch (static_cast(fixed.status_or_ban_until)) { // status or final date of a banishment case 1: // 0 = Unregistered ID clif_displaymessage(sd->sess, @@ -881,10 +866,10 @@ int chrif_accountban(Session *s) break; } } - else if (RFIFOB(s, 6) == 1) + else if (fixed.ban_not_status == 1) { // 0: change of statut, 1: ban - const TimeT timestamp = static_cast(RFIFOL(s, 7)); // status or final date of a banishment + const TimeT timestamp = fixed.status_or_ban_until; // status or final date of a banishment timestamp_seconds_buffer buffer; stamp_time(buffer, ×tamp); AString tmpstr = STRPRINTF("Your account has been banished until %s"_fmt, buffer); @@ -907,10 +892,10 @@ int chrif_accountban(Session *s) *------------------------------------------ */ static -int chrif_recvgmaccounts(Session *s) +int chrif_recvgmaccounts(Session *s, const std::vector>& repeat) { PRINTF("From login-server: receiving of %d GM accounts information.\n"_fmt, - pc_read_gm_account(s)); + pc_read_gm_account(s, repeat)); return 0; } @@ -921,9 +906,8 @@ int chrif_recvgmaccounts(Session *s) */ int chrif_reloadGMdb(void) { - - WFIFOW(char_session, 0) = 0x2af7; - WFIFOSET(char_session, 2); + Packet_Fixed<0x2af7> fixed_f7; + send_fpacket<0x2af7, 2>(char_session, fixed_f7); return 0; } @@ -1014,10 +998,10 @@ void ladmin_itemfrob_c(dumb_ptr bl, ItemNameId source_id, ItemNameId } static -void ladmin_itemfrob(Session *s) +void ladmin_itemfrob(Session *, const Packet_Fixed<0x2afa>& fixed) { - ItemNameId source_id = wrap(static_cast(RFIFOL(s, 2))); - ItemNameId dest_id = wrap(static_cast(RFIFOL(s, 6))); + ItemNameId source_id = fixed.source_item_id; + ItemNameId dest_id = fixed.dest_item_id; dumb_ptr bl = map_get_first_session(); // flooritems @@ -1048,121 +1032,213 @@ void chrif_delete(Session *s) static void chrif_parse(Session *s) { - int packet_len, cmd; - - // only char-server can have an access to here. - // so, if it isn't the char-server, we disconnect the session (fd != char_fd). - if (s != char_session) - { - s->set_eof(); - return; - } + assert (s == char_session); - while (RFIFOREST(s) >= 2) + RecvResult rv = RecvResult::Complete; + uint16_t packet_id; + while (rv == RecvResult::Complete && packet_peek_id(s, &packet_id)) { - cmd = RFIFOW(s, 0); - if (cmd < 0x2af8 - || cmd >= - 0x2af8 + - (sizeof(packet_len_table) / sizeof(packet_len_table[0])) - || packet_len_table[cmd - 0x2af8] == 0) - { - - int r = intif_parse(s); // intifに渡す - - if (r == 1) - continue; // intifで処理した - if (r == 2) - return; // intifで処理したが、データが足りない - - s->set_eof(); - return; - } - packet_len = packet_len_table[cmd - 0x2af8]; - if (packet_len == -1) - { - if (RFIFOREST(s) < 4) - return; - packet_len = RFIFOW(s, 2); - } - if (RFIFOREST(s) < packet_len) - return; - - switch (cmd) + switch (packet_id) { case 0x2af9: - chrif_connectack(s); + { + Packet_Fixed<0x2af9> fixed; + rv = recv_fpacket<0x2af9, 3>(s, fixed); + if (rv != RecvResult::Complete) + break; + + chrif_connectack(s, fixed); break; + } case 0x2afa: - ladmin_itemfrob(s); + { + Packet_Fixed<0x2afa> fixed; + rv = recv_fpacket<0x2afa, 10>(s, fixed); + if (rv != RecvResult::Complete) + break; + + ladmin_itemfrob(s, fixed); break; + } case 0x2afb: - chrif_sendmapack(s); + { + Packet_Fixed<0x2afb> fixed; + rv = recv_fpacket<0x2afb, 27>(s, fixed); + if (rv != RecvResult::Complete) + break; + + chrif_sendmapack(s, fixed); break; + } case 0x2afd: { - AccountId id = wrap(RFIFOL(s, 4)); - int login_id2 = RFIFOL(s, 8); - TimeT connect_until_time = static_cast(RFIFOL(s, 12)); - short tmw_version = RFIFOW(s, 16); - CharKey st_key; - CharData st_data; - RFIFO_STRUCT(s, 18, st_key); - RFIFO_STRUCT(s, 18 + sizeof(st_key), st_data); + Packet_Payload<0x2afd> payload; + rv = recv_ppacket<0x2afd>(s, payload); + if (rv != RecvResult::Complete) + break; + + AccountId id = payload.account_id; + int login_id2 = payload.login_id2; + TimeT connect_until_time = payload.connect_until; + short tmw_version = payload.packet_tmw_version; + CharKey st_key = payload.char_key; + CharData st_data = payload.char_data; pc_authok(id, login_id2, connect_until_time, tmw_version, &st_key, &st_data); - } break; + } case 0x2afe: - pc_authfail(wrap(RFIFOL(s, 2))); + { + Packet_Fixed<0x2afe> fixed; + rv = recv_fpacket<0x2afe, 6>(s, fixed); + if (rv != RecvResult::Complete) + break; + + pc_authfail(fixed.account_id); break; + } case 0x2b00: - map_setusers(RFIFOL(s, 2)); + { + Packet_Fixed<0x2b00> fixed; + rv = recv_fpacket<0x2b00, 6>(s, fixed); + if (rv != RecvResult::Complete) + break; + + map_setusers(fixed.users); break; + } case 0x2b03: - clif_charselectok(wrap(RFIFOL(s, 2))); + { + Packet_Fixed<0x2b03> fixed; + rv = recv_fpacket<0x2b03, 7>(s, fixed); + if (rv != RecvResult::Complete) + break; + + clif_charselectok(account_to_block(fixed.account_id)); break; + } case 0x2b04: - chrif_recvmap(s); + { + Packet_Head<0x2b04> head; + std::vector> repeat; + rv = recv_vpacket<0x2b04, 10, 16>(s, head, repeat); + if (rv != RecvResult::Complete) + break; + + chrif_recvmap(s, head, repeat); break; + } case 0x2b06: - chrif_changemapserverack(s); + { + Packet_Fixed<0x2b06> fixed; + rv = recv_fpacket<0x2b06, 44>(s, fixed); + if (rv != RecvResult::Complete) + break; + + chrif_changemapserverack(s, fixed); break; + } case 0x2b0b: - chrif_changedgm(s); + { + Packet_Fixed<0x2b0b> fixed; + rv = recv_fpacket<0x2b0b, 10>(s, fixed); + if (rv != RecvResult::Complete) + break; + + chrif_changedgm(s, fixed); break; + } case 0x2b0d: - chrif_changedsex(s); + { + Packet_Fixed<0x2b0d> fixed; + rv = recv_fpacket<0x2b0d, 7>(s, fixed); + if (rv != RecvResult::Complete) + break; + + chrif_changedsex(s, fixed); break; + } case 0x2b0f: - chrif_char_ask_name_answer(s); + { + Packet_Fixed<0x2b0f> fixed; + rv = recv_fpacket<0x2b0f, 34>(s, fixed); + if (rv != RecvResult::Complete) + break; + + chrif_char_ask_name_answer(s, fixed); break; + } case 0x2b11: - chrif_accountreg2(s); + { + Packet_Head<0x2b11> head; + std::vector> repeat; + rv = recv_vpacket<0x2b11, 8, 36>(s, head, repeat); + if (rv != RecvResult::Complete) + break; + + chrif_accountreg2(s, head, repeat); break; + } case 0x2b12: - chrif_divorce(wrap(RFIFOL(s, 2)), wrap(RFIFOL(s, 6))); + { + Packet_Fixed<0x2b12> fixed; + rv = recv_fpacket<0x2b12, 10>(s, fixed); + if (rv != RecvResult::Complete) + break; + + chrif_divorce(fixed.char_id, fixed.partner_id); break; + } case 0x2b13: - chrif_accountdeletion(s); + { + Packet_Fixed<0x2b13> fixed; + rv = recv_fpacket<0x2b13, 6>(s, fixed); + if (rv != RecvResult::Complete) + break; + + chrif_accountdeletion(s, fixed); break; + } case 0x2b14: - chrif_accountban(s); + { + Packet_Fixed<0x2b14> fixed; + rv = recv_fpacket<0x2b14, 11>(s, fixed); + if (rv != RecvResult::Complete) + break; + + chrif_accountban(s, fixed); break; + } case 0x2b15: - chrif_recvgmaccounts(s); - break; + { + std::vector> repeat; + rv = recv_packet_repeatonly<0x2b15, 4, 5>(s, repeat); + if (rv != RecvResult::Complete) + break; + chrif_recvgmaccounts(s, repeat); + break; + } default: + { + RecvResult r = intif_parse(s, packet_id); + + if (r == RecvResult::Complete) + break; + if (r == RecvResult::Incomplete) + return; + if (battle_config.error_log) PRINTF("chrif_parse : unknown packet %d %d\n"_fmt, s, - RFIFOW(s, 0)); + packet_id); s->set_eof(); return; + } } - RFIFOSKIP(s, packet_len); } + if (rv == RecvResult::Error) + s->set_eof(); } /*========================================== @@ -1178,7 +1254,8 @@ void send_users_tochar(TimerData *, tick_t) if (!char_session) return; - WFIFOW(char_session, 0) = 0x2aff; + Packet_Head<0x2aff> head_ff; + std::vector> repeat_ff; for (io::FD i : iter_fds()) { Session *s = get_session(i); @@ -1190,13 +1267,13 @@ void send_users_tochar(TimerData *, tick_t) || sd->state.shroud_active || bool(sd->status.option & Option::HIDE)) && pc_isGM(sd))) { - WFIFOL(char_session, 6 + 4 * users) = unwrap(sd->status_key.char_id); - users++; + Packet_Repeat<0x2aff> info; + info.char_id = sd->status_key.char_id; + repeat_ff.push_back(info); } } - WFIFOW(char_session, 2) = 6 + 4 * users; - WFIFOW(char_session, 4) = users; - WFIFOSET(char_session, 6 + 4 * users); + head_ff.users = users; + send_vpacket<0x2aff, 6, 4>(char_session, head_ff, repeat_ff); } /*========================================== diff --git a/src/map/intif.cpp b/src/map/intif.cpp index bb4b893..3ca2130 100644 --- a/src/map/intif.cpp +++ b/src/map/intif.cpp @@ -29,11 +29,13 @@ #include "../io/cxxstdio.hpp" +#include "../net/packets.hpp" #include "../net/socket.hpp" -#include "../net/vomit.hpp" #include "../mmo/mmo.hpp" +#include "../proto2/char-map.hpp" + #include "battle.hpp" #include "chrif.hpp" #include "clif.hpp" @@ -44,20 +46,6 @@ #include "../poison.hpp" -static -const int packet_len_table[] = -{ - -1, -1, 27, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -1, 7, 0, 0, 0, 0, 0, 0, -1, 11, 0, 0, 0, 0, 0, 0, - 35, -1, 11, 15, 34, 29, 7, -1, 0, 0, 0, 0, 0, 0, 0, 0, - 10, -1, 15, 0, 79, 19, 7, -1, 0, -1, -1, -1, 14, 67, 186, -1, - 9, 9, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 11, -1, 7, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - //----------------------------------------------------------------- // inter serverへの送信 @@ -65,11 +53,7 @@ const int packet_len_table[] = // Message for all GMs on all map servers void intif_GMmessage(XString mes) { - WFIFOW(char_session, 0) = 0x3000; - size_t len = mes.size() + 1; - WFIFOW(char_session, 2) = 4 + len; - WFIFO_STRING(char_session, 4, mes, len); - WFIFOSET(char_session, WFIFOW(char_session, 2)); + send_packet_repeatonly<0x3000, 4, 1>(char_session, mes); } // The transmission of Wisp/Page to inter-server (player not found on this server) @@ -77,13 +61,10 @@ void intif_wis_message(dumb_ptr sd, CharName nick, ZString mes { nullpo_retv(sd); - size_t mes_len = mes.size() + 1; - WFIFOW(char_session, 0) = 0x3001; - WFIFOW(char_session, 2) = mes_len + 52; - WFIFO_STRING(char_session, 4, sd->status_key.name.to__actual(), 24); - WFIFO_STRING(char_session, 28, nick.to__actual(), 24); - WFIFO_STRING(char_session, 52, mes, mes_len); - WFIFOSET(char_session, WFIFOW(char_session, 2)); + Packet_Head<0x3001> head_01; + head_01.from_char_name = sd->status_key.name; + head_01.to_char_name = nick; + send_vpacket<0x3001, 52, 1>(char_session, head_01, mes); if (battle_config.etc_log) PRINTF("intif_wis_message from %s to %s)\n"_fmt, @@ -92,12 +73,12 @@ void intif_wis_message(dumb_ptr sd, CharName nick, ZString mes // The reply of Wisp/page static -void intif_wis_replay(int id, int flag) +void intif_wis_replay(CharId id, int flag) { - WFIFOW(char_session, 0) = 0x3002; - WFIFOL(char_session, 2) = id; - WFIFOB(char_session, 6) = flag; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target - WFIFOSET(char_session, 7); + Packet_Fixed<0x3002> fixed_02; + fixed_02.char_id = id; + fixed_02.flag = flag; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target + send_fpacket<0x3002, 7>(char_session, fixed_02); if (battle_config.etc_log) PRINTF("intif_wis_replay: id: %d, flag:%d\n"_fmt, id, flag); @@ -106,13 +87,10 @@ void intif_wis_replay(int id, int flag) // The transmission of GM only Wisp/Page from server to inter-server void intif_wis_message_to_gm(CharName Wisp_name, GmLevel min_gm_level, ZString mes) { - size_t mes_len = mes.size() + 1; - WFIFOW(char_session, 0) = 0x3003; - WFIFOW(char_session, 2) = mes_len + 30; - WFIFO_STRING(char_session, 4, Wisp_name.to__actual(), 24); - WFIFOW(char_session, 28) = static_cast(min_gm_level.get_all_bits()); - WFIFO_STRING(char_session, 30, mes, mes_len); - WFIFOSET(char_session, WFIFOW(char_session, 2)); + Packet_Head<0x3003> head_03; + head_03.char_name = Wisp_name; + head_03.min_gm_level = min_gm_level; + send_vpacket<0x3003, 30, 1>(char_session, head_03, mes); if (battle_config.etc_log) PRINTF("intif_wis_message_to_gm: from: '%s', min level: %d, message: '%s'.\n"_fmt, @@ -122,20 +100,18 @@ void intif_wis_message_to_gm(CharName Wisp_name, GmLevel min_gm_level, ZString m // アカウント変数送信 void intif_saveaccountreg(dumb_ptr sd) { - int j, p; - nullpo_retv(sd); assert (sd->status.account_reg_num < ACCOUNT_REG_NUM); - WFIFOW(char_session, 0) = 0x3004; - WFIFOL(char_session, 4) = unwrap(sd->bl_id); - for (j = 0, p = 8; j < sd->status.account_reg_num; j++, p += 36) + Packet_Head<0x3004> head_04; + head_04.account_id = block_to_account(sd->bl_id); + std::vector> repeat_04(sd->status.account_reg_num); + for (size_t j = 0; j < sd->status.account_reg_num; j++) { - WFIFO_STRING(char_session, p, sd->status.account_reg[j].str, 32); - WFIFOL(char_session, p + 32) = sd->status.account_reg[j].value; + repeat_04[j].name = sd->status.account_reg[j].str; + repeat_04[j].value = sd->status.account_reg[j].value; } - WFIFOW(char_session, 2) = p; - WFIFOSET(char_session, p); + send_vpacket<0x3004, 8, 36>(char_session, head_04, repeat_04); } // アカウント変数要求 @@ -143,28 +119,27 @@ void intif_request_accountreg(dumb_ptr sd) { nullpo_retv(sd); - WFIFOW(char_session, 0) = 0x3005; - WFIFOL(char_session, 2) = unwrap(sd->bl_id); - WFIFOSET(char_session, 6); + Packet_Fixed<0x3005> fixed_05; + fixed_05.account_id = block_to_account(sd->bl_id); + send_fpacket<0x3005, 6>(char_session, fixed_05); } // 倉庫データ要求 void intif_request_storage(AccountId account_id) { - WFIFOW(char_session, 0) = 0x3010; - WFIFOL(char_session, 2) = unwrap(account_id); - WFIFOSET(char_session, 6); + Packet_Fixed<0x3010> fixed_10; + fixed_10.account_id = account_id; + send_fpacket<0x3010, 6>(char_session, fixed_10); } // 倉庫データ送信 void intif_send_storage(Storage *stor) { nullpo_retv(stor); - WFIFOW(char_session, 0) = 0x3011; - WFIFOW(char_session, 2) = sizeof(Storage) + 8; - WFIFOL(char_session, 4) = unwrap(stor->account_id); - WFIFO_STRUCT(char_session, 8, *stor); - WFIFOSET(char_session, WFIFOW(char_session, 2)); + Packet_Payload<0x3011> payload_11; + payload_11.account_id = stor->account_id; + payload_11.storage = *stor; + send_ppacket<0x3011>(char_session, payload_11); } // パーティ作成要求 @@ -172,21 +147,21 @@ void intif_create_party(dumb_ptr sd, PartyName name) { nullpo_retv(sd); - WFIFOW(char_session, 0) = 0x3020; - WFIFOL(char_session, 2) = unwrap(sd->status_key.account_id); - WFIFO_STRING(char_session, 6, name, 24); - WFIFO_STRING(char_session, 30, sd->status_key.name.to__actual(), 24); - WFIFO_STRING(char_session, 54, sd->bl_m->name_, 16); - WFIFOW(char_session, 70) = sd->status.base_level; - WFIFOSET(char_session, 72); + Packet_Fixed<0x3020> fixed_20; + fixed_20.account_id = sd->status_key.account_id; + fixed_20.party_name = name; + fixed_20.char_name = sd->status_key.name; + fixed_20.map_name = sd->bl_m->name_; + fixed_20.level = sd->status.base_level; + send_fpacket<0x3020, 72>(char_session, fixed_20); } // パーティ情報要求 void intif_request_partyinfo(PartyId party_id) { - WFIFOW(char_session, 0) = 0x3021; - WFIFOL(char_session, 2) = unwrap(party_id); - WFIFOSET(char_session, 6); + Packet_Fixed<0x3021> fixed_21; + fixed_21.party_id = party_id; + send_fpacket<0x3021, 6>(char_session, fixed_21); } // パーティ追加要求 @@ -196,34 +171,34 @@ void intif_party_addmember(PartyId party_id, AccountId account_id) sd = map_id2sd(account_to_block(account_id)); if (sd != NULL) { - WFIFOW(char_session, 0) = 0x3022; - WFIFOL(char_session, 2) = unwrap(party_id); - WFIFOL(char_session, 6) = unwrap(account_id); - WFIFO_STRING(char_session, 10, sd->status_key.name.to__actual(), 24); - WFIFO_STRING(char_session, 34, sd->bl_m->name_, 16); - WFIFOW(char_session, 50) = sd->status.base_level; - WFIFOSET(char_session, 52); + Packet_Fixed<0x3022> fixed_22; + fixed_22.party_id = party_id; + fixed_22.account_id = account_id; + fixed_22.char_name = sd->status_key.name; + fixed_22.map_name = sd->bl_m->name_; + fixed_22.level = sd->status.base_level; + send_fpacket<0x3022, 52>(char_session, fixed_22); } } // パーティ設定変更 void intif_party_changeoption(PartyId party_id, AccountId account_id, int exp, int item) { - WFIFOW(char_session, 0) = 0x3023; - WFIFOL(char_session, 2) = unwrap(party_id); - WFIFOL(char_session, 6) = unwrap(account_id); - WFIFOW(char_session, 10) = exp; - WFIFOW(char_session, 12) = item; - WFIFOSET(char_session, 14); + Packet_Fixed<0x3023> fixed_23; + fixed_23.party_id = party_id; + fixed_23.account_id = account_id; + fixed_23.exp = exp; + fixed_23.item = item; + send_fpacket<0x3023, 14>(char_session, fixed_23); } // パーティ脱退要求 void intif_party_leave(PartyId party_id, AccountId account_id) { - WFIFOW(char_session, 0) = 0x3024; - WFIFOL(char_session, 2) = unwrap(party_id); - WFIFOL(char_session, 6) = unwrap(account_id); - WFIFOSET(char_session, 10); + Packet_Fixed<0x3024> fixed_24; + fixed_24.party_id = party_id; + fixed_24.account_id = account_id; + send_fpacket<0x3024, 10>(char_session, fixed_24); } // パーティ移動要求 @@ -231,36 +206,33 @@ void intif_party_changemap(dumb_ptr sd, int online) { if (sd != NULL) { - WFIFOW(char_session, 0) = 0x3025; - WFIFOL(char_session, 2) = unwrap(sd->status.party_id); - WFIFOL(char_session, 6) = unwrap(sd->status_key.account_id); - WFIFO_STRING(char_session, 10, sd->bl_m->name_, 16); - WFIFOB(char_session, 26) = online; - WFIFOW(char_session, 27) = sd->status.base_level; - WFIFOSET(char_session, 29); + Packet_Fixed<0x3025> fixed_25; + fixed_25.party_id = sd->status.party_id; + fixed_25.account_id = sd->status_key.account_id; + fixed_25.map_name = sd->bl_m->name_; + fixed_25.online = online; + fixed_25.level = sd->status.base_level; + send_fpacket<0x3025, 29>(char_session, fixed_25); } } // パーティ会話送信 void intif_party_message(PartyId party_id, AccountId account_id, XString mes) { - size_t len = mes.size() + 1; - WFIFOW(char_session, 0) = 0x3027; - WFIFOW(char_session, 2) = len + 12; - WFIFOL(char_session, 4) = unwrap(party_id); - WFIFOL(char_session, 8) = unwrap(account_id); - WFIFO_STRING(char_session, 12, mes, len); - WFIFOSET(char_session, len + 12); + Packet_Head<0x3027> head_27; + head_27.party_id = party_id; + head_27.account_id = account_id; + send_vpacket<0x3027, 12, 1>(char_session, head_27, mes); } // パーティ競合チェック要求 void intif_party_checkconflict(PartyId party_id, AccountId account_id, CharName nick) { - WFIFOW(char_session, 0) = 0x3028; - WFIFOL(char_session, 2) = unwrap(party_id); - WFIFOL(char_session, 6) = unwrap(account_id); - WFIFO_STRING(char_session, 10, nick.to__actual(), 24); - WFIFOSET(char_session, 34); + Packet_Fixed<0x3028> fixed_28; + fixed_28.party_id = party_id; + fixed_28.account_id = account_id; + fixed_28.char_name = nick; + send_fpacket<0x3028, 34>(char_session, fixed_28); } //----------------------------------------------------------------- @@ -268,21 +240,18 @@ void intif_party_checkconflict(PartyId party_id, AccountId account_id, CharName // Wisp/Page reception static -int intif_parse_WisMessage(Session *s) +int intif_parse_WisMessage(Session *, const Packet_Head<0x3801>& head, AString& buf) { // rewritten by [Yor] dumb_ptr sd; - CharName from = stringish(RFIFO_STRING<24>(s, 8)); - CharName to = stringish(RFIFO_STRING<24>(s, 32)); - - size_t len = RFIFOW(s, 2) - 56; - AString buf = RFIFO_STRING(s, 56, len); + CharName from = head.src_char_name; + CharName to = head.dst_char_name; if (battle_config.etc_log) { PRINTF("intif_parse_wismessage: id: %d, from: %s, to: %s\n"_fmt, - RFIFOL(s, 4), + head.whisper_id, from, to); } @@ -294,23 +263,23 @@ int intif_parse_WisMessage(Session *s) // if source player not found in ignore list { clif_wis_message(sd->sess, from, buf); - intif_wis_replay(RFIFOL(s, 4), 0); // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target + intif_wis_replay(head.whisper_id, 0); // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target } } } else - intif_wis_replay(RFIFOL(s, 4), 1); // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target + intif_wis_replay(head.whisper_id, 1); // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target return 0; } // Wisp/page transmission result reception static -int intif_parse_WisEnd(Session *s) +int intif_parse_WisEnd(Session *, const Packet_Fixed<0x3802>& fixed) { dumb_ptr sd; - CharName name = stringish(RFIFO_STRING<24>(s, 2)); - uint8_t flag = RFIFOB(s, 26); + CharName name = fixed.sender_char_name; + uint8_t flag = fixed.flag; if (battle_config.etc_log) // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target PRINTF("intif_parse_wisend: player: %s, flag: %d\n"_fmt, @@ -324,17 +293,11 @@ int intif_parse_WisEnd(Session *s) // Received wisp message from map-server via char-server for ALL gm static -void mapif_parse_WisToGM(Session *s) +void mapif_parse_WisToGM(Session *, const Packet_Head<0x3803>& head, AString& message) { // 0x3003/0x3803 .w .24B .w .?B - if (RFIFOW(s, 2) - 30 <= 0) - return; - - int len = RFIFOW(s, 2) - 30; - - GmLevel min_gm_level = GmLevel::from(static_cast(RFIFOW(s, 28))); - CharName Wisp_name = stringish(RFIFO_STRING<24>(s, 4)); - AString message = RFIFO_STRING(s, 30, len); + GmLevel min_gm_level = head.min_gm_level; + CharName Wisp_name = head.char_name; // information is sended to all online GM for (io::FD i : iter_fds()) { @@ -352,39 +315,39 @@ void mapif_parse_WisToGM(Session *s) // アカウント変数通知 static -int intif_parse_AccountReg(Session *s) +int intif_parse_AccountReg(Session *, const Packet_Head<0x3804>& head, const std::vector>& repeat) { - int j, p; - dumb_ptr sd = map_id2sd(account_to_block(wrap(RFIFOL(s, 4)))); + dumb_ptr sd = map_id2sd(account_to_block(head.account_id)); if (sd == NULL) return 1; - for (p = 8, j = 0; p < RFIFOW(s, 2) && j < ACCOUNT_REG_NUM; - p += 36, j++) + + size_t jlim = std::min(ACCOUNT_REG_NUM, repeat.size()); + for (size_t j = 0; j < jlim; j++) { - sd->status.account_reg[j].str = stringish(RFIFO_STRING<32>(s, p)); - sd->status.account_reg[j].value = RFIFOL(s, p + 32); + sd->status.account_reg[j].str = repeat[j].name; + sd->status.account_reg[j].value = repeat[j].value; } - sd->status.account_reg_num = j; + sd->status.account_reg_num = jlim; return 0; } // 倉庫データ受信 static -int intif_parse_LoadStorage(Session *s) +int intif_parse_LoadStorage(Session *, const Packet_Payload<0x3810>& payload) { Storage *stor; dumb_ptr sd; - sd = map_id2sd(account_to_block(wrap(RFIFOL(s, 4)))); + sd = map_id2sd(account_to_block(payload.account_id)); if (sd == NULL) { if (battle_config.error_log) PRINTF("intif_parse_LoadStorage: user not found %d\n"_fmt, - RFIFOL(s, 4)); + payload.account_id); return 1; } - stor = account2storage(wrap(RFIFOL(s, 4))); + stor = account2storage(payload.account_id); if (stor->storage_status == 1) { // Already open.. lets ignore this update if (battle_config.error_log) @@ -400,16 +363,9 @@ int intif_parse_LoadStorage(Session *s) return 1; } - if (RFIFOW(s, 2) - 8 != sizeof(Storage)) - { - if (battle_config.error_log) - PRINTF("intif_parse_LoadStorage: data size error %d %zu\n"_fmt, - RFIFOW(s, 2) - 8, sizeof(Storage)); - return 1; - } if (battle_config.save_log) - PRINTF("intif_openstorage: %d\n"_fmt, RFIFOL(s, 4)); - RFIFO_STRUCT(s, 8, *stor); + PRINTF("intif_openstorage: %d\n"_fmt, payload.account_id); + *stor = payload.storage; stor->dirty = 0; stor->storage_status = 1; sd->state.storage_open = 1; @@ -422,50 +378,41 @@ int intif_parse_LoadStorage(Session *s) // 倉庫データ送信成功 static -void intif_parse_SaveStorage(Session *s) +void intif_parse_SaveStorage(Session *, const Packet_Fixed<0x3811>& fixed) { if (battle_config.save_log) - PRINTF("intif_savestorage: done %d %d\n"_fmt, RFIFOL(s, 2), - RFIFOB(s, 6)); - storage_storage_saved(wrap(RFIFOL(s, 2))); + PRINTF("intif_savestorage: done %d %d\n"_fmt, fixed.account_id, + fixed.unknown); + storage_storage_saved(fixed.account_id); } // パーティ作成可否 static -void intif_parse_PartyCreated(Session *s) +void intif_parse_PartyCreated(Session *, const Packet_Fixed<0x3820>& fixed) { if (battle_config.etc_log) PRINTF("intif: party created\n"_fmt); - AccountId account_id = wrap(RFIFOL(s, 2)); - int fail = RFIFOB(s, 6); - PartyId party_id = wrap(RFIFOL(s, 7)); - PartyName name = stringish(RFIFO_STRING<24>(s, 11)); + AccountId account_id = fixed.account_id; + int fail = fixed.error; + PartyId party_id = fixed.party_id; + PartyName name = fixed.party_name; party_created(account_id, fail, party_id, name); } // パーティ情報 static -void intif_parse_PartyInfo(Session *s) +void intif_parse_PartyInfo(Session *, const Packet_Head<0x3821>& head, bool has_opt, const Packet_Option<0x3821>& option) { - if (RFIFOW(s, 2) == 8) + if (!has_opt) { if (battle_config.error_log) - PRINTF("intif: party noinfo %d\n"_fmt, RFIFOL(s, 4)); - party_recv_noinfo(wrap(RFIFOL(s, 4))); + PRINTF("intif: party noinfo %d\n"_fmt, head.party_id); + party_recv_noinfo(head.party_id); return; } - if (RFIFOW(s, 2) != sizeof(PartyMost) + 8) - { - if (battle_config.error_log) - PRINTF("intif: party info : data size error %d %d %zu\n"_fmt, - RFIFOL(s, 4), RFIFOW(s, 2), - sizeof(PartyMost) + 8); - } - PartyId pi; - PartyMost pm; - RFIFO_STRUCT(s, 4, pi); - RFIFO_STRUCT(s, 8, pm); + PartyId pi = head.party_id; + PartyMost pm = option.party_most; PartyPair pp; pp.party_id = pi; pp.party_most = ± @@ -474,29 +421,29 @@ void intif_parse_PartyInfo(Session *s) // パーティ追加通知 static -void intif_parse_PartyMemberAdded(Session *s) +void intif_parse_PartyMemberAdded(Session *, const Packet_Fixed<0x3822>& fixed) { if (battle_config.etc_log) - PRINTF("intif: party member added %d %d %d\n"_fmt, RFIFOL(s, 2), - RFIFOL(s, 6), RFIFOB(s, 10)); - party_member_added(wrap(RFIFOL(s, 2)), wrap(RFIFOL(s, 6)), RFIFOB(s, 10)); + PRINTF("intif: party member added %d %d %d\n"_fmt, fixed.party_id, + fixed.account_id, fixed.flag); + party_member_added(fixed.party_id, fixed.account_id, fixed.flag); } // パーティ設定変更通知 static -void intif_parse_PartyOptionChanged(Session *s) +void intif_parse_PartyOptionChanged(Session *, const Packet_Fixed<0x3823>& fixed) { - party_optionchanged(wrap(RFIFOL(s, 2)), wrap(RFIFOL(s, 6)), RFIFOW(s, 10), - RFIFOW(s, 12), RFIFOB(s, 14)); + party_optionchanged(fixed.party_id, fixed.account_id, fixed.exp, + fixed.item, fixed.flag); } // パーティ脱退通知 static -void intif_parse_PartyMemberLeaved(Session *s) +void intif_parse_PartyMemberLeaved(Session *, const Packet_Fixed<0x3824>& fixed) { - PartyId party_id = wrap(RFIFOL(s, 2)); - AccountId account_id = wrap(RFIFOL(s, 6)); - CharName name = stringish(RFIFO_STRING<24>(s, 10)); + PartyId party_id = fixed.party_id; + AccountId account_id = fixed.account_id; + CharName name = fixed.char_name; if (battle_config.etc_log) PRINTF("intif: party member leaved %d %d %s\n"_fmt, party_id, account_id, name); @@ -505,118 +452,198 @@ void intif_parse_PartyMemberLeaved(Session *s) // パーティ解散通知 static -void intif_parse_PartyBroken(Session *s) +void intif_parse_PartyBroken(Session *, const Packet_Fixed<0x3826>& fixed) { - party_broken(wrap(RFIFOL(s, 2))); + party_broken(fixed.party_id); } // パーティ移動通知 static -void intif_parse_PartyMove(Session *s) +void intif_parse_PartyMove(Session *, const Packet_Fixed<0x3825>& fixed) { - PartyId party_id = wrap(RFIFOL(s, 2)); - AccountId account_id = wrap(RFIFOL(s, 6)); - MapName map = stringish(RFIFO_STRING<16>(s, 10)); - uint8_t online = RFIFOB(s, 26); - uint16_t lv = RFIFOW(s, 27); + PartyId party_id = fixed.party_id; + AccountId account_id = fixed.account_id; + MapName map = fixed.map_name; + uint8_t online = fixed.online; + uint16_t lv = fixed.level; party_recv_movemap(party_id, account_id, map, online, lv); } // パーティメッセージ static -void intif_parse_PartyMessage(Session *s) +void intif_parse_PartyMessage(Session *, const Packet_Head<0x3827>& head, AString& buf) { - size_t len = RFIFOW(s, 2) - 12; - AString buf = RFIFO_STRING(s, 12, len); - party_recv_message(wrap(RFIFOL(s, 4)), wrap(RFIFOL(s, 8)), buf); + party_recv_message(head.party_id, head.account_id, buf); } //----------------------------------------------------------------- // inter serverからの通信 // エラーがあれば0(false)を返すこと // パケットが処理できれば1,パケット長が足りなければ2を返すこと -int intif_parse(Session *s) +RecvResult intif_parse(Session *s, uint16_t packet_id) { - int packet_len; - int cmd = RFIFOW(s, 0); - // パケットのID確認 - if (cmd < 0x3800 - || cmd >= - 0x3800 + (sizeof(packet_len_table) / sizeof(packet_len_table[0])) - || packet_len_table[cmd - 0x3800] == 0) - { - return 0; - } - // パケットの長さ確認 - packet_len = packet_len_table[cmd - 0x3800]; - if (packet_len == -1) - { - if (RFIFOREST(s) < 4) - return 2; - packet_len = RFIFOW(s, 2); - } - if (RFIFOREST(s) < packet_len) - { - return 2; - } - // 処理分岐 - switch (cmd) + RecvResult rv; + + switch (packet_id) { case 0x3800: { - AString mes = RFIFO_STRING(s, 4, packet_len - 4); + AString mes; + rv = recv_packet_repeatonly<0x3800, 4, 1>(s, mes); + if (rv != RecvResult::Complete) + return rv; + clif_GMmessage(NULL, mes, 0); - } break; + } case 0x3801: - intif_parse_WisMessage(s); + { + Packet_Head<0x3801> head; + AString repeat; + rv = recv_vpacket<0x3801, 56, 1>(s, head, repeat); + if (rv != RecvResult::Complete) + return rv; + + intif_parse_WisMessage(s, head, repeat); break; + } case 0x3802: - intif_parse_WisEnd(s); + { + Packet_Fixed<0x3802> fixed; + rv = recv_fpacket<0x3802, 27>(s, fixed); + if (rv != RecvResult::Complete) + return rv; + + intif_parse_WisEnd(s, fixed); break; + } case 0x3803: - mapif_parse_WisToGM(s); + { + Packet_Head<0x3803> head; + AString repeat; + rv = recv_vpacket<0x3803, 30, 1>(s, head, repeat); + if (rv != RecvResult::Complete) + return rv; + + mapif_parse_WisToGM(s, head, repeat); break; + } case 0x3804: - intif_parse_AccountReg(s); + { + Packet_Head<0x3804> head; + std::vector> repeat; + rv = recv_vpacket<0x3804, 8, 36>(s, head, repeat); + if (rv != RecvResult::Complete) + return rv; + + intif_parse_AccountReg(s, head, repeat); break; + } case 0x3810: - intif_parse_LoadStorage(s); + { + Packet_Payload<0x3810> payload; + rv = recv_ppacket<0x3810>(s, payload); + if (rv != RecvResult::Complete) + return rv; + + intif_parse_LoadStorage(s, payload); break; + } case 0x3811: - intif_parse_SaveStorage(s); + { + Packet_Fixed<0x3811> fixed; + rv = recv_fpacket<0x3811, 7>(s, fixed); + if (rv != RecvResult::Complete) + return rv; + + intif_parse_SaveStorage(s, fixed); break; + } case 0x3820: - intif_parse_PartyCreated(s); + { + Packet_Fixed<0x3820> fixed; + rv = recv_fpacket<0x3820, 35>(s, fixed); + if (rv != RecvResult::Complete) + return rv; + + intif_parse_PartyCreated(s, fixed); break; + } case 0x3821: - intif_parse_PartyInfo(s); + { + Packet_Head<0x3821> head; + bool has_opt; + Packet_Option<0x3821> option; + rv = recv_opacket<0x3821, 8, sizeof(NetPacket_Option<0x3821>)>(s, head, &has_opt, option); + if (rv != RecvResult::Complete) + return rv; + + intif_parse_PartyInfo(s, head, has_opt, option); break; + } case 0x3822: - intif_parse_PartyMemberAdded(s); + { + Packet_Fixed<0x3822> fixed; + rv = recv_fpacket<0x3822, 11>(s, fixed); + if (rv != RecvResult::Complete) + return rv; + + intif_parse_PartyMemberAdded(s, fixed); break; + } case 0x3823: - intif_parse_PartyOptionChanged(s); + { + Packet_Fixed<0x3823> fixed; + rv = recv_fpacket<0x3823, 15>(s, fixed); + if (rv != RecvResult::Complete) + return rv; + + intif_parse_PartyOptionChanged(s, fixed); break; + } case 0x3824: - intif_parse_PartyMemberLeaved(s); + { + Packet_Fixed<0x3824> fixed; + rv = recv_fpacket<0x3824, 34>(s, fixed); + if (rv != RecvResult::Complete) + return rv; + + intif_parse_PartyMemberLeaved(s, fixed); break; + } case 0x3825: - intif_parse_PartyMove(s); + { + Packet_Fixed<0x3825> fixed; + rv = recv_fpacket<0x3825, 29>(s, fixed); + if (rv != RecvResult::Complete) + return rv; + + intif_parse_PartyMove(s, fixed); break; + } case 0x3826: - intif_parse_PartyBroken(s); + { + Packet_Fixed<0x3826> fixed; + rv = recv_fpacket<0x3826, 7>(s, fixed); + if (rv != RecvResult::Complete) + return rv; + + intif_parse_PartyBroken(s, fixed); break; + } case 0x3827: - intif_parse_PartyMessage(s); + { + Packet_Head<0x3827> head; + AString repeat; + rv = recv_vpacket<0x3827, 12, 1>(s, head, repeat); + if (rv != RecvResult::Complete) + return rv; + + intif_parse_PartyMessage(s, head, repeat); break; + } default: - if (battle_config.error_log) - PRINTF("intif_parse : unknown packet %d %x\n"_fmt, s, - RFIFOW(s, 0)); - return 0; + return RecvResult::Error; } - // パケット読み飛ばし - RFIFOSKIP(s, packet_len); - return 1; + return rv; } diff --git a/src/map/intif.hpp b/src/map/intif.hpp index 2e3d3fe..44bd8eb 100644 --- a/src/map/intif.hpp +++ b/src/map/intif.hpp @@ -31,7 +31,7 @@ # include "../mmo/fwd.hpp" -int intif_parse(Session *); +RecvResult intif_parse(Session *, uint16_t packet_id); void intif_GMmessage(XString mes); diff --git a/src/map/pc.cpp b/src/map/pc.cpp index 33cb57f..e3a672e 100644 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -40,10 +40,11 @@ #include "../io/read.hpp" #include "../net/timer.hpp" -#include "../net/vomit.hpp" #include "../mmo/utils.hpp" +#include "../proto2/char-map.hpp" + #include "atcommand.hpp" #include "battle.hpp" #include "chrif.hpp" @@ -2852,7 +2853,7 @@ int pc_attack(dumb_ptr sd, BlockId target_id, int type) if (bl->bl_type == BL::NPC) { // monster npcs [Valaris] - npc_click(sd, wrap(RFIFOL(sd->sess, 2))); + npc_click(sd, target_id); return 0; } @@ -5176,15 +5177,14 @@ void pc_autosave(TimerData *, tick_t) ).detach(); } -int pc_read_gm_account(Session *s) +int pc_read_gm_account(Session *, const std::vector>& repeat) { gm_accountm.clear(); - // (RFIFOW(fd, 2) - 4) / 5 - for (int i = 4; i < RFIFOW(s, 2); i += 5) + for (const auto& i : repeat) { - AccountId account_id = wrap(RFIFOL(s, i)); - GmLevel level = GmLevel::from(static_cast(RFIFOB(s, i + 4))); + AccountId account_id = i.account_id; + GmLevel level = i.gm_level; gm_accountm[account_id] = level; } return gm_accountm.size(); diff --git a/src/map/pc.hpp b/src/map/pc.hpp index 10c11cf..53e5c1d 100644 --- a/src/map/pc.hpp +++ b/src/map/pc.hpp @@ -31,6 +31,8 @@ # include "../mmo/utils.hpp" +# include "../proto2/fwd.hpp" + # include "clif.t.hpp" # include "map.hpp" @@ -172,7 +174,7 @@ void pc_set_gm_level(AccountId account_id, GmLevel level); void pc_setstand(dumb_ptr sd); void pc_cleanup(dumb_ptr sd); // [Fate] Clean up after a logged-out PC -int pc_read_gm_account(Session *); +int pc_read_gm_account(Session *, const std::vector>&); int pc_setinvincibletimer(dumb_ptr sd, interval_t); int pc_delinvincibletimer(dumb_ptr sd); int pc_logout(dumb_ptr sd); // [fate] Player logs out diff --git a/src/net/packets.hpp b/src/net/packets.hpp index 54167e8..4bb412f 100644 --- a/src/net/packets.hpp +++ b/src/net/packets.hpp @@ -188,7 +188,7 @@ RecvResult net_recv_opacket(Session *s, NetPacket_Head& head, bool *has_opt, if (nat.magic_packet_length < sizeof(NetPacket_Head)) return RecvResult::Error; size_t bytes_repeat = nat.magic_packet_length - sizeof(NetPacket_Head); - if (bytes_repeat % sizeof(NetPacket_Repeat)) + if (bytes_repeat % sizeof(NetPacket_Option)) return RecvResult::Error; size_t has_opt_pls = bytes_repeat / sizeof(NetPacket_Option); if (has_opt_pls > 1) -- cgit v1.2.3-60-g2f50