From 6bad6cbe77340378b2291a6891887d9bf9610f07 Mon Sep 17 00:00:00 2001 From: Zach Toogood Date: Sun, 16 Mar 2025 13:39:22 +0000 Subject: [PATCH 1/4] Core: Refactor map session management --- modules/custom/cpp/ah_announcement.cpp | 4 +- modules/custom/cpp/ah_pagination.cpp | 6 +- modules/renamer/cpp/renamer.cpp | 6 +- src/common/CMakeLists.txt | 2 + src/common/ipp.cpp | 101 +++++++ src/common/ipp.h | 61 +--- src/common/socket.cpp | 19 -- src/common/socket.h | 5 - src/login/data_session.cpp | 8 +- src/login/data_session.h | 2 + src/login/login_helpers.cpp | 18 -- src/login/login_helpers.h | 5 - src/map/CMakeLists.txt | 4 + src/map/enmity_container.cpp | 2 +- src/map/ipc_client.cpp | 20 +- src/map/map.cpp | 367 ++++--------------------- src/map/map.h | 84 +----- src/map/map_constants.h | 36 +++ src/map/map_session.cpp | 48 ++++ src/map/map_session.h | 59 ++++ src/map/map_session_container.cpp | 288 +++++++++++++++++++ src/map/map_session_container.h | 47 ++++ src/map/packet_system.cpp | 244 ++++++++-------- src/map/packet_system.h | 4 +- src/map/packets/server_ip.cpp | 12 +- src/map/packets/server_ip.h | 7 +- src/map/utils/charutils.cpp | 13 +- src/map/zone.cpp | 4 +- src/world/conquest_system.cpp | 1 + tools/fuzzer.cpp | 10 +- 30 files changed, 834 insertions(+), 653 deletions(-) create mode 100644 src/common/ipp.cpp create mode 100644 src/map/map_constants.h create mode 100644 src/map/map_session.cpp create mode 100644 src/map/map_session.h create mode 100644 src/map/map_session_container.cpp create mode 100644 src/map/map_session_container.h diff --git a/modules/custom/cpp/ah_announcement.cpp b/modules/custom/cpp/ah_announcement.cpp index 14180ab9831..26f5a38032d 100644 --- a/modules/custom/cpp/ah_announcement.cpp +++ b/modules/custom/cpp/ah_announcement.cpp @@ -25,7 +25,7 @@ extern uint8 PacketSize[512]; -extern std::function PacketParser[512]; +extern std::function PacketParser[512]; class AHAnnouncementModule : public CPPModule { @@ -35,7 +35,7 @@ class AHAnnouncementModule : public CPPModule const auto originalHandler = PacketParser[0x04E]; - const auto newHandler = [originalHandler](map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) -> void + const auto newHandler = [originalHandler](MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) -> void { TracyZoneScoped; diff --git a/modules/custom/cpp/ah_pagination.cpp b/modules/custom/cpp/ah_pagination.cpp index 28bfc7fe9a4..b99ab9db529 100644 --- a/modules/custom/cpp/ah_pagination.cpp +++ b/modules/custom/cpp/ah_pagination.cpp @@ -13,8 +13,8 @@ #include "map/packets/chat_message.h" #include "map/zone.h" -extern uint8 PacketSize[512]; -extern std::function PacketParser[512]; +extern uint8 PacketSize[512]; +extern std::function PacketParser[512]; class AHPaginationModule : public CPPModule { @@ -37,7 +37,7 @@ class AHPaginationModule : public CPPModule const auto originalHandler = PacketParser[0x04E]; - const auto newHandler = [ITEMS_PER_PAGE, TOTAL_PAGES, originalHandler](map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) -> void + const auto newHandler = [ITEMS_PER_PAGE, TOTAL_PAGES, originalHandler](MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) -> void { TracyZoneScoped; diff --git a/modules/renamer/cpp/renamer.cpp b/modules/renamer/cpp/renamer.cpp index dc4f22b00f2..cab3e3ce2a7 100644 --- a/modules/renamer/cpp/renamer.cpp +++ b/modules/renamer/cpp/renamer.cpp @@ -2,8 +2,8 @@ #include "map/utils/moduleutils.h" #include "map/zone.h" -extern uint8 PacketSize[512]; -extern std::function PacketParser[512]; +extern uint8 PacketSize[512]; +extern std::function PacketParser[512]; class RenamerModule : public CPPModule { @@ -50,7 +50,7 @@ class RenamerModule : public CPPModule lua[sol::create_if_nil]["xi"]["renamerTable"] = result; // Add a custom packet handler to the PacketParser array for id 0x01 - PacketParser[0x01] = [&](map_session_data_t* const, CCharEntity* const PChar, CBasicPacket&) + PacketParser[0x01] = [&](MapSession* const, CCharEntity* const PChar, CBasicPacket&) { ShowInfo(fmt::format("{} requested renamer list for {}", PChar->getName(), PChar->loc.zone->getName())); diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index d7ffbeb3a89..41f0ef76dda 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -16,6 +16,8 @@ set(COMMON_SOURCES $<$:${CMAKE_CURRENT_SOURCE_DIR}/debug_windows.cpp> ${CMAKE_CURRENT_SOURCE_DIR}/filewatcher.cpp ${CMAKE_CURRENT_SOURCE_DIR}/filewatcher.h + ${CMAKE_CURRENT_SOURCE_DIR}/ipp.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/ipp.h ${CMAKE_CURRENT_SOURCE_DIR}/kernel.cpp ${CMAKE_CURRENT_SOURCE_DIR}/kernel.h ${CMAKE_CURRENT_SOURCE_DIR}/logging.cpp diff --git a/src/common/ipp.cpp b/src/common/ipp.cpp new file mode 100644 index 00000000000..29a57808f66 --- /dev/null +++ b/src/common/ipp.cpp @@ -0,0 +1,101 @@ +/* +=========================================================================== + + Copyright (c) 2025 LandSandBoat Dev Teams + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see http://www.gnu.org/licenses/ + +=========================================================================== +*/ + +#include "ipp.h" + +auto ip2str(uint32 ip) -> std::string +{ + uint32 reversed_ip = htonl(ip); + char address[INET_ADDRSTRLEN]; + inet_ntop(AF_INET, &reversed_ip, address, INET_ADDRSTRLEN); + + // This is internal, so we can trust it. + return fmt::format("{}", asStringFromUntrustedSource(address)); +} + +auto str2ip(const char* ip_str) -> uint32 +{ + uint32 ip = 0; + inet_pton(AF_INET, ip_str, &ip); + return ntohl(ip); +} + +IPP::IPP() +{ +} + +// TODO: Documentation about whether ip needs to be in network byte order. +IPP::IPP(const uint32 ip, const uint16 port) +: ip_(ip) +, port_(port) +{ +} + +// TODO: Documentation about whether ip needs to be in network byte order. +IPP::IPP(const uint64& ipp) +: IPP(static_cast(ipp), static_cast(ipp >> 32)) +{ +} + +IPP::IPP(const zmq::message_t& message) +: IPP(*reinterpret_cast(message.data())) +{ +} + +IPP::IPP(const sockaddr_in& address) +#ifdef WIN32 +: IPP(ntohl(address.sin_addr.S_un.S_addr), ntohs(address.sin_port)) +#else +: IPP(ntohl(address.sin_addr.s_addr), ntohs(address.sin_port)) +#endif +{ +} + +auto IPP::getRawIPP() const -> uint64 +{ + return static_cast(ip_) | (static_cast(port_) << 32); +} + +auto IPP::getIP() const -> uint32 +{ + return ip_; +} + +auto IPP::getPort() const -> uint16 +{ + return port_; +} + +auto IPP::toString() const -> std::string +{ + return fmt::format("{}:{}", ip2str(ip_), port_); +} + +auto IPP::toZMQMessage() const -> zmq::message_t +{ + const auto ipp = getRawIPP(); + return zmq::message_t(&ipp, sizeof(ipp)); +} + +auto IPP::operator<(const IPP& other) const -> bool +{ + return ip_ < other.ip_ || (ip_ == other.ip_ && port_ < other.port_); +} diff --git a/src/common/ipp.h b/src/common/ipp.h index 5f9854fe023..ec617f2b009 100644 --- a/src/common/ipp.h +++ b/src/common/ipp.h @@ -28,64 +28,33 @@ #include #include +auto ip2str(uint32 ip) -> std::string; +auto str2ip(const char* ip_str) -> uint32; + class IPP final { public: - IPP() - { - } - - explicit IPP(const uint32 ip, const uint16 port) - : ip_(ip) - , port_(port) - { - } - - explicit IPP(const uint64& ipp) - : IPP(static_cast(ipp), static_cast(ipp >> 32)) - { - } - - explicit IPP(const zmq::message_t& message) - : IPP(*reinterpret_cast(message.data())) - { - } - - auto toString() const -> std::string - { - in_addr inaddr{}; - inaddr.s_addr = ip_; - - char address[INET_ADDRSTRLEN]; - inet_ntop(AF_INET, &inaddr, address, INET_ADDRSTRLEN); - - // TODO: Add a designator for if this address is connect, map, search, or world, etc. - - // This is internal, so we can trust it. - return fmt::format("{}:{}", asStringFromUntrustedSource(address), port_); - } + IPP(); + explicit IPP(const uint32 ip, const uint16 port); + explicit IPP(const uint64& ipp); + explicit IPP(const zmq::message_t& message); + explicit IPP(const sockaddr_in& address); - auto getIPP() const -> uint64 - { - return static_cast(ip_) | (static_cast(port_) << 32); - } + auto getRawIPP() const -> uint64; + auto getIP() const -> uint32; + auto getPort() const -> uint16; - auto toZMQMessage() const -> zmq::message_t - { - const auto ipp = getIPP(); - return zmq::message_t(&ipp, sizeof(ipp)); - } + auto toString() const -> std::string; + auto toZMQMessage() const -> zmq::message_t; // // Operators for use with STL containers // - auto operator<(const IPP& other) const -> bool - { - return ip_ < other.ip_ || (ip_ == other.ip_ && port_ < other.port_); - } + auto operator<(const IPP& other) const -> bool; private: + // TODO: Can we enforce whether this is in network byte order? uint32 ip_{}; uint16 port_{}; }; diff --git a/src/common/socket.cpp b/src/common/socket.cpp index e7a7e44e86a..f832c90dd97 100644 --- a/src/common/socket.cpp +++ b/src/common/socket.cpp @@ -162,25 +162,6 @@ int32 fd_max; time_t last_tick; time_t tick_time; -// hostname/ip conversion functions -std::string ip2str(uint32 ip) -{ - uint32 reversed_ip = htonl(ip); - char address[INET_ADDRSTRLEN]; - inet_ntop(AF_INET, &reversed_ip, address, INET_ADDRSTRLEN); - - // This is internal, so we can trust it. - return fmt::format("{}", asStringFromUntrustedSource(address)); -} - -uint32 str2ip(const char* ip_str) -{ - uint32 ip = 0; - inet_pton(AF_INET, ip_str, &ip); - - return ntohl(ip); -} - void set_nonblocking(int fd, unsigned long yes) { TracyZoneScoped; diff --git a/src/common/socket.h b/src/common/socket.h index ffddf642aba..8dd1c623654 100644 --- a/src/common/socket.h +++ b/src/common/socket.h @@ -152,11 +152,6 @@ extern time_t last_tick; void socket_init(); -// hostname/ip conversion functions -std::string ip2str(uint32 ip); - -uint32 str2ip(const char* ip_str); - void set_nonblocking(int fd, unsigned long yes); int32 makeBind_udp(uint32 ip, uint16 port); diff --git a/src/login/data_session.cpp b/src/login/data_session.cpp index 2b147bcf59d..1a76690f02d 100644 --- a/src/login/data_session.cpp +++ b/src/login/data_session.cpp @@ -259,7 +259,7 @@ void data_session::read_func() } uint32 charid = session.requestedCharacterID; - uint32 accountIP = loginHelpers::str2ip(ipAddress.c_str()); + uint32 accountIP = str2ip(ipAddress.c_str()); uint32 ZoneIP = 0; uint16 ZonePort = 0; @@ -301,7 +301,7 @@ void data_session::read_func() characterSelectionResponse.server_id = (charid >> 16) & 0xFF; // Looks wrong? shouldn't this be a server index? ShowInfo(fmt::format("data_session: zoneid:({}), zoneip:({}), zoneport:({}) for char:({})", - ZoneID, loginHelpers::ip2str(ntohl(ZoneIP)), ZonePort, charid)); + ZoneID, ip2str(ntohl(ZoneIP)), ZonePort, charid)); // Check the number of sessions uint16 sessionCount = 0; @@ -458,13 +458,13 @@ void data_session::read_func() if (!db::preparedStmt("INSERT INTO account_ip_record(login_time,accid,charid,client_ip) " "VALUES (?, ?, ?, ?)", - timeAndDate, session.accountID, charid, loginHelpers::ip2str(accountIP))) + timeAndDate, session.accountID, charid, ip2str(accountIP))) { ShowError("data_session: Could not write info to account_ip_record."); } } - ShowInfo(fmt::format("data_session: client {} finished work with lobbyview", loginHelpers::ip2str(accountIP))); + ShowInfo(fmt::format("data_session: client {} finished work with lobbyview", ip2str(accountIP))); } break; case 0xFE: // 254 diff --git a/src/login/data_session.h b/src/login/data_session.h index bdbf34937c0..e47263240b3 100644 --- a/src/login/data_session.h +++ b/src/login/data_session.h @@ -29,6 +29,8 @@ #include "login_helpers.h" #include "login_packets.h" +#include "common/ipp.h" + // port 54230 class data_session : public handler_session { diff --git a/src/login/login_helpers.cpp b/src/login/login_helpers.cpp index 51e18680dd6..f8f1fecabb5 100644 --- a/src/login/login_helpers.cpp +++ b/src/login/login_helpers.cpp @@ -46,24 +46,6 @@ namespace loginHelpers return authenticatedSessions_[ipAddr][sessionHash]; // NOTE: Will construct if doesn't exist } - // hostname/ip conversion functions - std::string ip2str(uint32 ip) - { - uint32 reversed_ip = htonl(ip); - char address[INET_ADDRSTRLEN]; - inet_ntop(AF_INET, &reversed_ip, address, INET_ADDRSTRLEN); - - // This is internal, so we can trust it. - return fmt::format("{}", asStringFromUntrustedSource(address)); - } - - uint32 str2ip(const char* ip_str) - { - uint32 ip = 0; - inet_pton(AF_INET, ip_str, &ip); - return ntohl(ip); - } - // https://github.com/atom0s/XiPackets/blob/main/lobby/S2C_0x0004_ResponseError.md void generateErrorMessage(char* packet, uint16 errorCode) { diff --git a/src/login/login_helpers.h b/src/login/login_helpers.h index 9b5ed035d71..d853d3e0b5f 100644 --- a/src/login/login_helpers.h +++ b/src/login/login_helpers.h @@ -82,11 +82,6 @@ namespace loginHelpers session_t& get_authenticated_session(std::string const& ipAddr, std::string const& sessionHash); - // hostname/ip conversion functions - std::string ip2str(uint32 ip); - - uint32 str2ip(const char* ip_str); - // https://github.com/atom0s/XiPackets/blob/main/lobby/S2C_0x0004_ResponseError.md void generateErrorMessage(char* packet, uint16 errorCode); diff --git a/src/map/CMakeLists.txt b/src/map/CMakeLists.txt index ef719af25b6..34c56dc55f5 100644 --- a/src/map/CMakeLists.txt +++ b/src/map/CMakeLists.txt @@ -77,6 +77,10 @@ set(SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/linkshell.h ${CMAKE_CURRENT_SOURCE_DIR}/map.cpp ${CMAKE_CURRENT_SOURCE_DIR}/map.h + ${CMAKE_CURRENT_SOURCE_DIR}/map_session_container.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/map_session_container.h + ${CMAKE_CURRENT_SOURCE_DIR}/map_session.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/map_session.h ${CMAKE_CURRENT_SOURCE_DIR}/merit.cpp ${CMAKE_CURRENT_SOURCE_DIR}/merit.h ${CMAKE_CURRENT_SOURCE_DIR}/mob_modifier.h diff --git a/src/map/enmity_container.cpp b/src/map/enmity_container.cpp index 4b4b967c65c..d1c26b87c9e 100644 --- a/src/map/enmity_container.cpp +++ b/src/map/enmity_container.cpp @@ -498,7 +498,7 @@ void CEnmityContainer::DecayEnmity() for (auto& it : m_EnmityList) { EnmityObject_t& PEnmityObject = it.second; - constexpr int decay_amount = (int)(60 / server_tick_rate); + constexpr int decay_amount = (int)(60 / kServerTickRate); PEnmityObject.VE -= PEnmityObject.VE > decay_amount ? decay_amount : PEnmityObject.VE; } diff --git a/src/map/ipc_client.cpp b/src/map/ipc_client.cpp index 57bcda516cc..fd4943ff473 100644 --- a/src/map/ipc_client.cpp +++ b/src/map/ipc_client.cpp @@ -676,21 +676,17 @@ void IPCClient::handleMessage_KillSession(const IPP& ipp, const ipc::KillSession { TracyZoneScoped; - map_session_data_t* sessionToDelete = nullptr; - - for (const auto& [_, session] : map_session_list) + if (auto sessionToDelete = gMapSessions.getSessionByCharId(message.victimId)) { - if (session->charID == message.victimId) + if (sessionToDelete->blowfish.status == BLOWFISH_PENDING_ZONE) { - sessionToDelete = session; - break; + ShowDebugFmt("Closing session of charid {} on request of other process", message.victimId); + gMapSessions.destroySession(sessionToDelete); + } + else + { + ShowDebugFmt("KillSession for charid {} not needed", message.victimId); } - } - - if (sessionToDelete && sessionToDelete->blowfish.status == BLOWFISH_PENDING_ZONE) - { - DebugSockets(fmt::format("Closing session of charid {} on request of other process", message.victimId)); - map_close_session(server_clock::now(), sessionToDelete); } } diff --git a/src/map/map.cpp b/src/map/map.cpp index 9033509a23f..268a211d83f 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -26,6 +26,7 @@ #include "common/console_service.h" #include "common/database.h" #include "common/debug.h" +#include "common/ipp.h" #include "common/logging.h" #include "common/socket.h" #include "common/timer.h" @@ -88,19 +89,18 @@ #include #endif -const char* MAP_CONF_FILENAME = nullptr; - -int8* g_PBuff = nullptr; // Global packet clipboard -int8* g_PBuffCopy = nullptr; // Copy of above, used to decrypt a second time if necessary. -int8* PTempBuff = nullptr; // Temporary packet clipboard - -int32 map_fd = 0; // main socket -uint32 map_amntplayers = 0; // map amnt unique players +// TODO: Why do we have this additional +20? +std::array g_PBuff; // Global packet clipboard +std::array g_PBuffCopy; // Copy of above, used to decrypt a second time if necessary. +std::array g_PTempBuff; // Temporary packet clipboard +std::array g_PDecompressBuff; // Temporary packet clipboard +// main socket +int32 map_fd = 0; in_addr map_ip = {}; uint16 map_port = 0; -map_session_list_t map_session_list = {}; +MapSessionContainer gMapSessions; nonstd::jthread messageThread; @@ -116,82 +116,12 @@ extern std::atomic gProcessLoaded; namespace { - uint32 MAX_BUFFER_SIZE = 2500U; - uint32 MAX_PACKETS_PER_COMPRESSION = 32U; - uint32 MAX_PACKET_BACKLOG_SIZE = MAX_PACKETS_PER_COMPRESSION * 6U; // If we hit this number, things are going very very badly. - + // Runtime statistics uint32 TotalPacketsToSendPerTick = 0U; uint32 TotalPacketsSentPerTick = 0U; uint32 TotalPacketsDelayedPerTick = 0U; } // namespace -map_session_data_t* mapsession_getbyipp(uint64 ipp) -{ - TracyZoneScoped; - map_session_list_t::iterator i = map_session_list.begin(); - while (i != map_session_list.end()) - { - if ((*i).first == ipp) - { - return (*i).second; - } - ++i; - } - return nullptr; -} - -map_session_data_t* mapsession_getbychar(CCharEntity* PChar) -{ - TracyZoneScoped; - - for (const auto& [_, session] : map_session_list) - { - if (PChar && session->PChar->id == PChar->id) - { - return session; - } - } - - return nullptr; -} - -map_session_data_t* mapsession_createsession(uint32 ip, uint16 port) -{ - TracyZoneScoped; - - const auto ipstr = ip2str(ip); - - const auto rset = db::preparedStmt("SELECT charid FROM accounts_sessions WHERE inet_ntoa(client_addr) = ? LIMIT 1", ipstr); - - if (rset == nullptr) - { - ShowError("SQL query failed in mapsession_createsession!"); - return nullptr; - } - - if (rset->rowsCount() == 0) - { - // This is noisy and not really necessary - DebugSockets(fmt::format("recv_parse: Invalid login attempt from {}", ipstr)); - return nullptr; - } - - map_session_data_t* map_session_data = new map_session_data_t(); - - map_session_data->server_packet_data = new int8[MAX_BUFFER_SIZE + 20]; - - map_session_data->last_update = time(nullptr); - map_session_data->client_addr = ip; - map_session_data->client_port = port; - - uint64 port64 = port; - uint64 ipp = ip; - ipp |= port64 << 32; - map_session_list[ipp] = map_session_data; - - return map_session_data; -} - void initConsoleService() { // clang-format off @@ -413,13 +343,6 @@ int32 do_init(int32 argc, char** argv) _sql->Query("DELETE FROM char_vars WHERE expiry > 0 AND expiry <= %d", currentTimestamp); _sql->Query("DELETE FROM server_variables WHERE expiry > 0 AND expiry <= %d", currentTimestamp); - g_PBuff = new int8[MAX_BUFFER_SIZE + 20]; - g_PBuffCopy = new int8[MAX_BUFFER_SIZE + 20]; - PTempBuff = new int8[MAX_BUFFER_SIZE + 20]; - - std::memset(g_PBuff, 0, MAX_BUFFER_SIZE + 20); - std::memset(PTempBuff, 0, MAX_BUFFER_SIZE + 20); - PacketGuard::Init(); initConsoleService(); @@ -453,10 +376,6 @@ void do_final(int code) { TracyZoneScoped; - destroy_arr(g_PBuff); - destroy_arr(g_PBuffCopy); - destroy_arr(PTempBuff); - ability::CleanupAbilitiesList(); itemutils::FreeItemList(); battleutils::FreeWeaponSkillsList(); @@ -482,12 +401,6 @@ void do_final(int code) timer_final(); - for (auto session : map_session_list) - { - destroy_arr(session.second->server_packet_data); - destroy(session.second); - } - luautils::cleanup(); logging::ShutDown(); @@ -588,34 +501,26 @@ int32 do_sockets(fd_set* rfd, duration next) sockaddr_in from{}; socklen_t fromlen = sizeof(from); - ret = recvudp(map_fd, g_PBuff, MAX_BUFFER_SIZE, 0, (struct sockaddr*)&from, &fromlen); + ret = recvudp(map_fd, g_PBuff.data(), kMaxBufferSize, 0, (struct sockaddr*)&from, &fromlen); if (ret != -1) { - // find player char -#ifdef WIN32 - uint32 ip = ntohl(from.sin_addr.S_un.S_addr); -#else - uint32 ip = ntohl(from.sin_addr.s_addr); -#endif - - uint64 port = ntohs(from.sin_port); - uint64 ipp = ip; - ipp |= port << 32; - map_session_data_t* map_session_data = mapsession_getbyipp(ipp); + const auto ipp = IPP(from); + // find player char + MapSession* map_session_data = gMapSessions.getSessionByIPP(ipp); if (map_session_data == nullptr) { - map_session_data = mapsession_createsession(ip, ntohs(from.sin_port)); + map_session_data = gMapSessions.createSession(ipp); if (map_session_data == nullptr) { - map_session_list.erase(ipp); + gMapSessions.destroySession(ipp); return -1; } } size_t size = ret; - int32 decryptCount = recv_parse(g_PBuff, &size, &from, map_session_data); + int32 decryptCount = recv_parse(g_PBuff.data(), &size, &from, map_session_data); if (decryptCount != -1) { // DecryptCount of 0 means the main key decrypted the packet @@ -623,9 +528,9 @@ int32 do_sockets(fd_set* rfd, duration next) { // If the previous package was lost, then we do not collect a new one, // and send the previous packet again - if (!parse(g_PBuff, &size, &from, map_session_data)) + if (!parse(g_PBuff.data(), &size, &from, map_session_data)) { - send_parse(g_PBuff, &size, &from, map_session_data, false); + send_parse(g_PBuff.data(), &size, &from, map_session_data, false); } } else if (decryptCount == 1 && map_session_data->blowfish.status == BLOWFISH_PENDING_ZONE) @@ -640,26 +545,23 @@ int32 do_sockets(fd_set* rfd, duration next) PChar->clearPacketList(); PChar->pushPacket(PChar, map_session_data->zone_type, map_session_data->zone_ipp); } - send_parse(g_PBuff, &size, &from, map_session_data, true); + send_parse(g_PBuff.data(), &size, &from, map_session_data, true); // Increment sync count with every packet // TODO: match incoming with a new parse that only cares about sync count map_session_data->server_packet_id += 1; } - ret = sendudp(map_fd, g_PBuff, size, 0, (const struct sockaddr*)&from, fromlen); - - int8* data = g_PBuff; - g_PBuff = map_session_data->server_packet_data; + ret = sendudp(map_fd, g_PBuff.data(), size, 0, (const struct sockaddr*)&from, fromlen); - map_session_data->server_packet_data = data; - map_session_data->server_packet_size = size; + std::swap(g_PBuff, map_session_data->server_packet_data); + std::swap(size, map_session_data->server_packet_size); } // If client is logging out, just close it. if (map_session_data->shuttingDown == 1) { - map_close_session(server_clock::now(), map_session_data); + gMapSessions.destroySession(map_session_data); } } } @@ -677,7 +579,7 @@ int32 do_sockets(fd_set* rfd, duration next) * * ************************************************************************/ -int32 map_decipher_packet(int8* buff, size_t size, sockaddr_in* from, map_session_data_t* PSession, blowfish_t* pbfkey) +int32 map_decipher_packet(uint8* buff, size_t size, sockaddr_in* from, MapSession* PSession, blowfish_t* pbfkey) { TracyZoneScoped; @@ -718,7 +620,7 @@ int32 map_decipher_packet(int8* buff, size_t size, sockaddr_in* from, map_sessio * * ************************************************************************/ -int32 recv_parse(int8* buff, size_t* buffsize, sockaddr_in* from, map_session_data_t* map_session_data) +int32 recv_parse(uint8* buff, size_t* buffsize, sockaddr_in* from, MapSession* map_session_data) { TracyZoneScoped; @@ -735,7 +637,7 @@ int32 recv_parse(int8* buff, size_t* buffsize, sockaddr_in* from, map_session_da } catch (...) { - ShowError(fmt::format("Possible crash attempt from: {}", ip2str(map_session_data->client_addr))); + ShowError(fmt::format("Possible crash attempt from: {}", map_session_data->client_ipp.toString())); return -1; } @@ -822,7 +724,7 @@ int32 recv_parse(int8* buff, size_t* buffsize, sockaddr_in* from, map_session_da map_session_data->client_packet_id = 0; map_session_data->server_packet_id = 0; - map_session_data->zone_ipp = 0; + map_session_data->zone_ipp = {}; map_session_data->zone_type = 0; return 0; @@ -832,7 +734,7 @@ int32 recv_parse(int8* buff, size_t* buffsize, sockaddr_in* from, map_session_da if (map_session_data->blowfish.status == BLOWFISH_PENDING_ZONE) { // Copy buff into the backup buffer. Blowfish can't be rewound currently. - std::memcpy(g_PBuffCopy, buff, *buffsize); + std::memcpy(g_PBuffCopy.data(), buff, *buffsize); } int decryptCount = 0; // char packets @@ -841,10 +743,10 @@ int32 recv_parse(int8* buff, size_t* buffsize, sockaddr_in* from, map_session_da // If the client is pending zone, they might not have received 0x00B, and thus not incremented their key // Check old blowfish data if (map_session_data->blowfish.status == BLOWFISH_PENDING_ZONE && - map_decipher_packet(g_PBuffCopy, *buffsize, from, map_session_data, &map_session_data->prev_blowfish) != -1) + map_decipher_packet(g_PBuffCopy.data(), *buffsize, from, map_session_data, &map_session_data->prev_blowfish) != -1) { // Copy decrypted bytes back into buffer - std::memcpy(buff, g_PBuffCopy, *buffsize); + std::memcpy(buff, g_PBuffCopy.data(), *buffsize); decryptCount++; } else @@ -856,17 +758,16 @@ int32 recv_parse(int8* buff, size_t* buffsize, sockaddr_in* from, map_session_da // reading data size uint32 PacketDataSize = ref(buff, *buffsize - sizeof(int32) - 16); - // creating buffer for decompress data - auto PacketDataBuff = std::make_unique(MAX_BUFFER_SIZE); + // it's decompressing data and getting new size - PacketDataSize = zlib_decompress(buff + FFXI_HEADER_SIZE, PacketDataSize, PacketDataBuff.get(), MAX_BUFFER_SIZE); + PacketDataSize = zlib_decompress((int8*)(buff + FFXI_HEADER_SIZE), PacketDataSize, (int8*)g_PDecompressBuff.data(), kMaxBufferSize); // Not sure why zlib_decompress is defined to return a uint32 when it returns -1 in situations. if (static_cast(PacketDataSize) != -1) { // it's making result buff // don't need std::memcpy header - std::memcpy(buff + FFXI_HEADER_SIZE, PacketDataBuff.get(), PacketDataSize); + std::memcpy(buff + FFXI_HEADER_SIZE, g_PDecompressBuff.data(), PacketDataSize); *buffsize = FFXI_HEADER_SIZE + PacketDataSize; return decryptCount; @@ -882,13 +783,13 @@ int32 recv_parse(int8* buff, size_t* buffsize, sockaddr_in* from, map_session_da * * ************************************************************************/ -int32 parse(int8* buff, size_t* buffsize, sockaddr_in* from, map_session_data_t* map_session_data) +int32 parse(uint8* buff, size_t* buffsize, sockaddr_in* from, MapSession* map_session_data) { TracyZoneScoped; // Start processing the incoming packet - int8* PacketData_Begin = &buff[FFXI_HEADER_SIZE]; - int8* PacketData_End = &buff[*buffsize]; + uint8* PacketData_Begin = &buff[FFXI_HEADER_SIZE]; + uint8* PacketData_End = &buff[*buffsize]; CCharEntity* PChar = map_session_data->PChar; @@ -907,8 +808,8 @@ int32 parse(int8* buff, size_t* buffsize, sockaddr_in* from, map_session_data_t* map_session_data->last_update = time(nullptr); } - for (int8* SmallPD_ptr = PacketData_Begin; SmallPD_ptr + (ref(SmallPD_ptr, 1) & 0xFE) * 2 <= PacketData_End && (ref(SmallPD_ptr, 1) & 0xFE); - SmallPD_ptr = SmallPD_ptr + SmallPD_Size * 2) + for (uint8* SmallPD_ptr = PacketData_Begin; SmallPD_ptr + (ref(SmallPD_ptr, 1) & 0xFE) * 2 <= PacketData_End && (ref(SmallPD_ptr, 1) & 0xFE); + SmallPD_ptr = SmallPD_ptr + SmallPD_Size * 2) { SmallPD_Size = (ref(SmallPD_ptr, 1) & 0x0FE); SmallPD_Type = (ref(SmallPD_ptr, 0) & 0x1FF); @@ -940,14 +841,12 @@ int32 parse(int8* buff, size_t* buffsize, sockaddr_in* from, map_session_data_t* { ShowWarning("[PacketGuard] Caught mismatch between player substate and recieved packet: Player: %s - Packet: %03hX", PChar->getName(), SmallPD_Type); - // TODO: Plug in optional jailutils usage continue; // skip this packet } if (settings::get("map.PACKETGUARD_ENABLED") && !PacketGuard::PacketsArrivingInCorrectOrder(PChar, SmallPD_Type)) { ShowWarning("[PacketGuard] Caught out-of-order packet: Player: %s - Packet: %03hX", PChar->getName(), SmallPD_Type); - // TODO: Plug in optional jailutils usage continue; // skip this packet } @@ -1004,13 +903,14 @@ int32 parse(int8* buff, size_t* buffsize, sockaddr_in* from, map_session_data_t* return 0; } - ref(map_session_data->server_packet_data, 2) = SmallPD_Code; - ref(map_session_data->server_packet_data, 8) = (uint32)time(nullptr); + ref(map_session_data->server_packet_data.data(), 2) = SmallPD_Code; + ref(map_session_data->server_packet_data.data(), 8) = (uint32)time(nullptr); g_PBuff = map_session_data->server_packet_data; *buffsize = map_session_data->server_packet_size; - map_session_data->server_packet_data = buff; + std::memcpy(map_session_data->server_packet_data.data(), buff, *buffsize); + return -1; } @@ -1027,9 +927,10 @@ int32 parse(int8* buff, size_t* buffsize, sockaddr_in* from, map_session_data_t* * * ************************************************************************/ -int32 send_parse(int8* buff, size_t* buffsize, sockaddr_in* from, map_session_data_t* map_session_data, bool usePreviousKey) +int32 send_parse(uint8* buff, size_t* buffsize, sockaddr_in* from, MapSession* map_session_data, bool usePreviousKey) { TracyZoneScoped; + // Modify the header of the outgoing packet // The essence of the transformations: // - send the client the number of the last packet received from him @@ -1049,7 +950,7 @@ int32 send_parse(int8* buff, size_t* buffsize, sockaddr_in* from, map_session_da std::unique_ptr PSmallPacket = nullptr; uint32 PacketSize = UINT32_MAX; - size_t PacketCount = std::clamp(PChar->getPacketCount(), 0, MAX_PACKETS_PER_COMPRESSION); + size_t PacketCount = std::clamp(PChar->getPacketCount(), 0, kMaxPacketPerCompression); uint8 packets = 0; bool incrementKeyAfterEncrypt = false; @@ -1067,7 +968,7 @@ int32 send_parse(int8* buff, size_t* buffsize, sockaddr_in* from, map_session_da auto packetList = PChar->getPacketListCopy(); packets = 0; - while (!packetList.empty() && *buffsize + packetList.front()->getSize() < MAX_BUFFER_SIZE && static_cast(packets) < PacketCount) + while (!packetList.empty() && *buffsize + packetList.front()->getSize() < kMaxBufferSize && static_cast(packets) < PacketCount) { PSmallPacket = std::move(packetList.front()); packetList.pop_front(); @@ -1092,7 +993,7 @@ int32 send_parse(int8* buff, size_t* buffsize, sockaddr_in* from, map_session_da } // Store zoneout packet in case we need to re-send this - if (type == 0x00B && map_session_data->blowfish.status == BLOWFISH_PENDING_ZONE && map_session_data->zone_ipp == 0) + if (type == 0x00B && map_session_data->blowfish.status == BLOWFISH_PENDING_ZONE && map_session_data->zone_ipp.getRawIPP() == 0) { auto IPPacket = static_cast(PSmallPacket.get()); @@ -1116,7 +1017,7 @@ int32 send_parse(int8* buff, size_t* buffsize, sockaddr_in* from, map_session_da // Compress the data without regard to the header // The returned size is 8 times the real data - PacketSize = zlib_compress(buff + FFXI_HEADER_SIZE, (uint32)(*buffsize - FFXI_HEADER_SIZE), PTempBuff, MAX_BUFFER_SIZE); + PacketSize = zlib_compress((int8*)(buff + FFXI_HEADER_SIZE), (uint32)(*buffsize - FFXI_HEADER_SIZE), (int8*)g_PTempBuff.data(), kMaxBufferSize); // handle compression error if (PacketSize == static_cast(-1)) @@ -1125,7 +1026,7 @@ int32 send_parse(int8* buff, size_t* buffsize, sockaddr_in* from, map_session_da continue; } - ref(PTempBuff, zlib_compressed_size(PacketSize)) = PacketSize; + ref(g_PTempBuff.data(), zlib_compressed_size(PacketSize)) = PacketSize; PacketSize = (uint32)zlib_compressed_size(PacketSize) + 4; @@ -1151,17 +1052,17 @@ int32 send_parse(int8* buff, size_t* buffsize, sockaddr_in* from, map_session_da // Record data size excluding header uint8 hash[16]; - md5((uint8*)PTempBuff, hash, PacketSize); - std::memcpy(PTempBuff + PacketSize, hash, 16); + md5(g_PTempBuff.data(), hash, PacketSize); + std::memcpy(g_PTempBuff.data() + PacketSize, hash, 16); PacketSize += 16; - if (PacketSize > MAX_BUFFER_SIZE + 20) + if (PacketSize > kMaxBufferSize + 20) { - ShowCritical("Memory manager: PTempBuff is overflowed (%u)", PacketSize); + ShowCritical("Memory manager: g_PTempBuff is overflowed (%u)", PacketSize); } // Making total packet - std::memcpy(buff + FFXI_HEADER_SIZE, PTempBuff, PacketSize); + std::memcpy(buff + FFXI_HEADER_SIZE, g_PTempBuff.data(), PacketSize); uint32 CypherSize = (PacketSize / 4) & -2; @@ -1208,7 +1109,7 @@ int32 send_parse(int8* buff, size_t* buffsize, sockaddr_in* from, map_session_da if (settings::get("logging.DEBUG_PACKET_BACKLOG")) { TracyZoneString(fmt::format("{} packets remaining", remainingPackets)); - if (remainingPackets > MAX_PACKET_BACKLOG_SIZE) + if (remainingPackets > kMaxPacketBacklogSize) { if (PChar->loc.zone == nullptr) { @@ -1217,175 +1118,25 @@ int32 send_parse(int8* buff, size_t* buffsize, sockaddr_in* from, map_session_da return 0; } ShowWarning(fmt::format("Packet backlog for char {} in {} is {}! Limit is: {}", - PChar->name, PChar->loc.zone->getName(), remainingPackets, MAX_PACKET_BACKLOG_SIZE)); + PChar->name, PChar->loc.zone->getName(), remainingPackets, kMaxPacketBacklogSize)); } } return 0; } -/************************************************************************ - * * - * A timer to end the session (we cannot do this without a timer, * - * since session continues to be used in do_sockets) * - * * - ************************************************************************/ - -int32 map_close_session(time_point tick, map_session_data_t* map_session_data) -{ - TracyZoneScoped; - if (map_session_data != nullptr && map_session_data->server_packet_data != nullptr) - { - // clear accounts_sessions if character is logging out (not when zoning) - if (map_session_data->shuttingDown == 1) - { - _sql->Query("DELETE FROM accounts_sessions WHERE charid = %u", map_session_data->charID); - } - - uint64 port64 = map_session_data->client_port; - uint64 ipp = map_session_data->client_addr; - ipp |= port64 << 32; - - destroy_arr(map_session_data->server_packet_data); - if (map_session_data->PChar) - { - CZone* PZone = map_session_data->PChar->loc.zone; - if (PZone) - { - // This should already be done in removeCharFromZone, but just to be safe... - PZone->DecreaseZoneCounter(map_session_data->PChar); - } - destroy(map_session_data->PChar); - } - destroy(map_session_data); - - map_session_list.erase(ipp); - return 0; - } - - ShowError("map_close_session: cannot close session, session not found"); - return 1; -} - /************************************************************************ * * * Timer function that cleans up all timed out players * * and removes stale dynamic targIDs after some time * + * * ************************************************************************/ int32 map_cleanup(time_point tick, CTaskMgr::CTask* PTask) { TracyZoneScoped; - map_session_list_t::iterator it = map_session_list.begin(); - - while (it != map_session_list.end()) - { - map_session_data_t* map_session_data = it->second; - - CCharEntity* PChar = map_session_data->PChar; - - if ((time(nullptr) - map_session_data->last_update) > 5) - { - if (PChar != nullptr && !PChar->isLinkDead) - { - _sql->Query("UPDATE char_flags SET disconnecting = 1 WHERE charid = %u", map_session_data->charID); - - PChar->isLinkDead = true; - PChar->updatemask |= UPDATE_HP; - - // Is this unintentionally sending extra packets when a player is disconnecting? - if (PChar->status == STATUS_TYPE::NORMAL) - { - PChar->loc.zone->SpawnPCs(PChar); - } - } - - if ((time(nullptr) - map_session_data->last_update) > settings::get("map.MAX_TIME_LASTUPDATE")) - { - bool otherMap = false; - - // check if session is attached to a different map server... - const char* fmtQuery = "select server_addr, server_port from accounts_sessions WHERE charid = %u"; - _sql->Query(fmtQuery, map_session_data->charID); - if (_sql->NextRow() == SQL_SUCCESS) - { - uint32 server_addr = _sql->GetUIntData(0); - uint32 server_port = _sql->GetUIntData(1); - - // s_addr of 0 is single process map server without IP address set explicitly in commandline - // map_port is 0 without the port being explicitly set in commandline - if ((map_ip.s_addr != 0 && server_addr != map_ip.s_addr) || (map_port != 0 && server_port != map_port)) - { - otherMap = true; - } - } - if (PChar != nullptr) - { - ShowDebug(fmt::format("Clearing map server session for player: '{}' in zone: '{}' (On other map server = {})", PChar->name, PChar->loc.zone ? PChar->loc.zone->getName() : "None", otherMap ? "Yes" : "No")); - - // Player session is attached to this map process and has stopped responding. - if (!otherMap) - { - map_session_data->PChar->StatusEffectContainer->SaveStatusEffects(true); - _sql->Query("DELETE FROM accounts_sessions WHERE charid = %u", map_session_data->charID); - - // Save position if d/c or logout/shutdown - if (map_session_data->shuttingDown == 0 || map_session_data->shuttingDown == 1) - { - charutils::SaveCharPosition(PChar); - } - } - - // uncharm pet if player d/c - if (PChar->PPet != nullptr && PChar->PPet->objtype == TYPE_MOB) - { - petutils::DespawnPet(PChar); - } - - PChar->status = STATUS_TYPE::SHUTDOWN; - - charutils::removeCharFromZone(PChar); - - destroy_arr(map_session_data->server_packet_data); - destroy(map_session_data->PChar); - destroy(map_session_data); - - map_session_list.erase(it++); - } - else - { - ShowWarning("map_cleanup: WITHOUT CHAR timed out, session closed on this process"); - if (!otherMap) - { - const char* Query = "DELETE FROM accounts_sessions WHERE charid = %u"; - _sql->Query(Query, map_session_data->charID); - } - - destroy_arr(map_session_data->server_packet_data); - destroy(map_session_data); - - map_session_list.erase(it++); - } - - continue; - } - } - else if (PChar != nullptr && PChar->isLinkDead) - { - _sql->Query("UPDATE char_flags SET disconnecting = 0 WHERE charid = %u", map_session_data->charID); - - PChar->isLinkDead = false; - PChar->updatemask |= UPDATE_HP; - - if (PChar->status == STATUS_TYPE::NORMAL) - { - PChar->loc.zone->SpawnPCs(PChar); - } - charutils::SaveCharStats(PChar); - } - ++it; - } + gMapSessions.cleanupSessions(); // clang-format off zoneutils::ForEachZone([](CZone* PZone) diff --git a/src/map/map.h b/src/map/map.h index 129e5964c39..2d786bf28f7 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -37,97 +37,27 @@ #include #include "command_handler.h" +#include "map_constants.h" +#include "map_session.h" +#include "map_session_container.h" #include "zone.h" -/************************************************************************ - * * - * Map's working session * - * * - ************************************************************************/ - -struct map_session_data_t -{ - uint32 client_addr = 0; - uint16 client_port = 0; - uint16 client_packet_id = 0; // id of the last packet that came from the client - uint16 server_packet_id = 0; // id of the last packet sent by the server - int8* server_packet_data = nullptr; // a pointer to the packet, which was previously sent to the client - size_t server_packet_size = 0; // the size of the packet that was previously sent to the client - time_t last_update = 0; // time of last packet recv - blowfish_t blowfish = {}; // unique decypher keys, these are the currently expected keys - CCharEntity* PChar = nullptr; // game char - uint8 shuttingDown = 0; // prevents double session closing - uint32 charID = 0; - - // Store old blowfish data, when a player recieves 0x00B their key should increment - // If it doesn't, and we can still successfully decrypt here, that means we need to resend 0x00B. - blowfish_t prev_blowfish = {}; - - // Used to resend 0x00B zoneout packet in case the client needs it - uint8 zone_type = 0; - uint32 zone_ipp = 0; - - void incrementBlowfish() - { - prev_blowfish = blowfish; - - blowfish.key[4] += 2; - - initBlowfish(); - } - - void initBlowfish() - { - md5((uint8*)(blowfish.key), blowfish.hash, 20); - - for (uint32 i = 0; i < 16; ++i) - { - if (blowfish.hash[i] == 0) - { - std::memset(blowfish.hash + i, 0, 16 - i); - break; - } - } - blowfish_init((int8*)blowfish.hash, 16, blowfish.P, blowfish.S[0]); - } -}; - -extern uint32 map_amntplayers; -extern int32 map_fd; - -// 2.5 updates per second -static constexpr float server_tick_rate = 2.5f; - -// Update every 400ms -static constexpr float server_tick_interval = 1000.0f / server_tick_rate; - -// Check Trigger Areas every 200ms -static constexpr float server_trigger_area_interval = server_tick_interval / 2.0f; - -typedef std::map map_session_list_t; -extern map_session_list_t map_session_list; +extern MapSessionContainer gMapSessions; extern in_addr map_ip; extern uint16 map_port; -extern inline map_session_data_t* mapsession_getbyipp(uint64 ipp); -extern inline map_session_data_t* mapsession_getbychar(CCharEntity* PChar); -extern inline map_session_data_t* mapsession_createsession(uint32 ip, uint16 port); - extern std::unique_ptr _sql; extern bool gLoadAllLua; //======================================================================= -int32 recv_parse(int8* buff, size_t* buffsize, sockaddr_in* from, map_session_data_t*); // main function to parse recv packets -int32 parse(int8* buff, size_t* buffsize, sockaddr_in* from, map_session_data_t*); // main function parsing the packets -int32 send_parse(int8* buff, size_t* buffsize, sockaddr_in* from, map_session_data_t*, bool usePreviousKey); // main function is building big packet - -void map_helpscreen(int32 flag); +int32 recv_parse(uint8* buff, size_t* buffsize, sockaddr_in* from, MapSession*); // main function to parse recv packets +int32 parse(uint8* buff, size_t* buffsize, sockaddr_in* from, MapSession*); // main function parsing the packets +int32 send_parse(uint8* buff, size_t* buffsize, sockaddr_in* from, MapSession*, bool usePreviousKey); // main function is building big packet int32 map_cleanup(time_point tick, CTaskMgr::CTask* PTask); // Clean up timed out players -int32 map_close_session(time_point tick, map_session_data_t* map_session_data); int32 map_garbage_collect(time_point tick, CTaskMgr::CTask* PTask); diff --git a/src/map/map_constants.h b/src/map/map_constants.h new file mode 100644 index 00000000000..3ebcf14227a --- /dev/null +++ b/src/map/map_constants.h @@ -0,0 +1,36 @@ +/* +=========================================================================== + + Copyright (c) 2025 LandSandBoat Dev Teams + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see http://www.gnu.org/licenses/ + +=========================================================================== +*/ + +#pragma once + +// 2.5 tick/updates per second +static constexpr auto kServerTickRate = 2.5f; + +// Tick/update every 400ms +static constexpr auto kServerTickInterval = 1000.0f / kServerTickRate; + +// Check Trigger Areas every 200ms +static constexpr auto kServerTriggerAreaInterval = kServerTickInterval / 2.0f; + +// Packet & networking constants +static constexpr auto kMaxBufferSize = 2500U; +static constexpr auto kMaxPacketPerCompression = 32U; +static constexpr auto kMaxPacketBacklogSize = kMaxPacketPerCompression * 6U; // If we hit this number, things are going very very badly. diff --git a/src/map/map_session.cpp b/src/map/map_session.cpp new file mode 100644 index 00000000000..752f7682255 --- /dev/null +++ b/src/map/map_session.cpp @@ -0,0 +1,48 @@ +/* +=========================================================================== + + Copyright (c) 2025 LandSandBoat Dev Teams + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see http://www.gnu.org/licenses/ + +=========================================================================== +*/ + +#include "map_session.h" + +#include "common/md52.h" + +void MapSession::incrementBlowfish() +{ + prev_blowfish = blowfish; + + blowfish.key[4] += 2; + + initBlowfish(); +} + +void MapSession::initBlowfish() +{ + md5((uint8*)(blowfish.key), blowfish.hash, 20); + + for (uint32 i = 0; i < 16; ++i) + { + if (blowfish.hash[i] == 0) + { + std::memset(blowfish.hash + i, 0, 16 - i); + break; + } + } + blowfish_init((int8*)blowfish.hash, 16, blowfish.P, blowfish.S[0]); +} diff --git a/src/map/map_session.h b/src/map/map_session.h new file mode 100644 index 00000000000..3ebb22baa65 --- /dev/null +++ b/src/map/map_session.h @@ -0,0 +1,59 @@ +/* +=========================================================================== + + Copyright (c) 2025 LandSandBoat Dev Teams + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see http://www.gnu.org/licenses/ + +=========================================================================== +*/ + +#pragma once + +#include "common/blowfish.h" +#include "common/cbasetypes.h" +#include "common/ipp.h" + +#include "map_constants.h" + +#include + +class CCharEntity; + +struct MapSession +{ + using Buffer = std::array; + + IPP client_ipp = {}; + uint16 client_packet_id = 0; // id of the last packet that came from the client + uint16 server_packet_id = 0; // id of the last packet sent by the server + Buffer server_packet_data = {}; // data of the packet, which was previously sent to the client + size_t server_packet_size = 0; // the size of the packet that was previously sent to the client + time_t last_update = 0; // time of last packet recv + blowfish_t blowfish = {}; // unique decypher keys, these are the currently expected keys + CCharEntity* PChar = nullptr; // game char + uint8 shuttingDown = 0; // prevents double session closing + uint32 charID = 0; + + // Store old blowfish data, when a player recieves 0x00B their key should increment + // If it doesn't, and we can still successfully decrypt here, that means we need to resend 0x00B. + blowfish_t prev_blowfish = {}; + + // Used to resend 0x00B zoneout packet in case the client needs it + uint8 zone_type = 0; + IPP zone_ipp = {}; + + void incrementBlowfish(); + void initBlowfish(); +}; diff --git a/src/map/map_session_container.cpp b/src/map/map_session_container.cpp new file mode 100644 index 00000000000..19bda2eb459 --- /dev/null +++ b/src/map/map_session_container.cpp @@ -0,0 +1,288 @@ +/* +=========================================================================== + + Copyright (c) 2025 LandSandBoat Dev Teams + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see http://www.gnu.org/licenses/ + +=========================================================================== +*/ + +#include "map_session_container.h" + +#include "map_session.h" +#include "status_effect_container.h" + +#include "common/database.h" +#include "common/socket.h" + +#include "entities/charentity.h" + +#include "utils/charutils.h" +#include "utils/petutils.h" + +auto MapSessionContainer::createSession(IPP ipp) -> MapSession* +{ + TracyZoneScoped; + + const auto ipstr = ip2str(ipp.getIP()); + + ShowDebugFmt("Creating session for {}", ipstr); + + const auto rset = db::preparedStmt("SELECT charid FROM accounts_sessions WHERE inet_ntoa(client_addr) = ? LIMIT 1", ipstr); + if (!rset) + { + ShowError("SQL query failed in mapsession_createsession!"); + return nullptr; + } + + if (rset->rowsCount() == 0) + { + // This is noisy and not really necessary + DebugSocketsFmt("recv_parse: Invalid login attempt from {}", ipstr); + return nullptr; + } + + auto map_session_data = std::make_unique(); + + map_session_data->last_update = time(nullptr); + map_session_data->client_ipp = ipp; + + sessions_[ipp] = std::move(map_session_data); + + return sessions_[ipp].get(); +} + +auto MapSessionContainer::getSessionByIPP(IPP ipp) -> MapSession* +{ + TracyZoneScoped; + + if (sessions_.find(ipp) != sessions_.end()) + { + return sessions_[ipp].get(); + } + + return nullptr; +} + +auto MapSessionContainer::getSessionByIPP(uint64 ipp) -> MapSession* +{ + TracyZoneScoped; + + auto ippObj = IPP(ipp); + + if (sessions_.find(ippObj) != sessions_.end()) + { + return sessions_[ippObj].get(); + } + + return nullptr; +} + +auto MapSessionContainer::getSessionByChar(CCharEntity* PChar) -> MapSession* +{ + TracyZoneScoped; + + if (PChar == nullptr) + { + return nullptr; + } + + for (const auto& [_, session] : sessions_) + { + if (session->PChar->id == PChar->id) + { + return session.get(); + } + } + + return nullptr; +} + +auto MapSessionContainer::getSessionByCharId(uint32 charId) -> MapSession* +{ + TracyZoneScoped; + + for (const auto& [_, session] : sessions_) + { + if (session->charID == charId) + { + return session.get(); + } + } + + return nullptr; +} + +auto MapSessionContainer::getSessionByCharName(const std::string& name) -> MapSession* +{ + TracyZoneScoped; + + for (const auto& [_, session] : sessions_) + { + if (session->PChar && session->PChar->name == name) + { + return session.get(); + } + } + + return nullptr; +} + +void MapSessionContainer::cleanupSessions() +{ + TracyZoneScoped; + + auto it = sessions_.begin(); + while (it != sessions_.end()) + { + auto& map_session_data = it->second; + + CCharEntity* PChar = map_session_data->PChar; + + if ((time(nullptr) - map_session_data->last_update) > 5) + { + if (PChar != nullptr && !PChar->isLinkDead) + { + db::preparedStmt("UPDATE char_flags SET disconnecting = 1 WHERE charid = ?", map_session_data->charID); + + PChar->isLinkDead = true; + PChar->updatemask |= UPDATE_HP; + + // Is this unintentionally sending extra packets when a player is disconnecting? + if (PChar->status == STATUS_TYPE::NORMAL) + { + PChar->loc.zone->SpawnPCs(PChar); + } + } + + if ((time(nullptr) - map_session_data->last_update) > settings::get("map.MAX_TIME_LASTUPDATE")) + { + bool otherMap = false; + + // check if session is attached to a different map server... + auto rset = db::preparedStmt("SELECT server_addr, server_port FROM accounts_sessions WHERE charid = ?", map_session_data->charID); + if (rset && rset->rowsCount() && rset->next()) + { + uint32 server_addr = rset->get("server_addr"); + uint32 server_port = rset->get("server_port"); + + // s_addr of 0 is single process map server without IP address set explicitly in commandline + // map_port is 0 without the port being explicitly set in commandline + if ((map_ip.s_addr != 0 && server_addr != map_ip.s_addr) || (map_port != 0 && server_port != map_port)) + { + otherMap = true; + } + } + + if (PChar != nullptr) + { + ShowDebug(fmt::format("Clearing map server session for player: '{}' in zone: '{}' (On other map server = {})", PChar->name, PChar->loc.zone ? PChar->loc.zone->getName() : "None", otherMap ? "Yes" : "No")); + + // Player session is attached to this map process and has stopped responding. + if (!otherMap) + { + map_session_data->PChar->StatusEffectContainer->SaveStatusEffects(true); + db::preparedStmt("DELETE FROM accounts_sessions WHERE charid = ?", map_session_data->charID); + + // Save position if d/c or logout/shutdown + if (map_session_data->shuttingDown == 0 || map_session_data->shuttingDown == 1) + { + charutils::SaveCharPosition(PChar); + } + } + + // uncharm pet if player d/c + if (PChar->PPet != nullptr && PChar->PPet->objtype == TYPE_MOB) + { + petutils::DespawnPet(PChar); + } + + PChar->status = STATUS_TYPE::SHUTDOWN; + + charutils::removeCharFromZone(PChar); + + destroy(map_session_data->PChar); + + sessions_.erase(it++); + } + else + { + ShowWarning("map_cleanup: WITHOUT CHAR timed out, session closed on this process"); + if (!otherMap) + { + db::preparedStmt("DELETE FROM accounts_sessions WHERE charid = ?", map_session_data->charID); + } + + sessions_.erase(it++); + } + + continue; + } + } + else if (PChar != nullptr && PChar->isLinkDead) + { + db::preparedStmt("UPDATE char_flags SET disconnecting = 0 WHERE charid = ?", map_session_data->charID); + + PChar->isLinkDead = false; + PChar->updatemask |= UPDATE_HP; + + if (PChar->status == STATUS_TYPE::NORMAL) + { + PChar->loc.zone->SpawnPCs(PChar); + } + charutils::SaveCharStats(PChar); + } + ++it; + } +} + +void MapSessionContainer::destroySession(IPP ipp) +{ + TracyZoneScoped; + + if (auto map_session_data = getSessionByIPP(ipp)) + { + destroySession(map_session_data); + } +} + +void MapSessionContainer::destroySession(MapSession* map_session_data) +{ + if (map_session_data == nullptr) + { + return; + } + + ShowDebugFmt("Closing session for {}", map_session_data->client_ipp.toString()); + + // clear accounts_sessions if character is logging out (not when zoning) + if (map_session_data->shuttingDown == 1) + { + db::preparedStmt("DELETE FROM accounts_sessions WHERE charid = ?", map_session_data->charID); + } + + if (map_session_data->PChar) + { + CZone* PZone = map_session_data->PChar->loc.zone; + if (PZone) + { + // This should already be done in removeCharFromZone, but just to be safe... + PZone->DecreaseZoneCounter(map_session_data->PChar); + } + destroy(map_session_data->PChar); + } + + sessions_.erase(map_session_data->client_ipp); +} diff --git a/src/map/map_session_container.h b/src/map/map_session_container.h new file mode 100644 index 00000000000..5631c236eca --- /dev/null +++ b/src/map/map_session_container.h @@ -0,0 +1,47 @@ +/* +=========================================================================== + + Copyright (c) 2025 LandSandBoat Dev Teams + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see http://www.gnu.org/licenses/ + +=========================================================================== +*/ + +#pragma once + +#include "common/ipp.h" + +class CCharEntity; +struct MapSession; + +class MapSessionContainer +{ +public: + auto createSession(IPP ipp) -> MapSession*; + + auto getSessionByIPP(IPP ipp) -> MapSession*; + auto getSessionByIPP(uint64 ipp) -> MapSession*; + auto getSessionByChar(CCharEntity* PChar) -> MapSession*; + auto getSessionByCharId(uint32 charId) -> MapSession*; + auto getSessionByCharName(const std::string& name) -> MapSession*; + + void cleanupSessions(); + + void destroySession(IPP ipp); + void destroySession(MapSession* map_session_data); + +private: + std::map> sessions_; +}; diff --git a/src/map/packet_system.cpp b/src/map/packet_system.cpp index 0df90f0a443..79b84628205 100644 --- a/src/map/packet_system.cpp +++ b/src/map/packet_system.cpp @@ -181,7 +181,7 @@ uint8 PacketSize[512]; -std::function PacketParser[512]; +std::function PacketParser[512]; /************************************************************************ * * @@ -228,7 +228,7 @@ namespace * * ************************************************************************/ -void SmallPacket0x000(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x000(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { ShowWarning("parse: Unhandled game packet %03hX from user: %s", (data.ref(0) & 0x1FF), PChar->getName()); } @@ -239,7 +239,7 @@ void SmallPacket0x000(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0xFFF_NOT_IMPLEMENTED(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0xFFF_NOT_IMPLEMENTED(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { ShowWarning("parse: SmallPacket is not implemented Type<%03hX>", (data.ref(0) & 0x1FF)); } @@ -252,7 +252,7 @@ void SmallPacket0xFFF_NOT_IMPLEMENTED(map_session_data_t* const PSession, CCharE * * ************************************************************************/ -void SmallPacket0x00A(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x00A(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; data.ref(0x5C) = 0; @@ -322,7 +322,7 @@ void SmallPacket0x00A(map_session_data_t* const PSession, CCharEntity* const PCh return; } - _sql->Query(fmtQuery, PChar->targid, currentZone->GetIP(), PSession->client_port, PChar->id); + _sql->Query(fmtQuery, PChar->targid, currentZone->GetIP(), PSession->client_ipp.getPort(), PChar->id); fmtQuery = "SELECT death FROM char_stats WHERE charid = %u"; int32 ret = _sql->Query(fmtQuery, PChar->id); @@ -431,7 +431,7 @@ void SmallPacket0x00A(map_session_data_t* const PSession, CCharEntity* const PCh * Before this packet is sent, all commands are blocked locally. * ************************************************************************/ -void SmallPacket0x00C(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x00C(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; PChar->pushPacket(PChar); @@ -469,7 +469,7 @@ void SmallPacket0x00C(map_session_data_t* const PSession, CCharEntity* const PCh * It is not reliable to recieve this packet, so do nothing. * ************************************************************************/ -void SmallPacket0x00D(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x00D(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -484,7 +484,7 @@ void SmallPacket0x00D(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x00F(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x00F(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; charutils::SendKeyItems(PChar); @@ -511,7 +511,7 @@ void SmallPacket0x00F(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x011(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x011(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; PSession->blowfish.status = BLOWFISH_ACCEPTED; @@ -546,7 +546,7 @@ void SmallPacket0x011(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x015(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x015(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; TracyZoneCString("Player Sync"); @@ -629,7 +629,7 @@ void SmallPacket0x015(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x016(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x016(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; uint16 targid = data.ref(0x04); @@ -696,7 +696,7 @@ void SmallPacket0x016(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x017(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x017(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; uint16 targid = data.ref(0x04); @@ -712,7 +712,7 @@ void SmallPacket0x017(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x01A(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x01A(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -1201,7 +1201,7 @@ void SmallPacket0x01A(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x01B(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x01B(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; // 0 - world pass, 2 - gold world pass; +1 - purchase @@ -1216,7 +1216,7 @@ void SmallPacket0x01B(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x01C(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x01C(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; PrintPacket(data); @@ -1228,7 +1228,7 @@ void SmallPacket0x01C(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x01E(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x01E(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -1267,7 +1267,7 @@ void SmallPacket0x01E(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x028(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x028(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; int32 quantity = data.ref(0x04); @@ -1344,7 +1344,7 @@ void SmallPacket0x028(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x029(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x029(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; uint32 quantity = data.ref(0x04); @@ -1480,7 +1480,7 @@ void SmallPacket0x029(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x032(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x032(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -1608,7 +1608,7 @@ void SmallPacket0x032(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x033(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x033(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -1716,7 +1716,7 @@ void SmallPacket0x033(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x034(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x034(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -1818,7 +1818,7 @@ void SmallPacket0x034(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x036(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x036(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -1893,7 +1893,7 @@ void SmallPacket0x036(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x037(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x037(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -1935,7 +1935,7 @@ void SmallPacket0x037(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x03A(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x03A(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; TracyZoneCString("Sort Inventory"); @@ -2008,7 +2008,7 @@ void SmallPacket0x03A(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x03B(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x03B(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; TracyZoneCString("Mannequin Equip"); @@ -2173,7 +2173,7 @@ void SmallPacket0x03B(map_session_data_t* const PSession, CCharEntity* const PCh // GP_CLI_COMMAND_BLACK_LIST // https://github.com/atom0s/XiPackets/tree/main/world/client/0x003C // Client is asking for blist because it wasn't initialized correctly? -void SmallPacket0x03C(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x03C(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; blacklistutils::SendBlacklist(PChar); @@ -2185,7 +2185,7 @@ void SmallPacket0x03C(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x03D(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x03D(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -2237,7 +2237,7 @@ void SmallPacket0x03D(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x041(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x041(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -2264,7 +2264,7 @@ void SmallPacket0x041(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x042(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x042(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -2291,7 +2291,7 @@ void SmallPacket0x042(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x04B(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x04B(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; uint8 msgChunk = data.ref(0x04); // The current chunk of the message to send (1 = start, 2 = rest of message) @@ -2418,7 +2418,7 @@ void SmallPacket0x04B(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x04D(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x04D(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -2431,7 +2431,7 @@ void SmallPacket0x04D(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x04E(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x04E(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -2444,7 +2444,7 @@ void SmallPacket0x04E(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x050(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x050(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; if (PChar->status != STATUS_TYPE::NORMAL) @@ -2497,7 +2497,7 @@ void SmallPacket0x050(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x051(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x051(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; if (PChar->status != STATUS_TYPE::NORMAL) @@ -2529,7 +2529,7 @@ void SmallPacket0x051(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x052(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x052(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; // Im guessing this is here to check if you can use A Item, as it seems useless to have this sent to server @@ -2548,7 +2548,7 @@ void SmallPacket0x052(map_session_data_t* const PSession, CCharEntity* const PCh * LockStyleSet * * * ************************************************************************/ -void SmallPacket0x053(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x053(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; uint8 count = data.ref(0x04); @@ -2661,7 +2661,7 @@ void SmallPacket0x053(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x058(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x058(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; uint16 skillID = data.ref(0x04); @@ -2690,7 +2690,7 @@ void SmallPacket0x058(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x059(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x059(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; // Do nothing. This is handled in synth state. @@ -2702,7 +2702,7 @@ void SmallPacket0x059(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x05A(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x05A(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; PChar->pushPacket(PChar); @@ -2719,7 +2719,7 @@ void SmallPacket0x05A(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x05B(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x05B(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -2766,7 +2766,7 @@ void SmallPacket0x05B(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x05C(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x05C(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -2823,7 +2823,7 @@ void SmallPacket0x05C(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x05D(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x05D(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; if (jailutils::InPrison(PChar)) @@ -2904,7 +2904,7 @@ void SmallPacket0x05D(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x05E(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x05E(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -3116,7 +3116,7 @@ void SmallPacket0x05E(map_session_data_t* const PSession, CCharEntity* const PCh // zone 245 cs 0x00C7 Password -void SmallPacket0x060(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x060(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -3134,7 +3134,7 @@ void SmallPacket0x060(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x061(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x061(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; PChar->pushPacket(PChar); @@ -3164,7 +3164,7 @@ void SmallPacket0x061(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x063(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x063(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; } @@ -3175,7 +3175,7 @@ void SmallPacket0x063(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x064(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x064(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; uint8 KeyTable = data.ref(0x4A); @@ -3209,7 +3209,7 @@ void SmallPacket0x064(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x066(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x066(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; if (settings::get("map.FISHING_ENABLE") && PChar->GetMLevel() >= settings::get("map.FISHING_MIN_LEVEL")) @@ -3224,7 +3224,7 @@ void SmallPacket0x066(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x06E(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x06E(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -3428,7 +3428,7 @@ void SmallPacket0x06E(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x06F(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x06F(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -3501,7 +3501,7 @@ void SmallPacket0x06F(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x070(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x070(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -3540,7 +3540,7 @@ void SmallPacket0x070(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x071(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x071(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -3729,7 +3729,7 @@ void SmallPacket0x071(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x074(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x074(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -3848,7 +3848,7 @@ void SmallPacket0x074(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x076(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x076(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -3869,7 +3869,7 @@ void SmallPacket0x076(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x077(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x077(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -3948,7 +3948,7 @@ void SmallPacket0x077(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x078(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x078(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -3961,7 +3961,7 @@ void SmallPacket0x078(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x083(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x083(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -4016,7 +4016,7 @@ void SmallPacket0x083(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x084(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x084(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -4045,7 +4045,7 @@ void SmallPacket0x084(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x085(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x085(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -4122,7 +4122,7 @@ void SmallPacket0x085(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x096(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x096(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -4223,7 +4223,7 @@ void SmallPacket0x096(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x09B(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x09B(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -4386,7 +4386,7 @@ void SmallPacket0x09B(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x0AA(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x0AA(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -4440,7 +4440,7 @@ void SmallPacket0x0AA(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x0A2(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x0A2(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -4455,7 +4455,7 @@ void SmallPacket0x0A2(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x0AB(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x0AB(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -4471,7 +4471,7 @@ void SmallPacket0x0AB(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x0AC(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x0AC(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -4516,7 +4516,7 @@ void SmallPacket0x0AC(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x0AD(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x0AD(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -4532,7 +4532,7 @@ void SmallPacket0x0AD(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x0B5(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x0B5(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -4847,7 +4847,7 @@ void SmallPacket0x0B5(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x0B6(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x0B6(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -4903,7 +4903,7 @@ void SmallPacket0x0B6(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x0BE(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x0BE(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -4982,7 +4982,7 @@ void SmallPacket0x0BE(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x0BF(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x0BF(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -5005,7 +5005,7 @@ void SmallPacket0x0BF(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x0C0(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x0C0(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -5022,7 +5022,7 @@ void SmallPacket0x0C0(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x0C3(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x0C3(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -5053,7 +5053,7 @@ void SmallPacket0x0C3(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x0C4(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x0C4(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -5216,7 +5216,7 @@ void SmallPacket0x0C4(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x0CB(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x0CB(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -5284,7 +5284,7 @@ void SmallPacket0x0CB(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x0D2(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x0D2(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -5306,7 +5306,7 @@ void SmallPacket0x0D2(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x0D3(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x0D3(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -5319,7 +5319,7 @@ void SmallPacket0x0D3(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x0DB(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x0DB(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -5408,7 +5408,7 @@ struct GP_CLI_CONFIG uint8_t padding00[3]; // PS2: (New; did not exist.) }; -void SmallPacket0x0DC(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x0DC(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -5514,7 +5514,7 @@ void SmallPacket0x0DC(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x0DD(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x0DD(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -5686,7 +5686,7 @@ void SmallPacket0x0DD(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x0DE(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x0DE(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -5707,7 +5707,7 @@ void SmallPacket0x0DE(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x0E0(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x0E0(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -5738,7 +5738,7 @@ void SmallPacket0x0E0(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x0E1(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x0E1(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -5759,7 +5759,7 @@ void SmallPacket0x0E1(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x0E2(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x0E2(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -5813,7 +5813,7 @@ void SmallPacket0x0E2(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x0E7(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x0E7(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -5863,7 +5863,7 @@ void SmallPacket0x0E7(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x0E8(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x0E8(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -5919,7 +5919,7 @@ void SmallPacket0x0E8(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x0EA(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x0EA(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -5959,7 +5959,7 @@ void SmallPacket0x0EA(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x0EB(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x0EB(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -5977,7 +5977,7 @@ void SmallPacket0x0EB(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x0F1(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x0F1(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -5995,7 +5995,7 @@ void SmallPacket0x0F1(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x0F2(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x0F2(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -6010,7 +6010,7 @@ void SmallPacket0x0F2(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x0F4(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x0F4(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; TracyZoneCString("Wide Scan"); @@ -6024,7 +6024,7 @@ void SmallPacket0x0F4(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x0F5(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x0F5(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -6057,7 +6057,7 @@ void SmallPacket0x0F5(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x0F6(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x0F6(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -6070,7 +6070,7 @@ void SmallPacket0x0F6(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x0FA(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x0FA(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -6258,7 +6258,7 @@ void SmallPacket0x0FA(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x0FB(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x0FB(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -6362,7 +6362,7 @@ void SmallPacket0x0FB(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x0FC(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x0FC(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -6461,7 +6461,7 @@ void SmallPacket0x0FC(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x0FD(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x0FD(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -6535,7 +6535,7 @@ void SmallPacket0x0FD(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x0FE(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x0FE(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -6617,7 +6617,7 @@ void SmallPacket0x0FE(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x0FF(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x0FF(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; uint16 itemID = data.ref(0x04); @@ -6658,7 +6658,7 @@ void SmallPacket0x0FF(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x100(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x100(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; if (PChar->loc.zone->CanUseMisc(MISC_MOGMENU) || PChar->m_moghouseID) @@ -6782,7 +6782,7 @@ void SmallPacket0x100(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x102(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x102(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; uint8 job = data.ref(0x08); @@ -6955,7 +6955,7 @@ void SmallPacket0x102(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x104(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x104(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; CCharEntity* PTarget = (CCharEntity*)PChar->GetEntity(PChar->BazaarID.targid, TYPE_PC); @@ -6985,7 +6985,7 @@ void SmallPacket0x104(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x105(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x105(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; if (PChar->BazaarID.id != 0) @@ -7039,7 +7039,7 @@ void SmallPacket0x105(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x106(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x106(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; uint8 Quantity = data.ref(0x08); @@ -7189,7 +7189,7 @@ void SmallPacket0x106(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x109(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x109(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -7206,7 +7206,7 @@ void SmallPacket0x109(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x10A(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x10A(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; uint8 slotID = data.ref(0x04); @@ -7251,7 +7251,7 @@ void SmallPacket0x10A(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x10B(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x10B(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; for (std::size_t i = 0; i < PChar->BazaarCustomers.size(); ++i) @@ -7279,7 +7279,7 @@ void SmallPacket0x10B(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x10C(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x10C(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; if (settings::get("main.ENABLE_ROE")) @@ -7297,7 +7297,7 @@ void SmallPacket0x10C(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x10D(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x10D(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; if (settings::get("main.ENABLE_ROE")) @@ -7313,7 +7313,7 @@ void SmallPacket0x10D(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x10E(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x10E(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; if (settings::get("main.ENABLE_ROE")) @@ -7329,7 +7329,7 @@ void SmallPacket0x10E(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x10F(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x10F(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; PChar->pushPacket(PChar); @@ -7341,7 +7341,7 @@ void SmallPacket0x10F(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x110(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x110(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; if (settings::get("map.FISHING_ENABLE") && PChar->GetMLevel() >= settings::get("map.FISHING_MIN_LEVEL")) @@ -7356,7 +7356,7 @@ void SmallPacket0x110(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x111(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x111(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; charutils::SetStyleLock(PChar, data.ref(0x04)); @@ -7369,7 +7369,7 @@ void SmallPacket0x111(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x112(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x112(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; // Send spark updates @@ -7400,7 +7400,7 @@ void SmallPacket0x112(map_session_data_t* const PSession, CCharEntity* const PCh * /sitchair * * * ************************************************************************/ -void SmallPacket0x113(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x113(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; @@ -7444,7 +7444,7 @@ void SmallPacket0x113(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x114(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x114(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; PChar->pushPacket(PChar); @@ -7456,7 +7456,7 @@ void SmallPacket0x114(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x115(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x115(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; PChar->pushPacket(PChar); @@ -7468,7 +7468,7 @@ void SmallPacket0x115(map_session_data_t* const PSession, CCharEntity* const PCh * This stub only handles the needed RoE updates. * * * ************************************************************************/ -void SmallPacket0x116(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x116(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; PChar->pushPacket(PChar); @@ -7482,7 +7482,7 @@ void SmallPacket0x116(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x117(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x117(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; PChar->pushPacket(PChar); @@ -7495,7 +7495,7 @@ void SmallPacket0x117(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x118(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x118(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { bool active = data.ref(0x04); if (PChar->PUnityChat) @@ -7513,7 +7513,7 @@ void SmallPacket0x118(map_session_data_t* const PSession, CCharEntity* const PCh * Request Emote List * * * ************************************************************************/ -void SmallPacket0x119(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x119(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { PChar->pushPacket(PChar); } @@ -7523,7 +7523,7 @@ void SmallPacket0x119(map_session_data_t* const PSession, CCharEntity* const PCh * Set Job Master Display * * * ************************************************************************/ -void SmallPacket0x11B(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x11B(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { PChar->m_jobMasterDisplay = data.ref(0x04) > 0; @@ -7537,7 +7537,7 @@ void SmallPacket0x11B(map_session_data_t* const PSession, CCharEntity* const PCh * * ************************************************************************/ -void SmallPacket0x11D(map_session_data_t* const PSession, CCharEntity* const PChar, CBasicPacket& data) +void SmallPacket0x11D(MapSession* const PSession, CCharEntity* const PChar, CBasicPacket& data) { TracyZoneScoped; if (jailutils::InPrison(PChar)) diff --git a/src/map/packet_system.h b/src/map/packet_system.h index 25c32f5819f..501c77f133f 100644 --- a/src/map/packet_system.h +++ b/src/map/packet_system.h @@ -27,11 +27,11 @@ #include "entities/charentity.h" -struct map_session_data_t; +struct MapSession; extern uint8 PacketSize[512]; -extern std::function PacketParser[512]; +extern std::function PacketParser[512]; void PrintPacket(CBasicPacket& data); void PacketParserInitialize(); diff --git a/src/map/packets/server_ip.cpp b/src/map/packets/server_ip.cpp index 6efbb54f390..02bef20f17e 100644 --- a/src/map/packets/server_ip.cpp +++ b/src/map/packets/server_ip.cpp @@ -25,14 +25,14 @@ #include "server_ip.h" #include "utils/zoneutils.h" -CServerIPPacket::CServerIPPacket(CCharEntity* PChar, uint8 zone_type, uint64 zone_ipp) +CServerIPPacket::CServerIPPacket(CCharEntity* PChar, uint8 zone_type, IPP zone_ipp) { this->setType(0x0B); this->setSize(0x1C); ref(0x04) = zone_type; - ref(0x08) = (uint32)zone_ipp; - ref(0x0C) = (uint16)(zone_ipp >> 32); + ref(0x08) = zone_ipp.getIP(); + ref(0x0C) = zone_ipp.getPort(); } uint8 CServerIPPacket::zoneType() @@ -40,7 +40,9 @@ uint8 CServerIPPacket::zoneType() return ref(0x04); } -uint64 CServerIPPacket::zoneIPP() +IPP CServerIPPacket::zoneIPP() { - return ref(0x08) | (uint64)ref(0x0C) << 32; + const auto ip = ref(0x08); + const auto port = ref(0x0C); + return IPP(ip, port); } diff --git a/src/map/packets/server_ip.h b/src/map/packets/server_ip.h index f24c3c26ee1..2b233bd2c81 100644 --- a/src/map/packets/server_ip.h +++ b/src/map/packets/server_ip.h @@ -23,6 +23,7 @@ #define _CSERVERIPPACKET_H #include "common/cbasetypes.h" +#include "common/ipp.h" #include "basic.h" @@ -31,10 +32,10 @@ class CCharEntity; class CServerIPPacket : public CBasicPacket { public: - CServerIPPacket(CCharEntity* PChar, uint8 zone_type, uint64 zone_ipp); + CServerIPPacket(CCharEntity* PChar, uint8 zone_type, IPP zone_ipp); - uint8 zoneType(); - uint64 zoneIPP(); + uint8 zoneType(); + IPP zoneIPP(); }; #endif diff --git a/src/map/utils/charutils.cpp b/src/map/utils/charutils.cpp index 139e2b224a6..da3a1caedcb 100644 --- a/src/map/utils/charutils.cpp +++ b/src/map/utils/charutils.cpp @@ -6582,7 +6582,7 @@ namespace charutils charutils::forceSynthCritFail("SendToZone", PChar); } - PChar->pushPacket(PChar, static_cast(type), ipp); + PChar->pushPacket(PChar, static_cast(type), IPP(ipp)); removeCharFromZone(PChar); } @@ -7231,16 +7231,7 @@ namespace charutils void removeCharFromZone(CCharEntity* PChar) { - map_session_data_t* PSession = nullptr; - - for (auto session : map_session_list) - { - if (session.second->charID == PChar->id) - { - PSession = session.second; - break; - } - } + MapSession* PSession = gMapSessions.getSessionByCharId(PChar->id); // Store old blowfish, recalculate expected new blowfish if (PSession) diff --git a/src/map/zone.cpp b/src/map/zone.cpp index 535b9dfb5d7..86549ef538e 100644 --- a/src/map/zone.cpp +++ b/src/map/zone.cpp @@ -962,8 +962,8 @@ void CZone::createZoneTimers() { TracyZoneScoped; - const auto tickInterval = std::chrono::milliseconds(static_cast(server_tick_interval)); - const auto triggerAreaInterval = std::chrono::milliseconds(static_cast(server_trigger_area_interval)); + const auto tickInterval = std::chrono::milliseconds(static_cast(kServerTickInterval)); + const auto triggerAreaInterval = std::chrono::milliseconds(static_cast(kServerTriggerAreaInterval)); // clang-format off ZoneTimer = CTaskMgr::getInstance()->AddTask(m_zoneName, server_clock::now(), this, CTaskMgr::TASK_INTERVAL, tickInterval, diff --git a/src/world/conquest_system.cpp b/src/world/conquest_system.cpp index 39c8ca9d45a..06ddc7e9e0c 100644 --- a/src/world/conquest_system.cpp +++ b/src/world/conquest_system.cpp @@ -24,6 +24,7 @@ #include "ipc_server.h" #include "common/database.h" +#include "common/ipp.h" ConquestSystem::ConquestSystem(WorldServer& worldServer) : worldServer_(worldServer) diff --git a/tools/fuzzer.cpp b/tools/fuzzer.cpp index 1ef9b13d18d..0e78a16d962 100644 --- a/tools/fuzzer.cpp +++ b/tools/fuzzer.cpp @@ -1,5 +1,5 @@ -#include #include +#include // https://llvm.org/docs/LibFuzzer.html // https://github.com/google/fuzzing/blob/master/docs/structure-aware-fuzzing.md @@ -7,12 +7,12 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) { // TODO: - //map_session_data_t map_session_data; - //CCharEntity CChar; + // MapSession map_session_data; + // CCharEntity CChar; - //auto packet = CBasicPacket(reinterpret_cast(Data)); + // auto packet = CBasicPacket(reinterpret_cast(Data)); - //PacketParser[SmallPD_Type](&map_session_data, &CChar, packet); + // PacketParser[SmallPD_Type](&map_session_data, &CChar, packet); return 0; } From e2e1fdc96cecc29a615088562f37e8a8333ae886 Mon Sep 17 00:00:00 2001 From: Zach Toogood Date: Sun, 16 Mar 2025 17:47:31 +0000 Subject: [PATCH 2/4] Core: Make more use of gMapIPP --- src/common/ipp.cpp | 49 ++++++++++++++++----------- src/common/ipp.h | 10 ++++-- src/common/socket.cpp | 5 +-- src/common/socket.h | 6 ++-- src/login/connect_server.cpp | 11 ++---- src/login/data_session.cpp | 6 ++-- src/map/alliance.cpp | 5 ++- src/map/ipc_client.cpp | 18 ++++------ src/map/map.cpp | 56 +++++++++++++++---------------- src/map/map.h | 12 +++---- src/map/map_session_container.cpp | 10 +++--- src/map/transport.cpp | 8 ++--- src/map/utils/instanceutils.cpp | 4 +-- src/map/utils/moduleutils.cpp | 4 +-- src/map/utils/zoneutils.cpp | 13 ++++--- src/map/zone.cpp | 2 +- src/world/ipc_server.cpp | 8 ++--- src/world/zone_settings.h | 3 +- 18 files changed, 113 insertions(+), 117 deletions(-) diff --git a/src/common/ipp.cpp b/src/common/ipp.cpp index 29a57808f66..5990d987095 100644 --- a/src/common/ipp.cpp +++ b/src/common/ipp.cpp @@ -21,35 +21,48 @@ #include "ipp.h" +// Converts a network-order IP to a host-order string. auto ip2str(uint32 ip) -> std::string { - uint32 reversed_ip = htonl(ip); - char address[INET_ADDRSTRLEN]; - inet_ntop(AF_INET, &reversed_ip, address, INET_ADDRSTRLEN); - - // This is internal, so we can trust it. + char address[INET_ADDRSTRLEN]; + inet_ntop(AF_INET, &ip, address, INET_ADDRSTRLEN); return fmt::format("{}", asStringFromUntrustedSource(address)); } -auto str2ip(const char* ip_str) -> uint32 +// Converts a host-order string to a network-order IP. +auto str2ip(const std::string& ip_str) -> uint32 { uint32 ip = 0; - inet_pton(AF_INET, ip_str, &ip); - return ntohl(ip); + inet_pton(AF_INET, ip_str.c_str(), &ip); + return ip; +} + +// Extracts the network-order IP from sockaddr_in. +auto sockaddr2netip(const sockaddr_in& addr) -> uint32 +{ +#ifdef _WIN32 + return addr.sin_addr.S_un.S_addr; +#else + return addr.sin_addr.s_addr; +#endif +} + +// Extracts the host-order port from sockaddr_in. +auto sockaddr2hostport(const sockaddr_in& addr) -> uint16 +{ + return ntohs(addr.sin_port); } IPP::IPP() { } -// TODO: Documentation about whether ip needs to be in network byte order. IPP::IPP(const uint32 ip, const uint16 port) : ip_(ip) , port_(port) { } -// TODO: Documentation about whether ip needs to be in network byte order. IPP::IPP(const uint64& ipp) : IPP(static_cast(ipp), static_cast(ipp >> 32)) { @@ -60,15 +73,6 @@ IPP::IPP(const zmq::message_t& message) { } -IPP::IPP(const sockaddr_in& address) -#ifdef WIN32 -: IPP(ntohl(address.sin_addr.S_un.S_addr), ntohs(address.sin_port)) -#else -: IPP(ntohl(address.sin_addr.s_addr), ntohs(address.sin_port)) -#endif -{ -} - auto IPP::getRawIPP() const -> uint64 { return static_cast(ip_) | (static_cast(port_) << 32); @@ -79,6 +83,11 @@ auto IPP::getIP() const -> uint32 return ip_; } +auto IPP::getIPString() const -> std::string +{ + return ip2str(ip_); +} + auto IPP::getPort() const -> uint16 { return port_; @@ -86,7 +95,7 @@ auto IPP::getPort() const -> uint16 auto IPP::toString() const -> std::string { - return fmt::format("{}:{}", ip2str(ip_), port_); + return fmt::format("{}:{}", getIPString(), port_); } auto IPP::toZMQMessage() const -> zmq::message_t diff --git a/src/common/ipp.h b/src/common/ipp.h index ec617f2b009..2de1dc29e81 100644 --- a/src/common/ipp.h +++ b/src/common/ipp.h @@ -29,7 +29,9 @@ #include auto ip2str(uint32 ip) -> std::string; -auto str2ip(const char* ip_str) -> uint32; +auto str2ip(const std::string& ip_str) -> uint32; +auto sockaddr2netip(const sockaddr_in& addr) -> uint32; +auto sockaddr2hostport(const sockaddr_in& addr) -> uint16; class IPP final { @@ -38,10 +40,10 @@ class IPP final explicit IPP(const uint32 ip, const uint16 port); explicit IPP(const uint64& ipp); explicit IPP(const zmq::message_t& message); - explicit IPP(const sockaddr_in& address); auto getRawIPP() const -> uint64; auto getIP() const -> uint32; + auto getIPString() const -> std::string; auto getPort() const -> uint16; auto toString() const -> std::string; @@ -54,7 +56,9 @@ class IPP final auto operator<(const IPP& other) const -> bool; private: - // TODO: Can we enforce whether this is in network byte order? + // IP is always stored and used in network byte order. uint32 ip_{}; + + // Port is always stored and used in host byte order (human-readable). uint16 port_{}; }; diff --git a/src/common/socket.cpp b/src/common/socket.cpp index f832c90dd97..839c931a1d5 100644 --- a/src/common/socket.cpp +++ b/src/common/socket.cpp @@ -20,6 +20,7 @@ */ #include "common/cbasetypes.h" +#include "common/ipp.h" #include "common/kernel.h" #include "common/logging.h" #include "common/mmo.h" @@ -270,13 +271,13 @@ void socket_init_udp() last_tick = time(nullptr); } -int32 recvudp(int32 fd, void* buff, size_t nbytes, int32 flags, struct sockaddr* from, socklen_t* addrlen) +int32 recvudp(int32 fd, void* buff, size_t nbytes, int32 flags, sockaddr* from, socklen_t* addrlen) { TracyZoneScoped; return sRecvfrom(fd, (char*)buff, (int)nbytes, flags, from, addrlen); } -int32 sendudp(int32 fd, void* buff, size_t nbytes, int32 flags, const struct sockaddr* from, socklen_t addrlen) +int32 sendudp(int32 fd, void* buff, size_t nbytes, int32 flags, const sockaddr* from, socklen_t addrlen) { TracyZoneScoped; return sSendto(fd, (const char*)buff, (int)nbytes, flags, from, addrlen); diff --git a/src/common/socket.h b/src/common/socket.h index 8dd1c623654..2161d34025a 100644 --- a/src/common/socket.h +++ b/src/common/socket.h @@ -26,6 +26,8 @@ #include "common/cbasetypes.h" #endif +class IPP; + #ifdef __APPLE__ #include #endif @@ -158,8 +160,8 @@ int32 makeBind_udp(uint32 ip, uint16 port); void socket_init_udp(void); -int32 recvudp(int32 fd, void* buff, size_t nbytes, int32 flags, struct sockaddr* from, socklen_t* addrlen); -int32 sendudp(int32 fd, void* buff, size_t nbytes, int32 flags, const struct sockaddr* from, socklen_t addrlen); +int32 recvudp(int32 fd, void* buff, size_t nbytes, int32 flags, sockaddr* from, socklen_t* addrlen); +int32 sendudp(int32 fd, void* buff, size_t nbytes, int32 flags, const sockaddr* from, socklen_t addrlen); template auto ref(U* buf, std::size_t index) -> T& diff --git a/src/login/connect_server.cpp b/src/login/connect_server.cpp index 1e6df4fa8ca..fa8935cd775 100644 --- a/src/login/connect_server.cpp +++ b/src/login/connect_server.cpp @@ -32,15 +32,10 @@ namespace { // We will only ever have a single login server, so we can use different logic for the routing id - const auto ip = settings::get("network.LOGIN_AUTH_IP"); - const uint64 port = settings::get("network.LOGIN_AUTH_PORT"); + const auto ip = str2ip(settings::get("network.LOGIN_AUTH_IP")); + const auto port = settings::get("network.LOGIN_AUTH_PORT"); - uint64 ipp{}; - inet_pton(AF_INET, ip.c_str(), &ipp); - - ipp |= (port << 32); - - return ipp; + return IPP(ip, port).getRawIPP(); } } // namespace diff --git a/src/login/data_session.cpp b/src/login/data_session.cpp index 1a76690f02d..d1047061efd 100644 --- a/src/login/data_session.cpp +++ b/src/login/data_session.cpp @@ -259,7 +259,7 @@ void data_session::read_func() } uint32 charid = session.requestedCharacterID; - uint32 accountIP = str2ip(ipAddress.c_str()); + uint32 accountIP = str2ip(ipAddress); uint32 ZoneIP = 0; uint16 ZonePort = 0; @@ -283,7 +283,7 @@ void data_session::read_func() key3[16] += 6; } - inet_pton(AF_INET, rset->get("zoneip").c_str(), &ZoneIP); + ZoneIP = str2ip(rset->get("zoneip")); ZonePort = rset->get("zoneport"); characterSelectionResponse.server_ip = ZoneIP; @@ -301,7 +301,7 @@ void data_session::read_func() characterSelectionResponse.server_id = (charid >> 16) & 0xFF; // Looks wrong? shouldn't this be a server index? ShowInfo(fmt::format("data_session: zoneid:({}), zoneip:({}), zoneport:({}) for char:({})", - ZoneID, ip2str(ntohl(ZoneIP)), ZonePort, charid)); + ZoneID, ip2str(ZoneIP), ZonePort, charid)); // Check the number of sessions uint16 sessionCount = 0; diff --git a/src/map/alliance.cpp b/src/map/alliance.cpp index 9de677f742d..5bf7fab5368 100644 --- a/src/map/alliance.cpp +++ b/src/map/alliance.cpp @@ -85,10 +85,13 @@ void CAlliance::dissolveAlliance(bool playerInitiated) } else { + const auto ip = gMapIPP.getIP(); + const auto port = gMapIPP.getPort(); + _sql->Query("UPDATE accounts_parties JOIN accounts_sessions USING (charid) " "SET allianceid = 0, partyflag = partyflag & ~%d " "WHERE allianceid = %u AND IF(%u = 0 AND %u = 0, true, server_addr = %u AND server_port = %u)", - ALLIANCE_LEADER | PARTY_SECOND | PARTY_THIRD, m_AllianceID, map_ip.s_addr, map_port, map_ip.s_addr, map_port); + ALLIANCE_LEADER | PARTY_SECOND | PARTY_THIRD, m_AllianceID, ip, port, ip, port); // Remove all parties. The `delParty` call removes a party from `partyList`. while (partyList.size() > 0) diff --git a/src/map/ipc_client.cpp b/src/map/ipc_client.cpp index fd4943ff473..69d28a5672e 100644 --- a/src/map/ipc_client.cpp +++ b/src/map/ipc_client.cpp @@ -60,27 +60,21 @@ namespace auto getZMQRoutingId() -> uint64 { - // Original IPP/RoutingId logic - - uint64 ipp = map_ip.s_addr; - uint64 port = map_port; + auto ip = gMapIPP.getIP(); + auto port = gMapIPP.getPort(); // if no ip/port were supplied, set to 1 (0 is not valid for an identity) - if (map_ip.s_addr == 0 && map_port == 0) + if (ip == 0 && port == 0) { const auto rset = db::preparedStmt("SELECT zoneip, zoneport FROM zone_settings GROUP BY zoneip, zoneport ORDER BY COUNT(*) DESC"); if (rset && rset->rowsCount() && rset->next()) { - const auto zoneip = rset->get("zoneip"); - const auto zoneport = rset->get("zoneport"); - - inet_pton(AF_INET, zoneip.c_str(), &ipp); - port = zoneport; + ip = str2ip(rset->get("zoneip")); + port = rset->get("zoneport"); } } - ipp |= (port << 32); - + auto ipp = IPP(ip, port).getRawIPP(); if (ipp == 0) { ShowWarning("ZMQ Routing ID IPP calculated as 0 - setting to 1. Check your zone_settings!"); diff --git a/src/map/map.cpp b/src/map/map.cpp index 268a211d83f..22861f37ed8 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -89,21 +89,10 @@ #include #endif -// TODO: Why do we have this additional +20? -std::array g_PBuff; // Global packet clipboard -std::array g_PBuffCopy; // Copy of above, used to decrypt a second time if necessary. -std::array g_PTempBuff; // Temporary packet clipboard -std::array g_PDecompressBuff; // Temporary packet clipboard - -// main socket -int32 map_fd = 0; -in_addr map_ip = {}; -uint16 map_port = 0; +IPP gMapIPP; MapSessionContainer gMapSessions; -nonstd::jthread messageThread; - std::unique_ptr _sql; extern std::map g_PZoneList; // Global array of pointers for zones @@ -116,6 +105,18 @@ extern std::atomic gProcessLoaded; namespace { + // Map UDP socket file descriptor + int32 map_fd = 0; + + // TODO: Why do we have this additional +20? + std::array g_PBuff; // Global packet clipboard + std::array g_PBuffCopy; // Copy of above, used to decrypt a second time if necessary. + std::array g_PTempBuff; // Temporary packet clipboard + std::array g_PDecompressBuff; // Temporary packet clipboard + + // ZMQ message thread + nonstd::jthread messageThread; + // Runtime statistics uint32 TotalPacketsToSendPerTick = 0U; uint32 TotalPacketsSentPerTick = 0U; @@ -215,21 +216,19 @@ int32 do_init(int32 argc, char** argv) ShowInfo("do_init: begin server initialization"); // These aren't set unless --ip or --port is set, respectively. - map_ip.s_addr = 0; - map_port = 0; + auto mapIP = 0; + auto mapPort = 0; // TODO: Replace with argparse::ArgumentParser for (int i = 1; i < argc; i++) { if (strcmp(argv[i], "--ip") == 0) { - uint32 ip = 0; - inet_pton(AF_INET, argv[i + 1], &ip); - map_ip.s_addr = ip; + mapIP = str2ip(argv[i + 1]); } else if (strcmp(argv[i], "--port") == 0) { - map_port = std::stoi(argv[i + 1]); + mapPort = std::stoi(argv[i + 1]); } else if (strcmp(argv[i], "--load_all") == 0) { @@ -237,7 +236,10 @@ int32 do_init(int32 argc, char** argv) } } - ShowInfoFmt("map_port: {}", map_port); + gMapIPP = IPP(mapIP, mapPort); + + ShowInfoFmt("map_ip: {}", gMapIPP.getIPString()); + ShowInfoFmt("map_port: {}", gMapIPP.getPort()); ShowInfoFmt("Zones assigned to this process: {}", zoneutils::GetZonesAssignedToThisProcess().size()); srand((uint32)time(nullptr)); @@ -260,7 +262,7 @@ int32 do_init(int32 argc, char** argv) PacketParserInitialize(); _sql->Query("DELETE FROM accounts_sessions WHERE IF(%u = 0 AND %u = 0, true, server_addr = %u AND server_port = %u)", - map_ip.s_addr, map_port, map_ip.s_addr, map_port); + gMapIPP.getIP(), gMapIPP.getPort(), gMapIPP.getIP(), gMapIPP.getPort()); ShowInfo("do_init: zlib is reading"); zlib_init(); @@ -322,8 +324,8 @@ int32 do_init(int32 argc, char** argv) monstrosity::LoadStaticData(); - ShowInfo("do_init: server is binding with port %u", map_port == 0 ? settings::get("network.MAP_PORT") : map_port); - map_fd = makeBind_udp(INADDR_ANY, map_port == 0 ? settings::get("network.MAP_PORT") : map_port); + ShowInfo("do_init: server is binding with port %u", gMapIPP.getPort() == 0 ? settings::get("network.MAP_PORT") : gMapIPP.getPort()); + map_fd = makeBind_udp(INADDR_ANY, gMapIPP.getPort() == 0 ? settings::get("network.MAP_PORT") : gMapIPP.getPort()); CVanaTime::getInstance()->setCustomEpoch(settings::get("map.VANADIEL_TIME_EPOCH")); @@ -504,7 +506,9 @@ int32 do_sockets(fd_set* rfd, duration next) ret = recvudp(map_fd, g_PBuff.data(), kMaxBufferSize, 0, (struct sockaddr*)&from, &fromlen); if (ret != -1) { - const auto ipp = IPP(from); + const auto ip = sockaddr2netip(from); + const auto port = sockaddr2hostport(from); + const auto ipp = IPP(ip, port); // find player char MapSession* map_session_data = gMapSessions.getSessionByIPP(ipp); @@ -590,11 +594,7 @@ int32 map_decipher_packet(uint8* buff, size_t size, sockaddr_in* from, MapSessio tmp = (uint16)((size - FFXI_HEADER_SIZE) / 4); tmp -= tmp % 2; -#ifdef WIN32 - uint32 ip = ntohl(from->sin_addr.S_un.S_addr); -#else - uint32 ip = ntohl(from->sin_addr.s_addr); -#endif + const auto ip = sockaddr2netip(*from); for (i = 0; i < tmp; i += 2) { diff --git a/src/map/map.h b/src/map/map.h index 2d786bf28f7..c506d01f71c 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -42,14 +42,14 @@ #include "map_session_container.h" #include "zone.h" -extern MapSessionContainer gMapSessions; - -extern in_addr map_ip; -extern uint16 map_port; +// +// Exposed globals +// +extern MapSessionContainer gMapSessions; +extern IPP gMapIPP; extern std::unique_ptr _sql; - -extern bool gLoadAllLua; +extern bool gLoadAllLua; //======================================================================= diff --git a/src/map/map_session_container.cpp b/src/map/map_session_container.cpp index 19bda2eb459..86899678ad5 100644 --- a/src/map/map_session_container.cpp +++ b/src/map/map_session_container.cpp @@ -36,11 +36,9 @@ auto MapSessionContainer::createSession(IPP ipp) -> MapSession* { TracyZoneScoped; - const auto ipstr = ip2str(ipp.getIP()); + ShowDebugFmt("Creating session for {}", ipp.getIPString()); - ShowDebugFmt("Creating session for {}", ipstr); - - const auto rset = db::preparedStmt("SELECT charid FROM accounts_sessions WHERE inet_ntoa(client_addr) = ? LIMIT 1", ipstr); + const auto rset = db::preparedStmt("SELECT charid FROM accounts_sessions WHERE client_addr = ? LIMIT 1", ipp.getIP()); if (!rset) { ShowError("SQL query failed in mapsession_createsession!"); @@ -50,7 +48,7 @@ auto MapSessionContainer::createSession(IPP ipp) -> MapSession* if (rset->rowsCount() == 0) { // This is noisy and not really necessary - DebugSocketsFmt("recv_parse: Invalid login attempt from {}", ipstr); + DebugSocketsFmt("recv_parse: Invalid login attempt from {}", ipp.getIPString()); return nullptr; } @@ -180,7 +178,7 @@ void MapSessionContainer::cleanupSessions() // s_addr of 0 is single process map server without IP address set explicitly in commandline // map_port is 0 without the port being explicitly set in commandline - if ((map_ip.s_addr != 0 && server_addr != map_ip.s_addr) || (map_port != 0 && server_port != map_port)) + if ((gMapIPP.getIP() != 0 && server_addr != gMapIPP.getIP()) || (gMapIPP.getPort() != 0 && server_port != gMapIPP.getPort())) { otherMap = true; } diff --git a/src/map/transport.cpp b/src/map/transport.cpp index 53462e6d71a..26ab4d7c8b7 100644 --- a/src/map/transport.cpp +++ b/src/map/transport.cpp @@ -124,10 +124,7 @@ void CTransportHandler::InitializeTransport() zone_settings ON ((transport >> 12) & 0xFFF) = zoneid WHERE \ IF(%d <> 0, '%s' = zoneip AND %d = zoneport, TRUE)"; - char address[INET_ADDRSTRLEN]; - inet_ntop(AF_INET, &map_ip, address, INET_ADDRSTRLEN); - int32 ret = _sql->Query(fmtQuery, map_ip.s_addr, address, map_port); - + int32 ret = _sql->Query(fmtQuery, gMapIPP.getIP(), gMapIPP.getIPString(), gMapIPP.getPort()); if (ret != SQL_ERROR && _sql->NumRows() != 0) { while (_sql->NextRow() == SQL_SUCCESS) @@ -189,8 +186,7 @@ void CTransportHandler::InitializeTransport() zone_settings ON zone = zoneid WHERE \ IF(%d <> 0, '%s' = zoneip AND %d = zoneport, TRUE)"; - ret = _sql->Query(fmtQuery, map_ip.s_addr, address, map_port); - + ret = _sql->Query(fmtQuery, gMapIPP.getIP(), gMapIPP.getIPString(), gMapIPP.getPort()); if (ret != SQL_ERROR && _sql->NumRows() != 0) { while (_sql->NextRow() == SQL_SUCCESS) diff --git a/src/map/utils/instanceutils.cpp b/src/map/utils/instanceutils.cpp index c6750a9b6ca..cec0d167c51 100644 --- a/src/map/utils/instanceutils.cpp +++ b/src/map/utils/instanceutils.cpp @@ -54,9 +54,7 @@ namespace instanceutils "ON instance_zone = zone_settings.zoneid " "WHERE IF(%d <> 0, '%s' = zoneip AND %d = zoneport, TRUE)"; - char address[INET_ADDRSTRLEN]; - inet_ntop(AF_INET, &map_ip, address, INET_ADDRSTRLEN); - int32 ret = _sql->Query(query, map_ip.s_addr, address, map_port); + int32 ret = _sql->Query(query, gMapIPP.getIP(), gMapIPP.getIPString(), gMapIPP.getPort()); if (ret != SQL_ERROR && _sql->NumRows() != 0) { diff --git a/src/map/utils/moduleutils.cpp b/src/map/utils/moduleutils.cpp index 22b54638b2d..3494d8e0188 100644 --- a/src/map/utils/moduleutils.cpp +++ b/src/map/utils/moduleutils.cpp @@ -33,8 +33,6 @@ #include #include -extern uint16 map_port; - namespace { // static storage, init and access @@ -242,7 +240,7 @@ namespace moduleutils if (parts.size() >= 3 && parts[0] == "xi" && parts[1] == "zones") { const auto zoneName = parts[2]; - const auto currentPort = map_port == 0 ? settings::get("network.MAP_PORT") : map_port; + const auto currentPort = gMapIPP.getPort() == 0 ? settings::get("network.MAP_PORT") : gMapIPP.getPort(); if (zoneSettingsPorts.find(zoneName) != zoneSettingsPorts.end() && zoneSettingsPorts[zoneName] != currentPort) { diff --git a/src/map/utils/zoneutils.cpp b/src/map/utils/zoneutils.cpp index 980608e7903..bf1cde8d32a 100644 --- a/src/map/utils/zoneutils.cpp +++ b/src/map/utils/zoneutils.cpp @@ -223,13 +223,14 @@ namespace zoneutils auto GetZonesAssignedToThisProcess() -> std::vector { - char address[INET_ADDRSTRLEN]; - inet_ntop(AF_INET, &map_ip, address, INET_ADDRSTRLEN); + const auto ip = gMapIPP.getIP(); + const auto ipStr = gMapIPP.getIPString(); + const auto port = gMapIPP.getPort(); const auto zonesQuery = fmt::format("SELECT zoneid " "FROM zone_settings " "WHERE IF({} <> 0, '{}' = zoneip AND {} = zoneport, TRUE)", - (uint32)map_ip.s_addr, address, map_port); + ip, ipStr, port); std::vector zonesOnThisProcess; @@ -1182,12 +1183,10 @@ namespace zoneutils const auto rset = db::preparedStmt(query, zoneID); if (rset && rset->rowsCount() && rset->next()) { - const auto zoneip = rset->get("zoneip"); + const auto zoneip = str2ip(rset->get("zoneip")); const auto port = rset->get("zoneport"); - inet_pton(AF_INET, zoneip.c_str(), &ipp); - - ipp |= (static_cast(port) << 32); + ipp = IPP(zoneip, port).getRawIPP(); } else { diff --git a/src/map/zone.cpp b/src/map/zone.cpp index 86549ef538e..d90141e1c73 100644 --- a/src/map/zone.cpp +++ b/src/map/zone.cpp @@ -412,8 +412,8 @@ void CZone::LoadZoneSettings() if (_sql->Query(Query, m_zoneID) != SQL_ERROR && _sql->NumRows() != 0 && _sql->NextRow() == SQL_SUCCESS) { m_zoneName.insert(0, (const char*)_sql->GetData(0)); + m_zoneIP = str2ip((const char*)_sql->GetData(1)); - inet_pton(AF_INET, (const char*)_sql->GetData(1), &m_zoneIP); m_zonePort = (uint16)_sql->GetUIntData(2); m_zoneMusic.m_songDay = (uint8)_sql->GetUIntData(3); // background music (day) m_zoneMusic.m_songNight = (uint8)_sql->GetUIntData(4); // background music (night) diff --git a/src/world/ipc_server.cpp b/src/world/ipc_server.cpp index d2fb6e79cc5..8d7f040cb19 100644 --- a/src/world/ipc_server.cpp +++ b/src/world/ipc_server.cpp @@ -69,8 +69,8 @@ auto IPCServer::getIPPForCharId(uint32 charId) -> std::optional const auto rset = db::preparedStmt("SELECT server_addr, server_port FROM accounts_sessions WHERE charid = ? LIMIT 1", charId); if (rset && rset->rowsCount() && rset->next()) { - const auto ip = rset->get("server_addr"); - const auto port = rset->get("server_port"); + const auto ip = rset->get("server_addr"); + const auto port = rset->get("server_port"); const auto ipp = IPP(ip, port); // characterCache_.updateCharacter(charId, ipp); @@ -92,8 +92,8 @@ auto IPCServer::getIPPForCharName(const std::string& charName) -> std::optional< charName); if (rset && rset->rowsCount() && rset->next()) { - const auto ip = rset->get("server_addr"); - const auto port = rset->get("server_port"); + const auto ip = rset->get("server_addr"); + const auto port = rset->get("server_port"); return IPP(ip, port); } diff --git a/src/world/zone_settings.h b/src/world/zone_settings.h index 867ac33f875..4d04ca751fc 100644 --- a/src/world/zone_settings.h +++ b/src/world/zone_settings.h @@ -56,8 +56,7 @@ class ZoneSettings final while (rset->next()) { - uint64 ip = 0; - inet_pton(AF_INET, rset->get("zoneip").c_str(), &ip); + uint64 ip = str2ip(rset->get("zoneip")); uint64 port = rset->get("zoneport"); ZoneSettingsEntry zone_settings{}; From f28028027d83fb91a94ceb5966c2fa29b0866630 Mon Sep 17 00:00:00 2001 From: Zach Toogood Date: Sun, 16 Mar 2025 20:42:04 +0000 Subject: [PATCH 3/4] Core: Simplify charutils::SendToZone --- src/map/ipc_client.cpp | 4 +- src/map/monstrosity.cpp | 2 +- src/map/packet_system.cpp | 7 ++-- src/map/utils/charutils.cpp | 83 +++++++++++++++++++------------------ src/map/utils/charutils.h | 9 +--- src/map/zone_entities.cpp | 2 +- 6 files changed, 52 insertions(+), 55 deletions(-) diff --git a/src/map/ipc_client.cpp b/src/map/ipc_client.cpp index 69d28a5672e..1c92dc38f39 100644 --- a/src/map/ipc_client.cpp +++ b/src/map/ipc_client.cpp @@ -799,7 +799,7 @@ void IPCClient::handleMessage_EntityInformationResponse(const IPP& ipp, const ip PChar->clearPacketList(); - charutils::SendToZone(PChar, ZoningType::Zoning, zoneutils::GetZoneIPP(PChar->loc.destination)); + charutils::SendToZone(PChar, PChar->loc.destination); } } } @@ -826,7 +826,7 @@ void IPCClient::handleMessage_SendPlayerToLocation(const IPP& ipp, const ipc::Se PChar->clearPacketList(); - charutils::SendToZone(PChar, ZoningType::Zoning, zoneutils::GetZoneIPP(PChar->loc.destination)); + charutils::SendToZone(PChar, PChar->loc.destination); } } diff --git a/src/map/monstrosity.cpp b/src/map/monstrosity.cpp index f66e18705dc..df90ef8942b 100644 --- a/src/map/monstrosity.cpp +++ b/src/map/monstrosity.cpp @@ -624,7 +624,7 @@ void monstrosity::HandleDeathMenu(CCharEntity* PChar, uint8 type) // Restart this zone with Gestation effect PChar->loc.destination = PChar->loc.zone->GetID(); - charutils::SendToZone(PChar, ZoningType::Zoning, zoneutils::GetZoneIPP(PChar->loc.destination)); + charutils::SendToZone(PChar, PChar->loc.destination); } } diff --git a/src/map/packet_system.cpp b/src/map/packet_system.cpp index 79b84628205..e6c099e8871 100644 --- a/src/map/packet_system.cpp +++ b/src/map/packet_system.cpp @@ -1076,7 +1076,7 @@ void SmallPacket0x01A(MapSession* const PSession, CCharEntity* const PChar, CBas PChar->status = STATUS_TYPE::DISAPPEAR; PChar->loc.boundary = 0; PChar->clearPacketList(); - charutils::SendToZone(PChar, ZoningType::Zoning, zoneutils::GetZoneIPP(PChar->loc.destination)); + charutils::SendToZone(PChar, PChar->loc.destination); } PChar->m_hasTractor = 0; @@ -3104,7 +3104,7 @@ void SmallPacket0x05E(MapSession* const PSession, CCharEntity* const PChar, CBas return; } - charutils::SendToZone(PChar, ZoningType::Zoning, ipp); + charutils::SendToZone(PChar, destination); } /************************************************************************ @@ -5263,13 +5263,12 @@ void SmallPacket0x0CB(MapSession* const PSession, CCharEntity* const PChar, CBas if (type != oldType && PChar->profile.mhflag & 0x0040) { auto zoneid = PChar->getZone(); - auto ipp = zoneutils::GetZoneIPP(zoneid); PChar->loc.destination = zoneid; PChar->status = STATUS_TYPE::DISAPPEAR; PChar->clearPacketList(); - charutils::SendToZone(PChar, ZoningType::Zoning, ipp); + charutils::SendToZone(PChar, zoneid); } } else diff --git a/src/map/utils/charutils.cpp b/src/map/utils/charutils.cpp index da3a1caedcb..96cf23f7183 100644 --- a/src/map/utils/charutils.cpp +++ b/src/map/utils/charutils.cpp @@ -6525,48 +6525,43 @@ namespace charutils } } - void SendToZone(CCharEntity* PChar, ZoningType type, uint64 ipp) + void SendToZone(CCharEntity* PChar, uint16 zoneId) { TracyZoneScoped; - if (type == ZoningType::Zoning) - { - auto ip = (uint32)ipp; - auto port = (uint32)(ipp >> 32); - _sql->Query("UPDATE accounts_sessions SET server_addr = %u, server_port = %u WHERE charid = %u", - ip, port, PChar->id); - - const char* Query = "UPDATE chars " - "SET " - "pos_zone = %u," - "pos_prevzone = %u," - "pos_rot = %u," - "pos_x = %.3f," - "pos_y = %.3f," - "pos_z = %.3f," - "moghouse = %u," - "boundary = %u " - "WHERE charid = %u"; - - _sql->Query(Query, PChar->loc.destination, - (PChar->m_moghouseID || PChar->loc.destination == PChar->getZone()) ? PChar->loc.prevzone : PChar->getZone(), PChar->loc.p.rotation, - PChar->loc.p.x, PChar->loc.p.y, PChar->loc.p.z, PChar->m_moghouseID, PChar->loc.boundary, PChar->id); - - message::send(ipc::CharZone{ - .charId = PChar->id, - .destinationZoneId = PChar->loc.destination, - }); - } - else // ZoningType::Logout + auto ipp = IPP(zoneutils::GetZoneIPP(zoneId)); + if (ipp.getIP() == 0) { - SaveCharPosition(PChar); - - message::send(ipc::CharZone{ - .charId = PChar->id, - .destinationZoneId = 0xFFFF, // Clear cache - }); + ShowError("charutils::SendToZone : Invalid zoneId %u", zoneId); + return; } + auto ip = ipp.getIP(); + auto port = ipp.getPort(); + _sql->Query("UPDATE accounts_sessions SET server_addr = %u, server_port = %u WHERE charid = %u", + ip, port, PChar->id); + + const char* Query = "UPDATE chars " + "SET " + "pos_zone = %u," + "pos_prevzone = %u," + "pos_rot = %u," + "pos_x = %.3f," + "pos_y = %.3f," + "pos_z = %.3f," + "moghouse = %u," + "boundary = %u " + "WHERE charid = %u"; + + _sql->Query(Query, PChar->loc.destination, + (PChar->m_moghouseID || PChar->loc.destination == PChar->getZone()) ? PChar->loc.prevzone : PChar->getZone(), PChar->loc.p.rotation, + PChar->loc.p.x, PChar->loc.p.y, PChar->loc.p.z, PChar->m_moghouseID, PChar->loc.boundary, PChar->id); + + message::send(ipc::CharZone{ + .charId = PChar->id, + .destinationZoneId = PChar->loc.destination, + }); + if (PChar->shouldPetPersistThroughZoning()) { PChar->setPetZoningInfo(); @@ -6582,15 +6577,23 @@ namespace charutils charutils::forceSynthCritFail("SendToZone", PChar); } - PChar->pushPacket(PChar, static_cast(type), IPP(ipp)); + PChar->pushPacket(PChar, 2, IPP(ipp)); removeCharFromZone(PChar); } + void SendDisconnect(CCharEntity* PChar) + { + TracyZoneScoped; + + SaveCharPosition(PChar); + PChar->pushPacket(PChar, 1, IPP()); + } + void ForceLogout(CCharEntity* PChar) { PChar->status = STATUS_TYPE::SHUTDOWN; - charutils::SendToZone(PChar, ZoningType::Logout, 0); + charutils::SendDisconnect(PChar); } void ForceRezone(CCharEntity* PChar) @@ -6601,7 +6604,7 @@ namespace charutils PChar->clearPacketList(); - SendToZone(PChar, ZoningType::Zoning, zoneutils::GetZoneIPP(PChar->loc.destination)); + SendToZone(PChar, PChar->loc.destination); } void HomePoint(CCharEntity* PChar, bool resetHPMP) @@ -6630,7 +6633,7 @@ namespace charutils PChar->updatemask |= UPDATE_HP; PChar->clearPacketList(); - SendToZone(PChar, ZoningType::Zoning, zoneutils::GetZoneIPP(PChar->loc.destination)); + SendToZone(PChar, PChar->loc.destination); } bool AddWeaponSkillPoints(CCharEntity* PChar, SLOTTYPE slotid, int wspoints) diff --git a/src/map/utils/charutils.h b/src/map/utils/charutils.h index ecb1afd11ec..7009427be31 100644 --- a/src/map/utils/charutils.h +++ b/src/map/utils/charutils.h @@ -50,12 +50,6 @@ enum class EMobDifficulty : uint8 MAX }; -enum class ZoningType -{ - Logout = 1, - Zoning = 2, -}; - // Capacity Bonuses applied based on RoE Completion // TODO: Add RoV Completion and Reive bonuses once implemented const std::vector> roeCapacityBonusRecords = { @@ -243,7 +237,8 @@ namespace charutils int32 GetPoints(CCharEntity* PChar, const char* type); void SetUnityLeader(CCharEntity* PChar, uint8 leaderID); auto GetConquestPointsName(CCharEntity* PChar) -> std::string; - void SendToZone(CCharEntity* PChar, ZoningType type, uint64 ipp); + void SendToZone(CCharEntity* PChar, uint16 zoneId); + void SendDisconnect(CCharEntity* PChar); void ForceLogout(CCharEntity* PChar); void ForceRezone(CCharEntity* PChar); void HomePoint(CCharEntity* PChar, bool resetHPMP); diff --git a/src/map/zone_entities.cpp b/src/map/zone_entities.cpp index ed8de446d9f..72a56268d22 100644 --- a/src/map/zone_entities.cpp +++ b/src/map/zone_entities.cpp @@ -1974,7 +1974,7 @@ void CZoneEntities::ZoneServer(time_point tick) continue; } - charutils::SendToZone(PChar, ZoningType::Zoning, ipp); + charutils::SendToZone(PChar, PChar->loc.destination); } if (tick > m_EffectCheckTime) From 78bbc6c9d7c9c32675dcfc19d6b90252f5859dc2 Mon Sep 17 00:00:00 2001 From: Zach Toogood Date: Sun, 16 Mar 2025 20:56:09 +0000 Subject: [PATCH 4/4] Core: Remove arbitrary +20 byte extension to network buffer --- src/map/map.cpp | 49 ++++++++++++++++++------------------- src/map/map_constants.h | 2 ++ src/map/map_session.h | 22 ++++++++--------- src/map/utils/charutils.cpp | 6 +++++ 4 files changed, 42 insertions(+), 37 deletions(-) diff --git a/src/map/map.cpp b/src/map/map.cpp index 22861f37ed8..04754117a8e 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -108,11 +108,10 @@ namespace // Map UDP socket file descriptor int32 map_fd = 0; - // TODO: Why do we have this additional +20? - std::array g_PBuff; // Global packet clipboard - std::array g_PBuffCopy; // Copy of above, used to decrypt a second time if necessary. - std::array g_PTempBuff; // Temporary packet clipboard - std::array g_PDecompressBuff; // Temporary packet clipboard + // Map udp buffers + NetworkBuffer PBuff; // Global packet clipboard + NetworkBuffer PBuffCopy; // Copy of above, used to decrypt a second time if necessary. + NetworkBuffer PScratchBuff; // Temporary packet clipboard // ZMQ message thread nonstd::jthread messageThread; @@ -503,7 +502,7 @@ int32 do_sockets(fd_set* rfd, duration next) sockaddr_in from{}; socklen_t fromlen = sizeof(from); - ret = recvudp(map_fd, g_PBuff.data(), kMaxBufferSize, 0, (struct sockaddr*)&from, &fromlen); + ret = recvudp(map_fd, PBuff.data(), kMaxBufferSize, 0, (struct sockaddr*)&from, &fromlen); if (ret != -1) { const auto ip = sockaddr2netip(from); @@ -524,7 +523,7 @@ int32 do_sockets(fd_set* rfd, duration next) size_t size = ret; - int32 decryptCount = recv_parse(g_PBuff.data(), &size, &from, map_session_data); + int32 decryptCount = recv_parse(PBuff.data(), &size, &from, map_session_data); if (decryptCount != -1) { // DecryptCount of 0 means the main key decrypted the packet @@ -532,9 +531,9 @@ int32 do_sockets(fd_set* rfd, duration next) { // If the previous package was lost, then we do not collect a new one, // and send the previous packet again - if (!parse(g_PBuff.data(), &size, &from, map_session_data)) + if (!parse(PBuff.data(), &size, &from, map_session_data)) { - send_parse(g_PBuff.data(), &size, &from, map_session_data, false); + send_parse(PBuff.data(), &size, &from, map_session_data, false); } } else if (decryptCount == 1 && map_session_data->blowfish.status == BLOWFISH_PENDING_ZONE) @@ -549,16 +548,16 @@ int32 do_sockets(fd_set* rfd, duration next) PChar->clearPacketList(); PChar->pushPacket(PChar, map_session_data->zone_type, map_session_data->zone_ipp); } - send_parse(g_PBuff.data(), &size, &from, map_session_data, true); + send_parse(PBuff.data(), &size, &from, map_session_data, true); // Increment sync count with every packet // TODO: match incoming with a new parse that only cares about sync count map_session_data->server_packet_id += 1; } - ret = sendudp(map_fd, g_PBuff.data(), size, 0, (const struct sockaddr*)&from, fromlen); + ret = sendudp(map_fd, PBuff.data(), size, 0, (const struct sockaddr*)&from, fromlen); - std::swap(g_PBuff, map_session_data->server_packet_data); + std::swap(PBuff, map_session_data->server_packet_data); std::swap(size, map_session_data->server_packet_size); } @@ -734,7 +733,7 @@ int32 recv_parse(uint8* buff, size_t* buffsize, sockaddr_in* from, MapSession* m if (map_session_data->blowfish.status == BLOWFISH_PENDING_ZONE) { // Copy buff into the backup buffer. Blowfish can't be rewound currently. - std::memcpy(g_PBuffCopy.data(), buff, *buffsize); + std::memcpy(PBuffCopy.data(), buff, *buffsize); } int decryptCount = 0; // char packets @@ -743,10 +742,10 @@ int32 recv_parse(uint8* buff, size_t* buffsize, sockaddr_in* from, MapSession* m // If the client is pending zone, they might not have received 0x00B, and thus not incremented their key // Check old blowfish data if (map_session_data->blowfish.status == BLOWFISH_PENDING_ZONE && - map_decipher_packet(g_PBuffCopy.data(), *buffsize, from, map_session_data, &map_session_data->prev_blowfish) != -1) + map_decipher_packet(PBuffCopy.data(), *buffsize, from, map_session_data, &map_session_data->prev_blowfish) != -1) { // Copy decrypted bytes back into buffer - std::memcpy(buff, g_PBuffCopy.data(), *buffsize); + std::memcpy(buff, PBuffCopy.data(), *buffsize); decryptCount++; } else @@ -760,14 +759,14 @@ int32 recv_parse(uint8* buff, size_t* buffsize, sockaddr_in* from, MapSession* m uint32 PacketDataSize = ref(buff, *buffsize - sizeof(int32) - 16); // it's decompressing data and getting new size - PacketDataSize = zlib_decompress((int8*)(buff + FFXI_HEADER_SIZE), PacketDataSize, (int8*)g_PDecompressBuff.data(), kMaxBufferSize); + PacketDataSize = zlib_decompress((int8*)(buff + FFXI_HEADER_SIZE), PacketDataSize, (int8*)PScratchBuff.data(), kMaxBufferSize); // Not sure why zlib_decompress is defined to return a uint32 when it returns -1 in situations. if (static_cast(PacketDataSize) != -1) { // it's making result buff // don't need std::memcpy header - std::memcpy(buff + FFXI_HEADER_SIZE, g_PDecompressBuff.data(), PacketDataSize); + std::memcpy(buff + FFXI_HEADER_SIZE, PScratchBuff.data(), PacketDataSize); *buffsize = FFXI_HEADER_SIZE + PacketDataSize; return decryptCount; @@ -906,7 +905,7 @@ int32 parse(uint8* buff, size_t* buffsize, sockaddr_in* from, MapSession* map_se ref(map_session_data->server_packet_data.data(), 2) = SmallPD_Code; ref(map_session_data->server_packet_data.data(), 8) = (uint32)time(nullptr); - g_PBuff = map_session_data->server_packet_data; + PBuff = map_session_data->server_packet_data; *buffsize = map_session_data->server_packet_size; std::memcpy(map_session_data->server_packet_data.data(), buff, *buffsize); @@ -1017,7 +1016,7 @@ int32 send_parse(uint8* buff, size_t* buffsize, sockaddr_in* from, MapSession* m // Compress the data without regard to the header // The returned size is 8 times the real data - PacketSize = zlib_compress((int8*)(buff + FFXI_HEADER_SIZE), (uint32)(*buffsize - FFXI_HEADER_SIZE), (int8*)g_PTempBuff.data(), kMaxBufferSize); + PacketSize = zlib_compress((int8*)(buff + FFXI_HEADER_SIZE), (uint32)(*buffsize - FFXI_HEADER_SIZE), (int8*)PScratchBuff.data(), kMaxBufferSize); // handle compression error if (PacketSize == static_cast(-1)) @@ -1026,7 +1025,7 @@ int32 send_parse(uint8* buff, size_t* buffsize, sockaddr_in* from, MapSession* m continue; } - ref(g_PTempBuff.data(), zlib_compressed_size(PacketSize)) = PacketSize; + ref(PScratchBuff.data(), zlib_compressed_size(PacketSize)) = PacketSize; PacketSize = (uint32)zlib_compressed_size(PacketSize) + 4; @@ -1052,17 +1051,17 @@ int32 send_parse(uint8* buff, size_t* buffsize, sockaddr_in* from, MapSession* m // Record data size excluding header uint8 hash[16]; - md5(g_PTempBuff.data(), hash, PacketSize); - std::memcpy(g_PTempBuff.data() + PacketSize, hash, 16); + md5(PScratchBuff.data(), hash, PacketSize); + std::memcpy(PScratchBuff.data() + PacketSize, hash, 16); PacketSize += 16; - if (PacketSize > kMaxBufferSize + 20) + if (PacketSize > kMaxBufferSize) { - ShowCritical("Memory manager: g_PTempBuff is overflowed (%u)", PacketSize); + ShowCritical("Memory manager: PScratchBuff is overflowed (%u)", PacketSize); } // Making total packet - std::memcpy(buff + FFXI_HEADER_SIZE, g_PTempBuff.data(), PacketSize); + std::memcpy(buff + FFXI_HEADER_SIZE, PScratchBuff.data(), PacketSize); uint32 CypherSize = (PacketSize / 4) & -2; diff --git a/src/map/map_constants.h b/src/map/map_constants.h index 3ebcf14227a..9d606e87293 100644 --- a/src/map/map_constants.h +++ b/src/map/map_constants.h @@ -34,3 +34,5 @@ static constexpr auto kServerTriggerAreaInterval = kServerTickInterval / 2.0f; static constexpr auto kMaxBufferSize = 2500U; static constexpr auto kMaxPacketPerCompression = 32U; static constexpr auto kMaxPacketBacklogSize = kMaxPacketPerCompression * 6U; // If we hit this number, things are going very very badly. + +using NetworkBuffer = std::array; diff --git a/src/map/map_session.h b/src/map/map_session.h index 3ebb22baa65..95ee4e9e570 100644 --- a/src/map/map_session.h +++ b/src/map/map_session.h @@ -33,18 +33,16 @@ class CCharEntity; struct MapSession { - using Buffer = std::array; - - IPP client_ipp = {}; - uint16 client_packet_id = 0; // id of the last packet that came from the client - uint16 server_packet_id = 0; // id of the last packet sent by the server - Buffer server_packet_data = {}; // data of the packet, which was previously sent to the client - size_t server_packet_size = 0; // the size of the packet that was previously sent to the client - time_t last_update = 0; // time of last packet recv - blowfish_t blowfish = {}; // unique decypher keys, these are the currently expected keys - CCharEntity* PChar = nullptr; // game char - uint8 shuttingDown = 0; // prevents double session closing - uint32 charID = 0; + IPP client_ipp = {}; + uint16 client_packet_id = 0; // id of the last packet that came from the client + uint16 server_packet_id = 0; // id of the last packet sent by the server + NetworkBuffer server_packet_data = {}; // data of the packet, which was previously sent to the client + size_t server_packet_size = 0; // the size of the packet that was previously sent to the client + time_t last_update = 0; // time of last packet recv + blowfish_t blowfish = {}; // unique decypher keys, these are the currently expected keys + CCharEntity* PChar = nullptr; // game char + uint8 shuttingDown = 0; // prevents double session closing + uint32 charID = 0; // Store old blowfish data, when a player recieves 0x00B their key should increment // If it doesn't, and we can still successfully decrypt here, that means we need to resend 0x00B. diff --git a/src/map/utils/charutils.cpp b/src/map/utils/charutils.cpp index 96cf23f7183..ef795325c0b 100644 --- a/src/map/utils/charutils.cpp +++ b/src/map/utils/charutils.cpp @@ -6587,6 +6587,12 @@ namespace charutils TracyZoneScoped; SaveCharPosition(PChar); + + message::send(ipc::CharZone{ + .charId = PChar->id, + .destinationZoneId = 0xFFFF, // Clear cache + }); + PChar->pushPacket(PChar, 1, IPP()); }