From 5938d3dec7fdbd2b81dfed285d0a7fd72b39dfef Mon Sep 17 00:00:00 2001 From: kimden <23140380+kimden@users.noreply.github.com> Date: Sat, 15 Mar 2025 23:36:36 +0400 Subject: [PATCH 01/34] Attempt to quickly clean up another packet (it failed dramatically) (due to pretty much everything being interconnected, I'll continue later if I can) [skip ci] --- src/items/item.cpp | 58 +++++++------ src/items/item.hpp | 9 +- src/items/network_item_manager.cpp | 29 ++++--- src/items/network_item_manager.hpp | 5 +- src/modes/free_for_all.cpp | 2 +- src/modes/free_for_all.hpp | 3 +- src/modes/linear_world.cpp | 2 +- src/modes/linear_world.hpp | 3 +- src/modes/soccer_world.cpp | 2 +- src/modes/soccer_world.hpp | 3 +- src/network/kart_data.cpp | 19 +++-- src/network/kart_data.hpp | 3 +- src/network/network_player_profile.cpp | 17 ++++ src/network/network_player_profile.hpp | 4 + src/network/packet_types.hpp | 41 +++++++++- src/network/packet_types_base.hpp | 109 ++++++++++++++++++++++++- src/network/peer_vote.hpp | 13 +-- src/network/protocols/client_lobby.cpp | 6 +- src/network/protocols/server_lobby.cpp | 104 ++++++++++++----------- src/network/protocols/server_lobby.hpp | 2 +- src/utils/lobby_settings.cpp | 8 +- src/utils/lobby_settings.hpp | 3 +- 22 files changed, 322 insertions(+), 123 deletions(-) diff --git a/src/items/item.cpp b/src/items/item.cpp index b08d87ead20..2b73334416f 100644 --- a/src/items/item.cpp +++ b/src/items/item.cpp @@ -28,6 +28,7 @@ #include "items/item_manager.hpp" #include "karts/abstract_kart.hpp" #include "modes/world.hpp" +#include "network/packet_types.hpp" #include "network/network_string.hpp" #include "network/rewind_manager.hpp" #include "tracks/arena_graph.hpp" @@ -67,21 +68,21 @@ ItemState::ItemState(ItemType type, const AbstractKart *owner, int id) //----------------------------------------------------------------------------- /** Constructor to restore item state at current ticks in client for live join */ -ItemState::ItemState(const BareNetworkString& buffer) +ItemState::ItemState(const ItemStatePacket& packet) { - m_type = (ItemType)buffer.getUInt8(); - m_original_type = (ItemType)buffer.getUInt8(); - m_ticks_till_return = buffer.getUInt32(); - m_item_id = buffer.getUInt32(); - m_deactive_ticks = buffer.getUInt32(); - m_used_up_counter = buffer.getUInt32(); - m_xyz = buffer.getVec3(); - m_original_rotation = buffer.getQuat(); + m_type = (ItemType)packet.type; + m_original_type = (ItemType)packet.original_type; + m_ticks_till_return = packet.ticks_till_return; + m_item_id = packet.item_id; + m_deactive_ticks = packet.deactive_ticks; + m_used_up_counter = packet.used_up_counter; + m_xyz = packet.xyz; + m_original_rotation = packet.original_rotation; m_previous_owner = NULL; - int8_t kart_id = buffer.getUInt8(); + int8_t kart_id = packet.previous_owner; if (kart_id != -1) m_previous_owner = World::getWorld()->getKart(kart_id); -} // ItemState(const BareNetworkString& buffer) +} // ItemState(const ItemStatePacket& packet) // ------------------------------------------------------------------------ /** Sets the disappear counter depending on type. */ @@ -185,24 +186,31 @@ void ItemState::collected(const AbstractKart *kart) // ---------------------------------------------------------------------------- /** Returns the graphical type of this item should be using (takes nolok into * account). */ -Item::ItemType ItemState::getGrahpicalType() const +Item::ItemType ItemState::getGraphicalType() const { return m_previous_owner && m_previous_owner->getIdent() == "nolok" && getType() == ITEM_BUBBLEGUM ? ITEM_BUBBLEGUM_NOLOK : getType(); -} // getGrahpicalType +} // getGraphicalType //----------------------------------------------------------------------------- /** Save item state at current ticks in server for live join */ -void ItemState::saveCompleteState(BareNetworkString* buffer) const +ItemStatePacket ItemState::saveCompleteState() const { - buffer->addUInt8((uint8_t)m_type).addUInt8((uint8_t)m_original_type) - .addUInt32(m_ticks_till_return).addUInt32(m_item_id) - .addUInt32(m_deactive_ticks).addUInt32(m_used_up_counter) - .add(m_xyz).add(m_original_rotation) - .addUInt8(m_previous_owner ? - (int8_t)m_previous_owner->getWorldKartId() : (int8_t)-1); + ItemStatePacket packet; + packet.type = m_type; + packet.original_type = m_original_type; + packet.ticks_till_return = m_ticks_till_return; + packet.item_id = m_item_id; + packet.deactive_ticks = m_deactive_ticks; + packet.used_up_counter = m_used_up_counter; + packet.xyz = m_xyz; + packet.original_rotation = m_original_rotation; + packet.previous_owner = m_previous_owner ? + m_previous_owner->getWorldKartId() : -1; + + return packet; } // saveCompleteState // ============================================================================ @@ -228,7 +236,7 @@ Item::Item(ItemType type, const Vec3& xyz, const Vec3& normal, m_animation_start_ticks = -9999; m_distance_2 = 1.2f; initItem(type, xyz, normal); - m_graphical_type = getGrahpicalType(); + m_graphical_type = getGraphicalType(); m_node = NULL; if (mesh && !GUIEngine::isNoGraphics()) @@ -256,7 +264,7 @@ Item::Item(ItemType type, const Vec3& xyz, const Vec3& normal, m_appear_anime_node = irr_driver->getSceneManager()->addEmptySceneNode(m_node); } setType(type); - handleNewMesh(getGrahpicalType()); + handleNewMesh(getGraphicalType()); if (!m_node) return; @@ -442,10 +450,10 @@ void Item::updateGraphics(float dt) if (m_node == NULL) return; - if (m_graphical_type != getGrahpicalType()) + if (m_graphical_type != getGraphicalType()) { - handleNewMesh(getGrahpicalType()); - m_graphical_type = getGrahpicalType(); + handleNewMesh(getGraphicalType()); + m_graphical_type = getGraphicalType(); } auto& stk_config = STKConfig::get(); diff --git a/src/items/item.hpp b/src/items/item.hpp index 6e319cf4fd4..b72009dc18e 100644 --- a/src/items/item.hpp +++ b/src/items/item.hpp @@ -35,6 +35,7 @@ class BareNetworkString; class AbstractKart; class LODNode; +struct ItemStatePacket; namespace irr { @@ -145,9 +146,9 @@ class ItemState public: // ------------------------------------------------------------------------ - ItemState(ItemType type, const AbstractKart *owner=NULL, int id = -1); + ItemState(ItemType type, const AbstractKart *owner=NULL, int id = -1); // ------------------------------------------------------------------------ - ItemState(const BareNetworkString& buffer); + ItemState(const ItemStatePacket& packet); // ------------------------------------------------------------------------ void initItem(ItemType type, const Vec3& xyz, const Vec3& normal); void update(int ticks); @@ -266,7 +267,7 @@ class ItemState /** Returns the type of this item. */ ItemType getType() const { return m_type; } // ------------------------------------------------------------------------ - ItemType getGrahpicalType() const; + ItemType getGraphicalType() const; // ------------------------------------------------------------------------ /** Returns the original type of this item. */ ItemType getOriginalType() const { return m_original_type; } @@ -313,7 +314,7 @@ class ItemState return m_original_rotation; } // ------------------------------------------------------------------------ - void saveCompleteState(BareNetworkString* buffer) const; + ItemStatePacket saveCompleteState() const; }; // class ItemState // ============================================================================ diff --git a/src/items/network_item_manager.cpp b/src/items/network_item_manager.cpp index 63af067085d..597f8c22e24 100644 --- a/src/items/network_item_manager.cpp +++ b/src/items/network_item_manager.cpp @@ -22,6 +22,7 @@ #include "modes/world.hpp" #include "network/network_config.hpp" #include "network/network_string.hpp" +#include "network/packet_types.hpp" #include "network/protocols/game_protocol.hpp" #include "network/rewind_manager.hpp" #include "network/stk_host.hpp" @@ -519,32 +520,36 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count) //----------------------------------------------------------------------------- /** Save all current items at current ticks in server for live join */ -void NetworkItemManager::saveCompleteState(BareNetworkString* buffer) const +NimCompleteStatePacket NetworkItemManager::saveCompleteState() const { + NimCompleteStatePacket packet; const uint32_t all_items = (uint32_t)m_all_items.size(); - buffer->addUInt32(World::getWorld()->getTicksSinceStart()) - .addUInt32(m_switch_ticks).addUInt32(all_items); + packet.ticks_since_start = World::getWorld()->getTicksSinceStart(); + packet.switch_ticks = m_switch_ticks; + packet.all_items_size = all_items; for (unsigned i = 0; i < all_items; i++) { + packet.all_items.emplace_back(); if (m_all_items[i]) { - buffer->addUInt8(1); - m_all_items[i]->saveCompleteState(buffer); + packet.all_items.back().has_item = true; + packet.all_items.back().item_state = std::make_shared(m_all_items[i]->saveCompleteState()); } else - buffer->addUInt8(0); + packet.all_items.back().has_item = false; } + return packet; } // saveCompleteState //----------------------------------------------------------------------------- /** Restore all current items at current ticks in client for live join * or at the start of a race. */ -void NetworkItemManager::restoreCompleteState(const BareNetworkString& buffer) +void NetworkItemManager::restoreCompleteState(const NimCompleteStatePacket& packet) { - m_confirmed_state_time = buffer.getUInt32(); - m_confirmed_switch_ticks = buffer.getUInt32(); - uint32_t all_items = buffer.getUInt32(); + m_confirmed_state_time = packet.ticks_since_start; + m_confirmed_switch_ticks = packet.switch_ticks; + uint32_t all_items = packet.all_items_size; for (ItemState* is : m_confirmed_state) { delete is; @@ -552,10 +557,10 @@ void NetworkItemManager::restoreCompleteState(const BareNetworkString& buffer) m_confirmed_state.clear(); for (unsigned i = 0; i < all_items; i++) { - const bool has_item = buffer.getUInt8() == 1; + const bool has_item = packet.all_items[i].has_item; if (has_item) { - ItemState* is = new ItemState(buffer); + ItemState* is = new ItemState(*(packet.all_items[i].item_state)); m_confirmed_state.push_back(is); } else diff --git a/src/items/network_item_manager.hpp b/src/items/network_item_manager.hpp index 6fef68284e5..d51e93690fc 100644 --- a/src/items/network_item_manager.hpp +++ b/src/items/network_item_manager.hpp @@ -30,6 +30,7 @@ #include class STKPeer; +class NimCompleteStatePacket; /** \ingroup items * The network item manager is responsible for handling all network related @@ -107,9 +108,9 @@ class NetworkItemManager : public Rewinder, public ItemManager m_last_confirmed_item_ticks.erase(peer); } // ------------------------------------------------------------------------ - void saveCompleteState(BareNetworkString* buffer) const; + NimCompleteStatePacket saveCompleteState() const; // ------------------------------------------------------------------------ - void restoreCompleteState(const BareNetworkString& buffer); + void restoreCompleteState(const NimCompleteStatePacket& packet); // ------------------------------------------------------------------------ void initServer(); diff --git a/src/modes/free_for_all.cpp b/src/modes/free_for_all.cpp index b5ed87be4ef..1ae87a5e193 100644 --- a/src/modes/free_for_all.cpp +++ b/src/modes/free_for_all.cpp @@ -295,7 +295,7 @@ bool FreeForAll::getKartFFAResult(int kart_id) const } // getKartFFAResult // ---------------------------------------------------------------------------- -void FreeForAll::saveCompleteState(BareNetworkString* bns, std::shared_ptr peer) +WorldCompleteStatePacket FreeForAll::saveCompleteState(std::shared_ptr peer) { for (unsigned i = 0; i < m_scores.size(); i++) bns->addUInt32(m_scores[i]); diff --git a/src/modes/free_for_all.hpp b/src/modes/free_for_all.hpp index e74c36e6c36..360f06d4744 100644 --- a/src/modes/free_for_all.hpp +++ b/src/modes/free_for_all.hpp @@ -85,8 +85,7 @@ class FreeForAll : public WorldWithRank m_scores.at(kart_id) = param; } // ------------------------------------------------------------------------ - virtual void saveCompleteState(BareNetworkString* bns, - std::shared_ptr peer) OVERRIDE; + virtual WorldCompleteStatePacket saveCompleteState(std::shared_ptr peer) OVERRIDE; // ------------------------------------------------------------------------ virtual void restoreCompleteState(const BareNetworkString& b) OVERRIDE; // ------------------------------------------------------------------------ diff --git a/src/modes/linear_world.cpp b/src/modes/linear_world.cpp index 9b170a7c11d..c7eeb22eadb 100644 --- a/src/modes/linear_world.cpp +++ b/src/modes/linear_world.cpp @@ -1237,7 +1237,7 @@ void LinearWorld::KartInfo::restoreCompleteState(const BareNetworkString& b) } // restoreCompleteState // ---------------------------------------------------------------------------- -void LinearWorld::saveCompleteState(BareNetworkString* bns, std::shared_ptr peer) +WorldCompleteStatePacket LinearWorld::saveCompleteState(std::shared_ptr peer) { bns->addUInt32(m_fastest_lap_ticks); bns->addFloat(m_distance_increase); diff --git a/src/modes/linear_world.hpp b/src/modes/linear_world.hpp index 76163de1333..2695fa25a6e 100644 --- a/src/modes/linear_world.hpp +++ b/src/modes/linear_world.hpp @@ -276,8 +276,7 @@ class LinearWorld : public WorldWithRank virtual std::pair getGameStartedProgress() const OVERRIDE; // ------------------------------------------------------------------------ - virtual void saveCompleteState(BareNetworkString* bns, - std::shared_ptr peer) OVERRIDE; + virtual WorldCompleteStatePacket saveCompleteState(std::shared_ptr peer) OVERRIDE; // ------------------------------------------------------------------------ virtual void restoreCompleteState(const BareNetworkString& b) OVERRIDE; // ------------------------------------------------------------------------ diff --git a/src/modes/soccer_world.cpp b/src/modes/soccer_world.cpp index 79937ee0022..c590aff6f85 100644 --- a/src/modes/soccer_world.cpp +++ b/src/modes/soccer_world.cpp @@ -1178,7 +1178,7 @@ void SoccerWorld::enterRaceOverState() } // enterRaceOverState // ---------------------------------------------------------------------------- -void SoccerWorld::saveCompleteState(BareNetworkString* bns, std::shared_ptr peer) +WorldCompleteStatePacket SoccerWorld::saveCompleteState(std::shared_ptr peer) { const unsigned red_scorers = (unsigned)m_red_scorers.size(); bns->addUInt32(red_scorers); diff --git a/src/modes/soccer_world.hpp b/src/modes/soccer_world.hpp index e0de86fd9f3..62d0d50b41d 100644 --- a/src/modes/soccer_world.hpp +++ b/src/modes/soccer_world.hpp @@ -263,8 +263,7 @@ class SoccerWorld : public WorldWithRank return progress; } // ------------------------------------------------------------------------ - virtual void saveCompleteState(BareNetworkString* bns, - std::shared_ptr peer) OVERRIDE; + virtual WorldCompleteStatePacket saveCompleteState(std::shared_ptr peer) OVERRIDE; // ------------------------------------------------------------------------ virtual void restoreCompleteState(const BareNetworkString& b) OVERRIDE; // ------------------------------------------------------------------------ diff --git a/src/network/kart_data.cpp b/src/network/kart_data.cpp index 577b4f479f0..ad00fbc7588 100644 --- a/src/network/kart_data.cpp +++ b/src/network/kart_data.cpp @@ -2,7 +2,7 @@ #include "karts/kart_model.hpp" #include "karts/kart_properties.hpp" -#include "network/network_string.hpp" +#include "network/packet_types.hpp" // ---------------------------------------------------------------------------- KartData::KartData(const KartProperties* kp) @@ -43,12 +43,21 @@ KartData::KartData(const BareNetworkString& ns) } // KartData(BareNetworkString&) // ---------------------------------------------------------------------------- -void KartData::encode(BareNetworkString* ns) const +KartDataPacket KartData::encode() const { - ns->encodeString(m_kart_type); + KartDataPacket packet; + packet.kart_type = m_kart_type; + packet.parameters = {}; + if (!m_kart_type.empty()) { - ns->addFloat(m_width).addFloat(m_height).addFloat(m_length) - .add(m_gravity_shift); + KartParametersPacket params; + params.width = m_width; + params.height = m_height; + params.length = m_length; + params.gravity_shift = m_gravity_shift; + packet.parameters = std::make_shared(params); } + + return packet; } // encode(BareNetworkString*) diff --git a/src/network/kart_data.hpp b/src/network/kart_data.hpp index a9c750c234f..1d4ec033509 100644 --- a/src/network/kart_data.hpp +++ b/src/network/kart_data.hpp @@ -1,6 +1,7 @@ #ifndef KART_DATA_HPP #define KART_DATA_HPP +#include "network/packet_types.hpp" #include "utils/vec3.hpp" #include @@ -28,7 +29,7 @@ class KartData // ------------------------------------------------------------------------ KartData(const BareNetworkString& ns); // ------------------------------------------------------------------------ - void encode(BareNetworkString* ns) const; + KartDataPacket encode() const; }; // class KartData diff --git a/src/network/network_player_profile.cpp b/src/network/network_player_profile.cpp index ac44a2fcc03..266f65c9373 100644 --- a/src/network/network_player_profile.cpp +++ b/src/network/network_player_profile.cpp @@ -22,6 +22,7 @@ #include "utils/string_utils.hpp" #include "utils/name_decorators/generic_decorator.hpp" +#include "network/packet_types.hpp" // ---------------------------------------------------------------------------- /** Returns true if this player is local, i.e. running on this computer. This @@ -43,3 +44,19 @@ core::stringw NetworkPlayerProfile::getDecoratedName(std::shared_ptrdecorate(StringUtils::wideToUtf8(m_player_name))); } // getDecoratedName // ---------------------------------------------------------------------------- + +EncodedSinglePlayerPacket NetworkPlayerProfile::getPacket() const +{ + EncodedSinglePlayerPacket packet; + packet.name = getName(); + packet.host_id = getHostId(); + packet.kart_color = getDefaultKartColor(); + packet.online_id = getOnlineId(); + packet.handicap = getHandicap(); + packet.local_player_id = getLocalPlayerId(); + packet.kart_team = getTeam(); + packet.country_code = getCountryCode(); + packet.kart_name = getKartName(); + return packet; +} // getPacket +//----------------------------------------------------------------------------- diff --git a/src/network/network_player_profile.hpp b/src/network/network_player_profile.hpp index 7df9c6eca40..6c8383670fb 100644 --- a/src/network/network_player_profile.hpp +++ b/src/network/network_player_profile.hpp @@ -36,6 +36,7 @@ class STKPeer; class GenericDecorator; enum KartTeam : int8_t; enum HandicapLevel : uint8_t; +struct EncodedSinglePlayerPacket; /*! \class NetworkPlayerProfile * \brief Contains the profile of a player. @@ -193,6 +194,9 @@ class NetworkPlayerProfile core::stringw getDecoratedName(std::shared_ptr decorator); // ------------------------------------------------------------------------ + // ------------------------------------------------------------------------ + EncodedSinglePlayerPacket getPacket() const; + // ------------------------------------------------------------------------ }; // class NetworkPlayerProfile #endif // HEADER_NETWORK_PLAYER_PROFILE diff --git a/src/network/packet_types.hpp b/src/network/packet_types.hpp index 37be504b495..1a2312b37af 100644 --- a/src/network/packet_types.hpp +++ b/src/network/packet_types.hpp @@ -20,6 +20,9 @@ #define PACKET_TYPES_HPP #include "network/network_string.hpp" +#include "utils/cpp2011.hpp" + +#include /** * IMPORTANT! @@ -89,16 +92,32 @@ enum BackLobbyReason : uint8_t BLR_SPECTATING_NEXT_GAME = 5 }; +struct Checkable +{ +private: + uint8_t m_state = 0; +public: + bool check(uint8_t which) const { return (m_state >> which) & 1; } + void set(uint8_t which, bool value) + { + if (value) + m_state |= (1 << which); + else + m_state &= ~(1 << which); + } +}; + //---------------------- Initialization --------------------------------------- #define DEFINE_CLASS(Name) \ -struct Name { \ +struct Name: public Checkable { \ public: \ - void toNetworkString(NetworkString* ns) const; \ - void fromNetworkString(NetworkString* ns); + void toNetworkString(NetworkString* ns) const; \ + void fromNetworkString(NetworkString* ns); #define SYNCHRONOUS(Value) bool isSynchronous() { return Value; } #define DEFINE_FIELD(Type, Var) Type Var; +#define DEFINE_FIELD_OPTIONAL(Type, Var, Condition) std::shared_ptr Var; #define DEFINE_FIXED_FIELD(Type, Var, Value) Type Var; #define DEFINE_VECTOR(Type, Size, Var) std::vector Var; #define END_DEFINE_CLASS(Name) }; @@ -108,6 +127,7 @@ struct Name { \ #undef SYNCHRONOUS #undef DEFINE_FIELD #undef DEFINE_FIXED_FIELD +#undef DEFINE_FIELD_OPTIONAL #undef DEFINE_VECTOR #undef END_DEFINE_CLASS @@ -123,6 +143,11 @@ inline void Name::toNetworkString(NetworkString* ns) const \ #define DEFINE_FIELD(Type, Var) \ ns->encode(Var); +// We send it if it exists, and receive only if the condition is true +#define DEFINE_FIELD_OPTIONAL(Type, Var, Condition) \ + if (Var) \ + ns->encode(*Var); + #define DEFINE_FIXED_FIELD(Type, Var, Value) \ ns->encode(Value); @@ -139,6 +164,7 @@ inline void Name::toNetworkString(NetworkString* ns) const \ #undef SYNCHRONOUS #undef DEFINE_FIELD #undef DEFINE_FIXED_FIELD +#undef DEFINE_FIELD_OPTIONAL #undef DEFINE_VECTOR #undef END_DEFINE_CLASS @@ -153,6 +179,14 @@ inline void Name::fromNetworkString(NetworkString* ns) \ #define DEFINE_FIELD(Type, Var) \ ns->decode(Var); +// We send it if it exists, and receive only if the condition is true +#define DEFINE_FIELD_OPTIONAL(Type, Var, Condition) \ + if (Condition) { \ + Type temp_##Var; \ + ns->decode(temp_##Var); \ + Var = std::make_shared(temp_##Var); \ + } + #define DEFINE_FIXED_FIELD(Type, Var, Value) #define DEFINE_VECTOR(Type, Size, Var) \ @@ -169,6 +203,7 @@ inline void Name::fromNetworkString(NetworkString* ns) \ #undef SYNCHRONOUS #undef DEFINE_FIELD #undef DEFINE_FIXED_FIELD +#undef DEFINE_FIELD_OPTIONAL #undef DEFINE_VECTOR #undef END_DEFINE_CLASS diff --git a/src/network/packet_types_base.hpp b/src/network/packet_types_base.hpp index 558399d9e9b..0e32e2253ae 100644 --- a/src/network/packet_types_base.hpp +++ b/src/network/packet_types_base.hpp @@ -36,7 +36,7 @@ * For now, for each non-vector type you have in the packets, you have * to define encode and decode for BareNetworkString. * - * If you need to use a type tbhat includes a comma, such as std::map, + * If you need to use a type that includes a comma, such as std::map, * you can use either a #define or using = to pass it anyway. */ @@ -69,4 +69,111 @@ DEFINE_CLASS(PlayerListPacket) DEFINE_VECTOR(PlayerListProfilePacket, all_profiles_size, all_profiles) END_DEFINE_CLASS(PlayerListPacket) +DEFINE_CLASS(EncodedSinglePlayerPacket) + DEFINE_FIELD(widestr, name) + DEFINE_FIELD(uint32_t, host_id) + DEFINE_FIELD(float, kart_color) + DEFINE_FIELD(uint32_t, online_id) + DEFINE_FIELD(uint8_t, handicap) + DEFINE_FIELD(uint8_t, local_player_id) + DEFINE_FIELD(uint8_t, kart_team) + DEFINE_FIELD(std::string, country_code) + DEFINE_FIELD(std::string, kart_name) +END_DEFINE_CLASS(EncodedSinglePlayerPacket) + +DEFINE_CLASS(EncodedPlayersPacket) +END_DEFINE_CLASS(EncodedPlayersPacket) + + +DEFINE_CLASS(PeerVotePacket) + DEFINE_FIELD(widestr, player_name) + DEFINE_FIELD(std::string, track_name) + DEFINE_FIELD(uint8_t, num_laps) + DEFINE_FIELD(bool, is_reverse) +END_DEFINE_CLASS(PeerVotePacket) + + +DEFINE_CLASS(DefaultVotePacket) + DEFINE_FIELD(uint32_t, winner_peer_id) + DEFINE_FIELD(PeerVotePacket, default_vote) +END_DEFINE_CLASS(DefaultVotePacket) + +DEFINE_CLASS(BattleInfoPacket) + DEFINE_FIELD(uint32_t, battle_hit_capture_limit) + DEFINE_FIELD(float, battle_time_limit) + DEFINE_FIELD(uint16_t, flag_return_time) + DEFINE_FIELD(uint16_t, flag_deactivated_time) +END_DEFINE_CLASS(BattleInfoPacket) + +DEFINE_CLASS(KartParametersPacket) + DEFINE_FIELD(float, width) + DEFINE_FIELD(float, height) + DEFINE_FIELD(float, length) + DEFINE_FIELD(Vec3, gravity_shift) +END_DEFINE_CLASS(KartParametersPacket) + +DEFINE_CLASS(KartDataPacket) + DEFINE_FIELD(std::string, kart_type) + DEFINE_FIELD_OPTIONAL(KartParametersPacket, parameters, !kart_type.empty()) +END_DEFINE_CLASS(KartDataPacket) + +DEFINE_CLASS(LoadWorldPacket) + SYNCHRONOUS(true) + DEFINE_FIXED_FIELD(uint8_t, type, LE_LOAD_WORLD) + DEFINE_FIELD(DefaultVotePacket, default_vote) + DEFINE_FIELD(bool, live_join) + DEFINE_FIELD(uint8_t, players_size) + DEFINE_VECTOR(EncodedSinglePlayerPacket, players_size, all_players) + DEFINE_FIELD(uint32_t, item_seed) + DEFINE_FIELD_OPTIONAL(BattleInfoPacket, battle_info, check(0)) // RaceManager::get()->isBattleMode() + DEFINE_VECTOR(KartDataPacket, players_size, players_kart_data) +END_DEFINE_CLASS(LoadWorldPacket) + +DEFINE_CLASS(ItemStatePacket) + DEFINE_FIELD(uint8_t, type) + DEFINE_FIELD(uint8_t, original_type) + DEFINE_FIELD(uint32_t, ticks_till_return) + DEFINE_FIELD(uint32_t, item_id) + DEFINE_FIELD(uint32_t, deactive_ticks) + DEFINE_FIELD(uint32_t, used_up_counter) + DEFINE_FIELD(Vec3, xyz) + DEFINE_FIELD(btQuaternion, original_rotation) + DEFINE_FIELD(uint8_t, previous_owner) +END_DEFINE_CLASS(ItemStatePacket) + +DEFINE_CLASS(ItemCompleteStatePacket) + DEFINE_FIELD(bool, has_item) + DEFINE_FIELD_OPTIONAL(ItemStatePacket, item_state, has_item) +END_DEFINE_CLASS(ItemCompleteStatePacket) + +DEFINE_CLASS(NimCompleteStatePacket) + DEFINE_FIELD(uint32_t, ticks_since_start) + DEFINE_FIELD(uint32_t, switch_ticks) + DEFINE_FIELD(uint32_t, all_items_size) + DEFINE_VECTOR(ItemCompleteStatePacket, all_items_size, all_items) +END_DEFINE_CLASS(NimCompleteStatePacket) + +DEFINE_CLASS(WorldCompleteStatePacket) + +END_DEFINE_CLASS(WorldCompleteStatePacket) + +DEFINE_CLASS(InsideGameInfoPacket) + DEFINE_FIELD(uint8_t, players_size) + DEFINE_VECTOR(EncodedSinglePlayerPacket, players_size, all_players) + DEFINE_VECTOR(KartDataPacket, players_size, players_kart_data) +END_DEFINE_CLASS(InsideGameInfoPacket) + +DEFINE_CLASS(LiveJoinPacket) + SYNCHRONOUS(true) + DEFINE_FIXED_FIELD(uint8_t, type, LE_LIVE_JOIN_ACK) + DEFINE_FIELD(uint64_t, client_starting_time) + DEFINE_FIELD(uint8_t, check_count); + DEFINE_FIELD(uint64_t, live_join_start_time) + DEFINE_FIELD(uint32_t, last_live_join_util_ticks) + DEFINE_FIELD(NimCompleteStatePacket, nim_complete_state) + DEFINE_FIELD(WorldCompleteStatePacket, world_complete_state) + DEFINE_FIELD_OPTIONAL(InsideGameInfoPacket, inside_info, check(0)) // RaceManager::get()->supportsLiveJoining() +END_DEFINE_CLASS(LiveJoinPacket) + + // end \ No newline at end of file diff --git a/src/network/peer_vote.hpp b/src/network/peer_vote.hpp index fdd84f076cf..4ead5b211e9 100644 --- a/src/network/peer_vote.hpp +++ b/src/network/peer_vote.hpp @@ -20,6 +20,7 @@ #define PEER_VOTE_HPP #include "network/network_string.hpp" +#include "network/packet_types.hpp" #include "irrString.h" #include @@ -62,12 +63,14 @@ class PeerVote // ------------------------------------------------------ /** Encodes this vote object into a network string. */ - void encode(NetworkString *ns) + PeerVotePacket encode() { - ns->encodeString(m_player_name) - .encodeString(m_track_name) - .addUInt8(m_num_laps) - .addUInt8(m_reverse); + PeerVotePacket packet; + packet.player_name = m_player_name; + packet.track_name = m_track_name; + packet.num_laps = m_num_laps; + packet.is_reverse = m_reverse; + return packet; } // encode }; // class PeerVote diff --git a/src/network/protocols/client_lobby.cpp b/src/network/protocols/client_lobby.cpp index db0f415f1d1..79730e05f90 100644 --- a/src/network/protocols/client_lobby.cpp +++ b/src/network/protocols/client_lobby.cpp @@ -318,10 +318,10 @@ void ClientLobby::addAllPlayers(Event* event) peer->cleanPlayerProfiles(); m_server_send_live_load_world = data.getUInt8() == 1; - bool is_specator = true; + bool is_spectator = true; std::vector > players = - decodePlayers(data, peer, &is_specator); - setSpectator(is_specator); + decodePlayers(data, peer, &is_spectator); + setSpectator(is_spectator); uint32_t random_seed = data.getUInt32(); ItemManager::updateRandomSeed(random_seed); diff --git a/src/network/protocols/server_lobby.cpp b/src/network/protocols/server_lobby.cpp index 2b47cd2b50c..1538bcf0c2f 100644 --- a/src/network/protocols/server_lobby.cpp +++ b/src/network/protocols/server_lobby.cpp @@ -77,25 +77,21 @@ // Helper functions. namespace { - void encodePlayers(BareNetworkString* bns, - std::vector >& players, + EncodedSinglePlayerPacket encodePlayer(std::shared_ptr player, const std::shared_ptr& decorator) { - bns->addUInt8((uint8_t)players.size()); - for (unsigned i = 0; i < players.size(); i++) - { - std::shared_ptr& player = players[i]; - bns->encodeString(player->getDecoratedName(decorator)) - .addUInt32(player->getHostId()) - .addFloat(player->getDefaultKartColor()) - .addUInt32(player->getOnlineId()) - .addUInt8(player->getHandicap()) - .addUInt8(player->getLocalPlayerId()) - .addUInt8(player->getTeam()) - .encodeString(player->getCountryCode()); - bns->encodeString(player->getKartName()); - } - } // encodePlayers + EncodedSinglePlayerPacket packet; + packet.name = player->getDecoratedName(decorator); + packet.host_id = player->getHostId(); + packet.kart_color = player->getDefaultKartColor(); + packet.online_id = player->getOnlineId(); + packet.handicap = player->getHandicap(); + packet.local_player_id = player->getLocalPlayerId(); + packet.kart_team = player->getTeam(); + packet.country_code = player->getCountryCode(); + packet.kart_name = player->getKartName(); + return packet; + } //------------------------------------------------------------------------- /** Returns true if world is active for clients to live join, spectate or * going back to lobby live @@ -947,8 +943,6 @@ void ServerLobby::asynchronousUpdate() auto& stk_config = STKConfig::get(); - NetworkString* load_world_message = getLoadWorldMessage(players, - false/*live_join*/); m_game_setup->setHitCaptureTime(getSettings()->getBattleHitCaptureLimit(), getSettings()->getBattleTimeLimit()); uint16_t flag_return_time = (uint16_t)stk_config->time2Ticks( @@ -968,6 +962,8 @@ void ServerLobby::asynchronousUpdate() resetPeersReady(); m_state = LOAD_WORLD; + NetworkString* load_world_message = getLoadWorldMessage(players, + false/*live_join*/); Comm::sendMessageToPeers(load_world_message); // updatePlayerList so the in lobby players (if any) can see always // spectators join the game @@ -1004,33 +1000,34 @@ void ServerLobby::asynchronousUpdate() } // asynchronousUpdate //----------------------------------------------------------------------------- -NetworkString* ServerLobby::getLoadWorldMessage( +LoadWorldPacket ServerLobby::getLoadWorldMessage( std::vector >& players, bool live_join) const { - NetworkString* load_world_message = getNetworkString(); - load_world_message->setSynchronous(true); - load_world_message->addUInt8(LE_LOAD_WORLD); - getSettings()->encodeDefaultVote(load_world_message); - load_world_message->addUInt8(live_join ? 1 : 0); - encodePlayers(load_world_message, players, m_name_decorator); - load_world_message->addUInt32(m_item_seed); + LoadWorldPacket packet; + packet.default_vote = getSettings()->encodeDefaultVote(); + packet.live_join = live_join; + packet.players_size = players.size(); + for (auto& player: players) + packet.all_players.push_back(encodePlayer(player, m_name_decorator)); + packet.item_seed = m_item_seed; + packet.battle_info = {}; + if (RaceManager::get()->isBattleMode()) { - auto& stk_config = STKConfig::get(); - - load_world_message->addUInt32(getSettings()->getBattleHitCaptureLimit()) - .addFloat(getSettings()->getBattleTimeLimit()); - uint16_t flag_return_time = (uint16_t)stk_config->time2Ticks( - getSettings()->getFlagReturnTimeout()); - load_world_message->addUInt16(flag_return_time); - uint16_t flag_deactivated_time = (uint16_t)stk_config->time2Ticks( - getSettings()->getFlagDeactivatedTime()); - load_world_message->addUInt16(flag_deactivated_time); + BattleInfoPacket battle_packet; + battle_packet.battle_hit_capture_limit = getSettings()->getBattleHitCaptureLimit(); + battle_packet.battle_time_limit = getSettings()->getBattleTimeLimit(); + battle_packet.flag_return_time = (uint16_t)stk_config->time2Ticks( + getSettings()->getFlagReturnTimeout()); + battle_packet.flag_deactivated_time = (uint16_t)stk_config->time2Ticks( + getSettings()->getFlagDeactivatedTime()); + packet.battle_info = battle_packet; } for (unsigned i = 0; i < players.size(); i++) - players[i]->getKartData().encode(load_world_message); - return load_world_message; + packet.players_kart_data.push_back(players[i]->getKartData().encode()); + + return packet; } // getLoadWorldMessage //----------------------------------------------------------------------------- @@ -1312,33 +1309,45 @@ void ServerLobby::finishedLoadingLiveJoinClient(Event* event) const uint8_t cc = (uint8_t)Track::getCurrentTrack()->getCheckManager()->getCheckStructureCount(); NetworkString* ns = getNetworkString(10); - ns->setSynchronous(true); - ns->addUInt8(LE_LIVE_JOIN_ACK).addUInt64(m_client_starting_time) - .addUInt8(cc).addUInt64(live_join_start_time) - .addUInt32(m_last_live_join_util_ticks); + + LiveJoinPacket packet; + + packet.client_starting_time = m_client_starting_time; + packet.check_count = cc; + packet.live_join_start_time = live_join_start_time; + packet.last_live_join_util_ticks = m_last_live_join_util_ticks; NetworkItemManager* nim = dynamic_cast (Track::getCurrentTrack()->getItemManager()); assert(nim); - nim->saveCompleteState(ns); + packet.nim_complete_state = nim->saveCompleteState(); nim->addLiveJoinPeer(peer); - w->saveCompleteState(ns, peer); + packet.world_complete_state = w->saveCompleteState(peer); + packet.inside_info = {}; if (RaceManager::get()->supportsLiveJoining()) { + InsideGameInfoPacket inside_packet; // Only needed in non-racing mode as no need players can added after // starting of race std::vector > players = getLivePlayers(); - encodePlayers(ns, players, m_name_decorator); + + inside_packet.players_size = players.size(); + + for (auto& player: players) + inside_packet.all_players.push_back(encodePlayer(player, m_name_decorator)); for (unsigned i = 0; i < players.size(); i++) - players[i]->getKartData().encode(ns); + inside_packet.players_kart_data.push_back(players[i]->getKartData().encode()); + + packet.inside_info = inside_packet; } m_peers_ready[peer] = false; peer->setWaitingForGame(false); peer->setSpectator(spectator); + packet.toNetworkString(ns); peer->sendPacket(ns, PRM_RELIABLE); delete ns; updatePlayerList(); @@ -3093,7 +3102,6 @@ void ServerLobby::handlePlayerVote(Event* event) // ---------------------------------------------------------------------------- /** Select the track to be used based on all votes being received. * \param winner_vote The PeerVote that was picked. - * \param winner_peer_id The host id of winner (unchanged if no vote). * \return True if race can go on, otherwise wait. */ bool ServerLobby::handleAllVotes(PeerVote* winner_vote) diff --git a/src/network/protocols/server_lobby.hpp b/src/network/protocols/server_lobby.hpp index 44728e6d4de..137b633a449 100644 --- a/src/network/protocols/server_lobby.hpp +++ b/src/network/protocols/server_lobby.hpp @@ -260,7 +260,7 @@ class ServerLobby : public LobbyProtocol, public LobbyContextUser void handlePlayerDisconnection() const; void addLiveJoinPlaceholder( std::vector >& players) const; - NetworkString* getLoadWorldMessage( + LoadWorldPacket getLoadWorldMessage( std::vector >& players, bool live_join) const; void setPlayerKarts(const NetworkString& ns, std::shared_ptr peer) const; diff --git a/src/utils/lobby_settings.cpp b/src/utils/lobby_settings.cpp index 6d8cbc53a06..f57377640da 100644 --- a/src/utils/lobby_settings.cpp +++ b/src/utils/lobby_settings.cpp @@ -555,10 +555,12 @@ void LobbySettings::applyRestrictionsOnWinnerVote(PeerVote* winner_vote) const } // applyRestrictionsOnWinnerVote //----------------------------------------------------------------------------- -void LobbySettings::encodeDefaultVote(NetworkString* ns) const +DefaultVotePacket LobbySettings::encodeDefaultVote(NetworkString* ns) const { - ns->addUInt32(m_winner_peer_id); - m_default_vote->encode(ns); + DefaultVotePacket packet; + packet.winner_peer_id = m_winner_peer_id; + packet.default_vote = m_default_vote->encode(); + return packet; } // encodeDefaultVote //----------------------------------------------------------------------------- diff --git a/src/utils/lobby_settings.hpp b/src/utils/lobby_settings.hpp index 4f9b227b039..c7c182cae08 100644 --- a/src/utils/lobby_settings.hpp +++ b/src/utils/lobby_settings.hpp @@ -35,6 +35,7 @@ class STKPeer; class Tournament; class Track; struct GameInfo; +struct DefaultVotePacket; /** @brief A class that manipulates server settings, such as resetting, * scoring, goal policies, etc. Might be split into a few parts later, @@ -84,7 +85,7 @@ class LobbySettings: public LobbyContextComponent void initializeDefaultVote(); void applyRestrictionsOnVote(PeerVote* vote, Track* t) const; void applyRestrictionsOnWinnerVote(PeerVote* winner_vote) const; - void encodeDefaultVote(NetworkString* ns) const; + DefaultVotePacket encodeDefaultVote() const; void setDefaultVote(PeerVote winner_vote); PeerVote getDefaultVote() const; bool isInWhitelist(const std::string& username) const; From acf854ca237f810c07e81c725894a4d3d9726d69 Mon Sep 17 00:00:00 2001 From: kimden <23140380+kimden@users.noreply.github.com> Date: Sat, 22 Mar 2025 17:26:45 +0400 Subject: [PATCH 02/34] One more commit trying to do stuff [skip ci] because the road to successful compilation is very long --- src/items/item.cpp | 8 +- src/modes/capture_the_flag.cpp | 21 +++-- src/modes/capture_the_flag.hpp | 4 +- src/modes/free_for_all.cpp | 17 ++++- src/modes/free_for_all.hpp | 4 +- src/modes/linear_world.cpp | 100 +++++++++++++++--------- src/modes/linear_world.hpp | 8 +- src/modes/soccer_world.cpp | 123 ++++++++++++++++-------------- src/modes/soccer_world.hpp | 7 +- src/modes/world.hpp | 4 +- src/network/packet_types.hpp | 50 +++++++++++- src/network/packet_types_base.hpp | 108 +++++++++++++++++++++++--- src/tracks/check_line.cpp | 27 +++++-- src/tracks/check_line.hpp | 4 +- src/tracks/check_structure.cpp | 27 +++++-- src/tracks/check_structure.hpp | 4 +- src/tracks/track_sector.cpp | 39 +++++----- src/tracks/track_sector.hpp | 5 +- 18 files changed, 392 insertions(+), 168 deletions(-) diff --git a/src/items/item.cpp b/src/items/item.cpp index 2b73334416f..fd69228d6a1 100644 --- a/src/items/item.cpp +++ b/src/items/item.cpp @@ -76,8 +76,8 @@ ItemState::ItemState(const ItemStatePacket& packet) m_item_id = packet.item_id; m_deactive_ticks = packet.deactive_ticks; m_used_up_counter = packet.used_up_counter; - m_xyz = packet.xyz; - m_original_rotation = packet.original_rotation; + m_xyz = packet.original_xyz_rotation.xyz; + m_original_rotation = packet.original_xyz_rotation.rotation; m_previous_owner = NULL; int8_t kart_id = packet.previous_owner; if (kart_id != -1) @@ -205,8 +205,8 @@ ItemStatePacket ItemState::saveCompleteState() const packet.item_id = m_item_id; packet.deactive_ticks = m_deactive_ticks; packet.used_up_counter = m_used_up_counter; - packet.xyz = m_xyz; - packet.original_rotation = m_original_rotation; + packet.original_xyz_rotation.xyz = m_xyz; + packet.original_xyz_rotation.rotation = m_original_rotation; packet.previous_owner = m_previous_owner ? m_previous_owner->getWorldKartId() : -1; diff --git a/src/modes/capture_the_flag.cpp b/src/modes/capture_the_flag.cpp index ee05e48ce71..1f1187e7143 100644 --- a/src/modes/capture_the_flag.cpp +++ b/src/modes/capture_the_flag.cpp @@ -553,16 +553,23 @@ const std::string& CaptureTheFlag::getIdent() const } // getIdent // ---------------------------------------------------------------------------- -void CaptureTheFlag::saveCompleteState(BareNetworkString* bns, std::shared_ptr peer) +std::shared_ptr CaptureTheFlag::saveCompleteState(std::shared_ptr peer) { - FreeForAll::saveCompleteState(bns, peer); - bns->addUInt32(m_red_scores).addUInt32(m_blue_scores); + auto packet = std::make_shared(); + + auto sp = FreeForAll::saveCompleteState(peer); + packet->ffa_packet = std::dynamic_pointer_cast(sp); + packet->red_score = m_red_scores; + packet->blue_score = m_blue_scores; + return packet; } // saveCompleteState // ---------------------------------------------------------------------------- -void CaptureTheFlag::restoreCompleteState(const BareNetworkString& b) +void CaptureTheFlag::restoreCompleteState(const std::shared_ptr& packet) { - FreeForAll::restoreCompleteState(b); - m_red_scores = b.getUInt32(); - m_blue_scores = b.getUInt32(); + std::shared_ptr ctf_packet = + std::dynamic_pointer_cast(packet); + FreeForAll::restoreCompleteState(ctf_packet->ffa_packet); + m_red_scores = ctf_packet->red_score; + m_blue_scores = ctf_packet->blue_score; } // restoreCompleteState diff --git a/src/modes/capture_the_flag.hpp b/src/modes/capture_the_flag.hpp index da6f090bf5d..33b014a8d14 100644 --- a/src/modes/capture_the_flag.hpp +++ b/src/modes/capture_the_flag.hpp @@ -157,10 +157,10 @@ class CaptureTheFlag : public FreeForAll return progress; } // ------------------------------------------------------------------------ - virtual void saveCompleteState(BareNetworkString* bns, + virtual std::shared_ptr saveCompleteState( std::shared_ptr peer) OVERRIDE; // ------------------------------------------------------------------------ - virtual void restoreCompleteState(const BareNetworkString& b) OVERRIDE; + virtual void restoreCompleteState(const std::shared_ptr& b) OVERRIDE; }; // CaptureTheFlag #endif diff --git a/src/modes/free_for_all.cpp b/src/modes/free_for_all.cpp index 1ae87a5e193..9b9b93a1b4e 100644 --- a/src/modes/free_for_all.cpp +++ b/src/modes/free_for_all.cpp @@ -295,17 +295,26 @@ bool FreeForAll::getKartFFAResult(int kart_id) const } // getKartFFAResult // ---------------------------------------------------------------------------- -WorldCompleteStatePacket FreeForAll::saveCompleteState(std::shared_ptr peer) +std::shared_ptr FreeForAll::saveCompleteState(std::shared_ptr peer) { + auto packet = std::make_shared(); for (unsigned i = 0; i < m_scores.size(); i++) - bns->addUInt32(m_scores[i]); + packet->scores.push_back(m_scores[i]); } // saveCompleteState // ---------------------------------------------------------------------------- -void FreeForAll::restoreCompleteState(const BareNetworkString& b) +void FreeForAll::restoreCompleteState(const std::shared_ptr& packet) { + std::shared_ptr ffa_packet = + std::dynamic_pointer_cast(packet); + + // kimden sincerely hopes here nothing will be broken + if (ffa_packet->scores.size() != m_scores.size()) + Log::error("FreeForAll", "Packet incoming scores size = %d, local scores size = %d", + ffa_packet->scores.size(), m_scores.size()); + for (unsigned i = 0; i < m_scores.size(); i++) - m_scores[i] = b.getUInt32(); + m_scores[i] = (i >= ffa_packet->scores.size() ? 0 : ffa_packet->scores[i]); } // restoreCompleteState // ---------------------------------------------------------------------------- diff --git a/src/modes/free_for_all.hpp b/src/modes/free_for_all.hpp index 360f06d4744..28f087349cc 100644 --- a/src/modes/free_for_all.hpp +++ b/src/modes/free_for_all.hpp @@ -85,9 +85,9 @@ class FreeForAll : public WorldWithRank m_scores.at(kart_id) = param; } // ------------------------------------------------------------------------ - virtual WorldCompleteStatePacket saveCompleteState(std::shared_ptr peer) OVERRIDE; + virtual std::shared_ptr saveCompleteState(std::shared_ptr peer) OVERRIDE; // ------------------------------------------------------------------------ - virtual void restoreCompleteState(const BareNetworkString& b) OVERRIDE; + virtual void restoreCompleteState(const std::shared_ptr& b) OVERRIDE; // ------------------------------------------------------------------------ void notifyAboutScoreIfNonzero(int id); }; // FreeForAll diff --git a/src/modes/linear_world.cpp b/src/modes/linear_world.cpp index c7eeb22eadb..b95827e869a 100644 --- a/src/modes/linear_world.cpp +++ b/src/modes/linear_world.cpp @@ -1215,79 +1215,111 @@ std::pair LinearWorld::getGameStartedProgress() const } // getGameStartedProgress // ---------------------------------------------------------------------------- -void LinearWorld::KartInfo::saveCompleteState(BareNetworkString* bns) +KartInfoPacket LinearWorld::KartInfo::saveCompleteState() { - bns->addUInt32(m_finished_laps); - bns->addUInt32(m_ticks_at_last_lap); - bns->addUInt32(m_lap_start_ticks); - bns->addFloat(m_estimated_finish); - bns->addFloat(m_overall_distance); - bns->addFloat(m_wrong_way_timer); + KartInfoPacket packet; + packet.finished_laps = m_finished_laps; + packet.ticks_at_last_lap = m_ticks_at_last_lap; + packet.lap_start_ticks = m_lap_start_ticks; + packet.estimated_finish = m_estimated_finish; + packet.overall_distance = m_overall_distance; + packet.wrong_way_timer = m_wrong_way_timer; + return packet; } // saveCompleteState // ---------------------------------------------------------------------------- -void LinearWorld::KartInfo::restoreCompleteState(const BareNetworkString& b) +void LinearWorld::KartInfo::restoreCompleteState(const KartInfoPacket& packet) { - m_finished_laps = b.getUInt32(); - m_ticks_at_last_lap = b.getUInt32(); - m_lap_start_ticks = b.getUInt32(); - m_estimated_finish = b.getFloat(); - m_overall_distance = b.getFloat(); - m_wrong_way_timer = b.getFloat(); + m_finished_laps = packet.finished_laps; + m_ticks_at_last_lap = packet.ticks_at_last_lap; + m_lap_start_ticks = packet.lap_start_ticks; + m_estimated_finish = packet.estimated_finish; + m_overall_distance = packet.overall_distance; + m_wrong_way_timer = packet.wrong_way_timer; } // restoreCompleteState // ---------------------------------------------------------------------------- -WorldCompleteStatePacket LinearWorld::saveCompleteState(std::shared_ptr peer) +std::shared_ptr LinearWorld::saveCompleteState(std::shared_ptr peer) { - bns->addUInt32(m_fastest_lap_ticks); - bns->addFloat(m_distance_increase); + auto packet = std::make_shared(); + + packet->fastest_lap_ticks = m_fastest_lap_ticks; + packet->distance_increase = m_distance_increase; for (auto& kart : m_karts) { - bns->add(kart->getXYZ()); - bns->add(kart->getRotation()); + PlacementPacket placement_packet; + placement_packet.xyz = kart->getXYZ(); + placement_packet.rotation = kart->getRotation(); + packet->kart_placements.push_back(std::move(placement_packet)); } for (KartInfo& ki : m_kart_info) - ki.saveCompleteState(bns); + packet->kart_infos.push_back(ki.saveCompleteState()); for (TrackSector* ts : m_kart_track_sector) - ts->saveCompleteState(bns); + packet->track_sectors.push_back(ts->saveCompleteState()); CheckManager* cm = Track::getCurrentTrack()->getCheckManager(); const uint8_t cc = (uint8_t)cm->getCheckStructureCount(); - bns->addUInt8(cc); + packet->check_structure_count = cc; for (unsigned i = 0; i < cc; i++) - cm->getCheckStructure(i)->saveCompleteState(bns); + packet->check_structures.push_back(cm->getCheckStructure(i)->saveCompleteState()); + return packet; } // saveCompleteState // ---------------------------------------------------------------------------- -void LinearWorld::restoreCompleteState(const BareNetworkString& b) +void LinearWorld::restoreCompleteState(const std::shared_ptr& packet) { - m_fastest_lap_ticks = b.getUInt32(); - m_distance_increase = b.getFloat(); + std::shared_ptr linear_packet = + std::dynamic_pointer_cast(packet); + m_fastest_lap_ticks = linear_packet->fastest_lap_ticks; + m_distance_increase = linear_packet->distance_increase; + + // kimden sincerely hopes here nothing will be broken + if (linear_packet->kart_placements.size() != m_karts.size()) + Log::error("LinearWorld", "Packet incoming karts size = %d, local karts size = %d", + linear_packet->kart_placements.size(), m_karts.size()); + + int i = 0; for (auto& kart : m_karts) { btTransform t; - Vec3 xyz = b.getVec3(); + Vec3 xyz = linear_packet->kart_placements[i].xyz; t.setOrigin(xyz); - t.setRotation(b.getQuat()); + t.setRotation(linear_packet->kart_placements[i].rotation); kart->setTrans(t); kart->setXYZ(xyz); + ++i; } + + // kimden sincerely hopes here nothing will be broken + if (linear_packet->kart_infos.size() != m_kart_info.size()) + Log::error("LinearWorld", "Packet incoming kartinfos size = %d, local kartinfos size = %d", + linear_packet->kart_infos.size(), m_kart_info.size()); + + i = 0; for (KartInfo& ki : m_kart_info) - ki.restoreCompleteState(b); + ki.restoreCompleteState(linear_packet->kart_infos[i++]); + + // kimden sincerely hopes here nothing will be broken + if (linear_packet->track_sectors.size() != m_kart_track_sector.size()) + Log::error("LinearWorld", "Packet incoming track sectors size = %d, local track sectors size = %d", + linear_packet->track_sectors.size(), m_kart_track_sector.size()); + + i = 0; for (TrackSector* ts : m_kart_track_sector) - ts->restoreCompleteState(b); + ts->restoreCompleteState(linear_packet->track_sectors[i++]); updateRacePosition(); - const unsigned cc = b.getUInt8(); + const unsigned cc = linear_packet->check_structure_count; CheckManager* cm = Track::getCurrentTrack()->getCheckManager(); if (cc != cm->getCheckStructureCount()) { - Log::warn("LinearWorld", - "Server has different check structures size."); + Log::error("LinearWorld", + "Server has different check structures size: %d incoming, %d locally", + cc, cm->getCheckStructureCount()); return; } for (unsigned i = 0; i < cc; i++) - cm->getCheckStructure(i)->restoreCompleteState(b); + cm->getCheckStructure(i)->restoreCompleteState(linear_packet->check_structures[i]); } // restoreCompleteState // ---------------------------------------------------------------------------- diff --git a/src/modes/linear_world.hpp b/src/modes/linear_world.hpp index 2695fa25a6e..a68eba2d52a 100644 --- a/src/modes/linear_world.hpp +++ b/src/modes/linear_world.hpp @@ -135,9 +135,9 @@ class LinearWorld : public WorldWithRank m_warn_issued = 0; } // reset // -------------------------------------------------------------------- - void saveCompleteState(BareNetworkString* bns); + KartInfoPacket saveCompleteState(); // -------------------------------------------------------------------- - void restoreCompleteState(const BareNetworkString& b); + void restoreCompleteState(const KartInfoPacket& packet); }; // ------------------------------------------------------------------------ @@ -276,9 +276,9 @@ class LinearWorld : public WorldWithRank virtual std::pair getGameStartedProgress() const OVERRIDE; // ------------------------------------------------------------------------ - virtual WorldCompleteStatePacket saveCompleteState(std::shared_ptr peer) OVERRIDE; + virtual std::shared_ptr saveCompleteState(std::shared_ptr peer) OVERRIDE; // ------------------------------------------------------------------------ - virtual void restoreCompleteState(const BareNetworkString& b) OVERRIDE; + virtual void restoreCompleteState(const std::shared_ptr& b) OVERRIDE; // ------------------------------------------------------------------------ void updateCheckLinesServer(int check_id, int kart_id); // ------------------------------------------------------------------------ diff --git a/src/modes/soccer_world.cpp b/src/modes/soccer_world.cpp index c590aff6f85..c5da60e2c34 100644 --- a/src/modes/soccer_world.cpp +++ b/src/modes/soccer_world.cpp @@ -234,7 +234,43 @@ class BallGoalData } }; // BallGoalData +//============================================================================= + +ScorerDataPacket SoccerWorld::ScorerData::saveCompleteState(bool has_soccer_fixes) +{ + ScorerDataPacket packet; + packet.id = m_id; + packet.correct_goal = m_correct_goal; + packet.time = m_time; + packet.kart = m_kart; + packet.player = m_player; + if (has_soccer_fixes) + { + // kimden: Please get rid of types here. + packet.country_code = std::make_shared(m_country_code); + packet.handicap_level = std::make_shared(m_handicap_level); + } + return packet; +} // saveCompleteState //----------------------------------------------------------------------------- + +void SoccerWorld::ScorerData::restoreCompleteState(const ScorerDataPacket& packet) +{ + m_id = packet.id; + m_correct_goal = packet.correct_goal; + m_time = packet.time; + m_kart = packet.kart; + m_player = packet.player; + if (NetworkConfig::get()->getServerCapabilities().find("soccer_fixes") + != NetworkConfig::get()->getServerCapabilities().end()) + { + if (auto ptr = packet.country_code) + m_country_code = *ptr; + if (auto ptr = packet.handicap_level) + m_handicap_level = (HandicapLevel)*ptr; + } +} // restoreCompleteState +//============================================================================= /** Constructor. Sets up the clock mode etc. */ SoccerWorld::SoccerWorld() : WorldWithRank() @@ -1176,89 +1212,60 @@ void SoccerWorld::enterRaceOverState() } } // enterRaceOverState - // ---------------------------------------------------------------------------- -WorldCompleteStatePacket SoccerWorld::saveCompleteState(std::shared_ptr peer) + +std::shared_ptr SoccerWorld::saveCompleteState(std::shared_ptr peer) { + auto packet = std::make_shared(); + + bool has_soccer_fixes = + peer->getClientCapabilities().find("soccer_fixes") != + peer->getClientCapabilities().end(); + const unsigned red_scorers = (unsigned)m_red_scorers.size(); - bns->addUInt32(red_scorers); + packet->red_scorers_count = red_scorers; for (unsigned i = 0; i < red_scorers; i++) - { - bns->addUInt8((uint8_t)m_red_scorers[i].m_id) - .addUInt8(m_red_scorers[i].m_correct_goal) - .addFloat(m_red_scorers[i].m_time) - .encodeString(m_red_scorers[i].m_kart) - .encodeString(m_red_scorers[i].m_player); - if (peer->getClientCapabilities().find("soccer_fixes") != - peer->getClientCapabilities().end()) - { - bns->encodeString(m_red_scorers[i].m_country_code) - .addUInt8(m_red_scorers[i].m_handicap_level); - } - } + packet->red_scorers.push_back(std::move(m_red_scorers[i].saveCompleteState(has_soccer_fixes))); const unsigned blue_scorers = (unsigned)m_blue_scorers.size(); - bns->addUInt32(blue_scorers); + packet->blue_scorers_count = blue_scorers; for (unsigned i = 0; i < blue_scorers; i++) - { - bns->addUInt8((uint8_t)m_blue_scorers[i].m_id) - .addUInt8(m_blue_scorers[i].m_correct_goal) - .addFloat(m_blue_scorers[i].m_time) - .encodeString(m_blue_scorers[i].m_kart) - .encodeString(m_blue_scorers[i].m_player); - if (peer->getClientCapabilities().find("soccer_fixes") != - peer->getClientCapabilities().end()) - { - bns->encodeString(m_blue_scorers[i].m_country_code) - .addUInt8(m_blue_scorers[i].m_handicap_level); - } - } - bns->addTime(m_reset_ball_ticks).addTime(m_ticks_back_to_own_goal); + packet->blue_scorers.push_back(std::move(m_blue_scorers[i].saveCompleteState(has_soccer_fixes))); + + packet->reser_ball_ticks = m_reset_ball_ticks; + packet->ticks_back_to_own_goal = m_ticks_back_to_own_goal; + return packet; } // saveCompleteState // ---------------------------------------------------------------------------- -void SoccerWorld::restoreCompleteState(const BareNetworkString& b) +void SoccerWorld::restoreCompleteState(const std::shared_ptr& packet) { + std::shared_ptr soccer_packet = + std::dynamic_pointer_cast(packet); + m_red_scorers.clear(); m_blue_scorers.clear(); - const unsigned red_size = b.getUInt32(); + // As we don't know the peer, we assume our has_soccer_fixes based on what + // SERVER has told us. This is wrong. + + const unsigned red_size = soccer_packet->red_scorers_count; for (unsigned i = 0; i < red_size; i++) { ScorerData sd; - sd.m_id = b.getUInt8(); - sd.m_correct_goal = b.getUInt8() == 1; - sd.m_time = b.getFloat(); - b.decodeString(&sd.m_kart); - b.decodeStringW(&sd.m_player); - if (NetworkConfig::get()->getServerCapabilities().find("soccer_fixes") - != NetworkConfig::get()->getServerCapabilities().end()) - { - b.decodeString(&sd.m_country_code); - sd.m_handicap_level = (HandicapLevel)b.getUInt8(); - } + sd.restoreCompleteState(soccer_packet->red_scorers[i]); m_red_scorers.push_back(sd); } - const unsigned blue_size = b.getUInt32(); + const unsigned blue_size = soccer_packet->blue_scorers_count; for (unsigned i = 0; i < blue_size; i++) { ScorerData sd; - sd.m_id = b.getUInt8(); - sd.m_correct_goal = b.getUInt8() == 1; - sd.m_time = b.getFloat(); - b.decodeString(&sd.m_kart); - b.decodeStringW(&sd.m_player); - if (NetworkConfig::get()->getServerCapabilities().find("soccer_fixes") - != NetworkConfig::get()->getServerCapabilities().end()) - { - b.decodeString(&sd.m_country_code); - sd.m_handicap_level = (HandicapLevel)b.getUInt8(); - } + sd.restoreCompleteState(soccer_packet->blue_scorers[i]); m_blue_scorers.push_back(sd); } - m_reset_ball_ticks = b.getTime(); - m_ticks_back_to_own_goal = b.getTime(); + m_reset_ball_ticks = soccer_packet->reser_ball_ticks; + m_ticks_back_to_own_goal = soccer_packet->ticks_back_to_own_goal; } // restoreCompleteState // ---------------------------------------------------------------------------- diff --git a/src/modes/soccer_world.hpp b/src/modes/soccer_world.hpp index 62d0d50b41d..1499301bf62 100644 --- a/src/modes/soccer_world.hpp +++ b/src/modes/soccer_world.hpp @@ -55,6 +55,9 @@ class SoccerWorld : public WorldWithRank std::string m_country_code; /** Handicap of player. */ HandicapLevel m_handicap_level; + + ScorerDataPacket saveCompleteState(bool has_soccer_fixes); + void restoreCompleteState(const ScorerDataPacket& packet); }; // ScorerData private: @@ -263,9 +266,9 @@ class SoccerWorld : public WorldWithRank return progress; } // ------------------------------------------------------------------------ - virtual WorldCompleteStatePacket saveCompleteState(std::shared_ptr peer) OVERRIDE; + virtual std::shared_ptr saveCompleteState(std::shared_ptr peer) OVERRIDE; // ------------------------------------------------------------------------ - virtual void restoreCompleteState(const BareNetworkString& b) OVERRIDE; + virtual void restoreCompleteState(const std::shared_ptr& b) OVERRIDE; // ------------------------------------------------------------------------ virtual bool isGoalPhase() const OVERRIDE { diff --git a/src/modes/world.hpp b/src/modes/world.hpp index de26d82e22b..f6d15cf37f7 100644 --- a/src/modes/world.hpp +++ b/src/modes/world.hpp @@ -376,9 +376,9 @@ class World : public WorldStatus m_eliminated_karts--; } // ------------------------------------------------------------------------ - virtual void saveCompleteState(BareNetworkString* bns, std::shared_ptr peer) {} + virtual std::shared_ptr saveCompleteState(std::shared_ptr peer) { return {}; } // ------------------------------------------------------------------------ - virtual void restoreCompleteState(const BareNetworkString& buffer) {} + virtual void restoreCompleteState(const std::shared_ptr& buffer) {} // ------------------------------------------------------------------------ /** The code that draws the timer should call this first to know * whether the game mode wants a timer drawn. */ diff --git a/src/network/packet_types.hpp b/src/network/packet_types.hpp index 1a2312b37af..740c499cf49 100644 --- a/src/network/packet_types.hpp +++ b/src/network/packet_types.hpp @@ -92,13 +92,19 @@ enum BackLobbyReason : uint8_t BLR_SPECTATING_NEXT_GAME = 5 }; +struct Packet +{ + // Needed to dynamic_cast + virtual ~Packet() {} +}; + struct Checkable { private: - uint8_t m_state = 0; + uint32_t m_state = 0; public: - bool check(uint8_t which) const { return (m_state >> which) & 1; } - void set(uint8_t which, bool value) + bool check(uint32_t which) const { return (m_state >> which) & 1; } + void set(uint32_t which, bool value) { if (value) m_state |= (1 << which); @@ -110,25 +116,31 @@ struct Checkable //---------------------- Initialization --------------------------------------- #define DEFINE_CLASS(Name) \ -struct Name: public Checkable { \ +struct Name: public Checkable, public Packet { \ public: \ void toNetworkString(NetworkString* ns) const; \ void fromNetworkString(NetworkString* ns); #define SYNCHRONOUS(Value) bool isSynchronous() { return Value; } +#define AUX_VAR(Type, Var) Type Var; #define DEFINE_FIELD(Type, Var) Type Var; +#define DEFINE_FIELD_PTR(Type, Var) std::shared_ptr Var; #define DEFINE_FIELD_OPTIONAL(Type, Var, Condition) std::shared_ptr Var; #define DEFINE_FIXED_FIELD(Type, Var, Value) Type Var; #define DEFINE_VECTOR(Type, Size, Var) std::vector Var; +#define DEFINE_VECTOR_OBJ(Type, Size, Var) std::vector Var; #define END_DEFINE_CLASS(Name) }; #include "network/packet_types_base.hpp" #undef DEFINE_CLASS #undef SYNCHRONOUS +#undef AUX_VAR #undef DEFINE_FIELD +#undef DEFINE_FIELD_PTR #undef DEFINE_FIXED_FIELD #undef DEFINE_FIELD_OPTIONAL #undef DEFINE_VECTOR +#undef DEFINE_VECTOR_OBJ #undef END_DEFINE_CLASS //---------------------- To NetworkString ------------------------------------- @@ -140,9 +152,15 @@ inline void Name::toNetworkString(NetworkString* ns) const \ #define SYNCHRONOUS(Value) \ ns->setSynchronous(Value); +#define AUX_VAR(Type, Var) + #define DEFINE_FIELD(Type, Var) \ ns->encode(Var); +#define DEFINE_FIELD_PTR(Type, Var) \ + if (Var) \ + ns->encode(*Var); + // We send it if it exists, and receive only if the condition is true #define DEFINE_FIELD_OPTIONAL(Type, Var, Condition) \ if (Var) \ @@ -152,6 +170,11 @@ inline void Name::toNetworkString(NetworkString* ns) const \ ns->encode(Value); #define DEFINE_VECTOR(Type, Size, Value) \ + for (unsigned Value##_cnt = 0; Value##_cnt < Size; ++Value##_cnt) { \ + ns->encode(Value[Value##_cnt]); \ + } + +#define DEFINE_VECTOR_OBJ(Type, Size, Value) \ for (unsigned Value##_cnt = 0; Value##_cnt < Size; ++Value##_cnt) { \ Value[Value##_cnt].toNetworkString(ns); \ } @@ -162,10 +185,13 @@ inline void Name::toNetworkString(NetworkString* ns) const \ #include "network/packet_types_base.hpp" #undef DEFINE_CLASS #undef SYNCHRONOUS +#undef AUX_VAR #undef DEFINE_FIELD +#undef DEFINE_FIELD_PTR #undef DEFINE_FIXED_FIELD #undef DEFINE_FIELD_OPTIONAL #undef DEFINE_VECTOR +#undef DEFINE_VECTOR_OBJ #undef END_DEFINE_CLASS //---------------------- From NetworkString ----------------------------------- @@ -176,9 +202,17 @@ inline void Name::fromNetworkString(NetworkString* ns) \ #define SYNCHRONOUS(Value) +#define AUX_VAR(Type, Var) + #define DEFINE_FIELD(Type, Var) \ ns->decode(Var); +// Same as optional but unconditional +#define DEFINE_FIELD_PTR(Type, Var) \ + Type temp_##Var; \ + ns->decode(temp_##Var); \ + Var = std::make_shared(temp_##Var); \ + // We send it if it exists, and receive only if the condition is true #define DEFINE_FIELD_OPTIONAL(Type, Var, Condition) \ if (Condition) { \ @@ -190,6 +224,12 @@ inline void Name::fromNetworkString(NetworkString* ns) \ #define DEFINE_FIXED_FIELD(Type, Var, Value) #define DEFINE_VECTOR(Type, Size, Var) \ + Var.resize(Size); \ + for (unsigned Var##_cnt = 0; Var##_cnt < Size; ++Var##_cnt) { \ + ns->decode(Var[Var##_cnt]); \ + } + +#define DEFINE_VECTOR_OBJ(Type, Size, Var) \ Var.resize(Size); \ for (unsigned Var##_cnt = 0; Var##_cnt < Size; ++Var##_cnt) { \ Var[Var##_cnt].fromNetworkString(ns); \ @@ -201,7 +241,9 @@ inline void Name::fromNetworkString(NetworkString* ns) \ #include "network/packet_types_base.hpp" #undef DEFINE_CLASS #undef SYNCHRONOUS +#undef AUX_VAR #undef DEFINE_FIELD +#undef DEFINE_FIELD_PTR #undef DEFINE_FIXED_FIELD #undef DEFINE_FIELD_OPTIONAL #undef DEFINE_VECTOR diff --git a/src/network/packet_types_base.hpp b/src/network/packet_types_base.hpp index 0e32e2253ae..20651b0d180 100644 --- a/src/network/packet_types_base.hpp +++ b/src/network/packet_types_base.hpp @@ -66,7 +66,7 @@ DEFINE_CLASS(PlayerListPacket) DEFINE_FIXED_FIELD(uint8_t, type, LE_UPDATE_PLAYER_LIST) DEFINE_FIELD(bool, game_started) DEFINE_FIELD(uint8_t, all_profiles_size) - DEFINE_VECTOR(PlayerListProfilePacket, all_profiles_size, all_profiles) + DEFINE_VECTOR_OBJ(PlayerListProfilePacket, all_profiles_size, all_profiles) END_DEFINE_CLASS(PlayerListPacket) DEFINE_CLASS(EncodedSinglePlayerPacket) @@ -123,12 +123,17 @@ DEFINE_CLASS(LoadWorldPacket) DEFINE_FIELD(DefaultVotePacket, default_vote) DEFINE_FIELD(bool, live_join) DEFINE_FIELD(uint8_t, players_size) - DEFINE_VECTOR(EncodedSinglePlayerPacket, players_size, all_players) + DEFINE_VECTOR_OBJ(EncodedSinglePlayerPacket, players_size, all_players) DEFINE_FIELD(uint32_t, item_seed) DEFINE_FIELD_OPTIONAL(BattleInfoPacket, battle_info, check(0)) // RaceManager::get()->isBattleMode() - DEFINE_VECTOR(KartDataPacket, players_size, players_kart_data) + DEFINE_VECTOR_OBJ(KartDataPacket, players_size, players_kart_data) END_DEFINE_CLASS(LoadWorldPacket) +DEFINE_CLASS(PlacementPacket) + DEFINE_FIELD(Vec3, xyz) + DEFINE_FIELD(btQuaternion, rotation) +END_DEFINE_CLASS(PlacementPacket) + DEFINE_CLASS(ItemStatePacket) DEFINE_FIELD(uint8_t, type) DEFINE_FIELD(uint8_t, original_type) @@ -136,8 +141,7 @@ DEFINE_CLASS(ItemStatePacket) DEFINE_FIELD(uint32_t, item_id) DEFINE_FIELD(uint32_t, deactive_ticks) DEFINE_FIELD(uint32_t, used_up_counter) - DEFINE_FIELD(Vec3, xyz) - DEFINE_FIELD(btQuaternion, original_rotation) + DEFINE_FIELD(PlacementPacket, original_xyz_rotation) DEFINE_FIELD(uint8_t, previous_owner) END_DEFINE_CLASS(ItemStatePacket) @@ -150,17 +154,103 @@ DEFINE_CLASS(NimCompleteStatePacket) DEFINE_FIELD(uint32_t, ticks_since_start) DEFINE_FIELD(uint32_t, switch_ticks) DEFINE_FIELD(uint32_t, all_items_size) - DEFINE_VECTOR(ItemCompleteStatePacket, all_items_size, all_items) + DEFINE_VECTOR_OBJ(ItemCompleteStatePacket, all_items_size, all_items) END_DEFINE_CLASS(NimCompleteStatePacket) -DEFINE_CLASS(WorldCompleteStatePacket) +DEFINE_CLASS(KartInfoPacket) + DEFINE_FIELD(uint32_t, finished_laps) + DEFINE_FIELD(uint32_t, ticks_at_last_lap) + DEFINE_FIELD(uint32_t, lap_start_ticks) + DEFINE_FIELD(float, estimated_finish) + DEFINE_FIELD(float, overall_distance) + DEFINE_FIELD(float, wrong_way_timer) +END_DEFINE_CLASS(KartInfoPacket) + +DEFINE_CLASS(TrackSectorPacket) + DEFINE_FIELD(uint32_t, current_graph_node) + DEFINE_FIELD(uint32_t, estimated_valid_graph_node) + DEFINE_FIELD(uint32_t, last_valid_graph_node) + DEFINE_FIELD(Vec3, current_track_coords) + DEFINE_FIELD(Vec3, estimated_valid_track_coords) + DEFINE_FIELD(Vec3, latest_valid_track_coords) + DEFINE_FIELD(bool, on_road) + DEFINE_FIELD(uint32_t, last_triggered_checkline) +END_DEFINE_CLASS(TrackSectorPacket) + +DEFINE_CLASS(CheckStructureSubPacket) + DEFINE_FIELD(Vec3, previous_position) + DEFINE_FIELD(bool, is_active) +END_DEFINE_CLASS(CheckStructureSubPacket) + +DEFINE_CLASS(CheckStructurePacket) + AUX_VAR(uint32_t, karts_count) + DEFINE_VECTOR_OBJ(CheckStructureSubPacket, karts_count, player_check_state) +END_DEFINE_CLASS(CheckStructurePacket) + +DEFINE_CLASS(CheckLineSubPacket) + DEFINE_FIELD(bool, previous_sign) +END_DEFINE_CLASS(CheckLineSubPacket) +DEFINE_CLASS(CheckLinePacket) + AUX_VAR(uint32_t, karts_count) + DEFINE_FIELD_PTR(CheckStructurePacket, check_structure_packet) + DEFINE_VECTOR_OBJ(CheckLineSubPacket, karts_count, subpackets) +END_DEFINE_CLASS(CheckLinePacket) + +DEFINE_CLASS(LinearWorldCompleteStatePacket) + AUX_VAR(uint32_t, karts_count) + AUX_VAR(uint32_t, track_sectors_count) + DEFINE_FIELD(uint32_t, fastest_lap_ticks) + DEFINE_FIELD(float, distance_increase) + DEFINE_VECTOR_OBJ(PlacementPacket, karts_count, kart_placements) + DEFINE_VECTOR_OBJ(KartInfoPacket, karts_count, kart_infos) + DEFINE_VECTOR_OBJ(TrackSectorPacket, track_sectors_count, track_sectors) + DEFINE_FIELD(uint8_t, check_structure_count) + DEFINE_VECTOR_OBJ(CheckStructurePacket, check_structure_count, check_structures) +END_DEFINE_CLASS(LinearWorldCompleteStatePacket) + +// 0: peer->getClientCapabilities().find("soccer_fixes") != peer->getClientCapabilities().end() +DEFINE_CLASS(ScorerDataPacket) + DEFINE_FIELD(uint8_t, id) + DEFINE_FIELD(uint8_t, correct_goal) + DEFINE_FIELD(float, time) + DEFINE_FIELD(std::string, kart) + DEFINE_FIELD(widestr, player) + DEFINE_FIELD_OPTIONAL(std::string, country_code, check(0)) + DEFINE_FIELD_OPTIONAL(uint8_t, handicap_level, check(0)) +END_DEFINE_CLASS(ScoreerDataPacket) + +DEFINE_CLASS(SoccerWorldCompleteStatePacket) + DEFINE_FIELD(uint32_t, red_scorers_count) + DEFINE_VECTOR_OBJ(ScorerDataPacket, red_scorers_count, red_scorers) + DEFINE_FIELD(uint32_t, blue_scorers_count) + DEFINE_VECTOR_OBJ(ScorerDataPacket, blue_scorers_count, blue_scorers) + DEFINE_FIELD(uint32_t, reser_ball_ticks) + DEFINE_FIELD(uint32_t, ticks_back_to_own_goal) +END_DEFINE_CLASS(SoccerWorldCompleteStatePacket) + +DEFINE_CLASS(FFAWorldCompleteStatePacket) + AUX_VAR(uint32_t, karts_count) + DEFINE_VECTOR(uint32_t, karts_count, scores) +END_DEFINE_CLASS(FFAWorldCompleteStatePacket) + +DEFINE_CLASS(CTFWorldCompleteStatePacket) + DEFINE_FIELD_PTR(FFAWorldCompleteStatePacket, ffa_packet) + DEFINE_FIELD(uint32_t, red_score) + DEFINE_FIELD(uint32_t, blue_score) +END_DEFINE_CLASS(CTFWorldCompleteStatePacket) + +DEFINE_CLASS(WorldCompleteStatePacket) + DEFINE_FIELD_OPTIONAL(LinearWorldCompleteStatePacket, linear_packet, check(0)) + DEFINE_FIELD_OPTIONAL(SoccerWorldCompleteStatePacket, soccer_packet, check(1)) + DEFINE_FIELD_OPTIONAL(FFAWorldCompleteStatePacket, ffa_packet, check(2)) + DEFINE_FIELD_OPTIONAL(CTFWorldCompleteStatePacket, ctf_packet, check(3)) END_DEFINE_CLASS(WorldCompleteStatePacket) DEFINE_CLASS(InsideGameInfoPacket) DEFINE_FIELD(uint8_t, players_size) - DEFINE_VECTOR(EncodedSinglePlayerPacket, players_size, all_players) - DEFINE_VECTOR(KartDataPacket, players_size, players_kart_data) + DEFINE_VECTOR_OBJ(EncodedSinglePlayerPacket, players_size, all_players) + DEFINE_VECTOR_OBJ(KartDataPacket, players_size, players_kart_data) END_DEFINE_CLASS(InsideGameInfoPacket) DEFINE_CLASS(LiveJoinPacket) diff --git a/src/tracks/check_line.cpp b/src/tracks/check_line.cpp index 9c02269f391..4fe5b724e7e 100644 --- a/src/tracks/check_line.cpp +++ b/src/tracks/check_line.cpp @@ -254,23 +254,36 @@ bool CheckLine::isTriggered(const Vec3 &old_pos, const Vec3 &new_pos, } // isTriggered // ---------------------------------------------------------------------------- -void CheckLine::saveCompleteState(BareNetworkString* bns) +std::shared_ptr CheckLine::saveCompleteState() { - CheckStructure::saveCompleteState(bns); World* world = World::getWorld(); + + auto packet = std::make_shared(); + + auto sp = CheckStructure::saveCompleteState(); + packet->check_structure_packet = std::dynamic_pointer_cast(sp); + for (unsigned int i = 0; i < world->getNumKarts(); i++) - bns->addUInt8(m_previous_sign[i] ? 1 : 0); -} // saveCompleteState + { + CheckLineSubPacket subpacket; + subpacket.previous_sign = m_previous_sign[i]; + packet->subpackets.push_back(subpacket); + } + return packet; +} // saveCompleteState // ---------------------------------------------------------------------------- -void CheckLine::restoreCompleteState(const BareNetworkString& b) +void CheckLine::restoreCompleteState(const std::shared_ptr& packet) { - CheckStructure::restoreCompleteState(b); + std::shared_ptr cl_packet = + std::dynamic_pointer_cast(packet); + CheckStructure::restoreCompleteState(cl_packet->check_structure_packet); + m_previous_sign.clear(); World* world = World::getWorld(); for (unsigned int i = 0; i < world->getNumKarts(); i++) { - bool previous_sign = b.getUInt8() == 1; + bool previous_sign = cl_packet->subpackets[i].previous_sign; m_previous_sign.push_back(previous_sign); } } // restoreCompleteState diff --git a/src/tracks/check_line.hpp b/src/tracks/check_line.hpp index 9857ffb081b..bf33270591a 100644 --- a/src/tracks/check_line.hpp +++ b/src/tracks/check_line.hpp @@ -86,9 +86,9 @@ class CheckLine : public CheckStructure * be too heigh to otherwise trigger he cannon). */ void setIgnoreHeight(bool b) { m_ignore_height = b; } // ------------------------------------------------------------------------ - virtual void saveCompleteState(BareNetworkString* bns) OVERRIDE; + virtual std::shared_ptr saveCompleteState() OVERRIDE; // ------------------------------------------------------------------------ - virtual void restoreCompleteState(const BareNetworkString& b) OVERRIDE; + virtual void restoreCompleteState(const std::shared_ptr& packet) OVERRIDE; // ------------------------------------------------------------------------ const Vec3 &getLeftPoint() const { return m_left_point; } // ------------------------------------------------------------------------ diff --git a/src/tracks/check_structure.cpp b/src/tracks/check_structure.cpp index d2b2106dd32..14c387b7d44 100644 --- a/src/tracks/check_structure.cpp +++ b/src/tracks/check_structure.cpp @@ -247,23 +247,40 @@ void CheckStructure::trigger(unsigned int kart_index) } // trigger // ---------------------------------------------------------------------------- -void CheckStructure::saveCompleteState(BareNetworkString* bns) +std::shared_ptr CheckStructure::saveCompleteState() { + std::shared_ptr packet = std::make_shared(); World* world = World::getWorld(); for (unsigned int i = 0; i < world->getNumKarts(); i++) - bns->add(m_previous_position[i]).addUInt8(m_is_active[i] ? 1 : 0); + { + CheckStructureSubPacket subpacket; + subpacket.previous_position = m_previous_position[i]; + subpacket.is_active = m_is_active[i]; + packet->player_check_state.push_back(std::move(subpacket)); + } + return packet; } // saveCompleteState // ---------------------------------------------------------------------------- -void CheckStructure::restoreCompleteState(const BareNetworkString& b) +void CheckStructure::restoreCompleteState(const std::shared_ptr& packet) { + std::shared_ptr check_packet = + std::dynamic_pointer_cast(packet); + m_previous_position.clear(); m_is_active.clear(); World* world = World::getWorld(); + + if (world->getNumKarts() != check_packet->player_check_state.size()) + Log::error("CheckStructure", "Packet's number of karts are not equal: " + "expected %d, received %d", + world->getNumKarts(), check_packet->player_check_state.size()); + for (unsigned int i = 0; i < world->getNumKarts(); i++) { - Vec3 xyz = b.getVec3(); - bool is_active = b.getUInt8() == 1; + CheckStructureSubPacket subpacket = check_packet->player_check_state[i]; + Vec3 xyz = subpacket.previous_position; + bool is_active = subpacket.is_active; m_previous_position.push_back(xyz); m_is_active.push_back(is_active); } diff --git a/src/tracks/check_structure.hpp b/src/tracks/check_structure.hpp index ceba9cd24a5..1f6fc89e432 100644 --- a/src/tracks/check_structure.hpp +++ b/src/tracks/check_structure.hpp @@ -137,9 +137,9 @@ class CheckStructure // ------------------------------------------------------------------------ virtual bool triggeringCheckline() const { return false; } // ------------------------------------------------------------------------ - virtual void saveCompleteState(BareNetworkString* bns); + virtual std::shared_ptr saveCompleteState(); // ------------------------------------------------------------------------ - virtual void restoreCompleteState(const BareNetworkString& b); + virtual void restoreCompleteState(const std::shared_ptr& packet); // ------------------------------------------------------------------------ void saveIsActive(int kart_id, BareNetworkString* bns); // ------------------------------------------------------------------------ diff --git a/src/tracks/track_sector.cpp b/src/tracks/track_sector.cpp index 54d8cde18b8..92ed7d6d613 100644 --- a/src/tracks/track_sector.cpp +++ b/src/tracks/track_sector.cpp @@ -21,6 +21,7 @@ #include "modes/linear_world.hpp" #include "modes/world.hpp" #include "network/network_string.hpp" +#include "network/packet_types.hpp" #include "tracks/check_manager.hpp" #include "tracks/check_structure.hpp" #include "tracks/arena_graph.hpp" @@ -196,23 +197,25 @@ void TrackSector::rewindTo(BareNetworkString* buffer) // ---------------------------------------------------------------------------- /** Save completely for spectating in linear race */ -void TrackSector::saveCompleteState(BareNetworkString* bns) +TrackSectorPacket TrackSector::saveCompleteState() { - bns->addUInt32(m_current_graph_node); - bns->addUInt32(m_estimated_valid_graph_node); - bns->addUInt32(m_last_valid_graph_node); - bns->add(m_current_track_coords); - bns->add(m_estimated_valid_track_coords); - bns->add(m_latest_valid_track_coords); - bns->addUInt8(m_on_road ? 1 : 0); - bns->addUInt32(m_last_triggered_checkline); + TrackSectorPacket packet; + packet.current_graph_node = m_current_graph_node; + packet.estimated_valid_graph_node = m_estimated_valid_graph_node; + packet.last_valid_graph_node = m_last_valid_graph_node; + packet.current_track_coords = m_current_track_coords; + packet.estimated_valid_track_coords = m_estimated_valid_track_coords; + packet.latest_valid_track_coords = m_latest_valid_track_coords; + packet.on_road = m_on_road; + packet.last_triggered_checkline = m_last_triggered_checkline; + return packet; } // saveCompleteState // ---------------------------------------------------------------------------- -void TrackSector::restoreCompleteState(const BareNetworkString& b) +void TrackSector::restoreCompleteState(const TrackSectorPacket& packet) { const int max_node = Graph::get()->getNumNodes(); - m_current_graph_node = b.getUInt32(); + m_current_graph_node = packet.current_graph_node; if (m_current_graph_node >= max_node) { Log::warn("TrackSector", "Server has different graph node list."); @@ -220,21 +223,21 @@ void TrackSector::restoreCompleteState(const BareNetworkString& b) // again it will have at least a valid node m_current_graph_node = 0; } - m_estimated_valid_graph_node = b.getUInt32(); + m_estimated_valid_graph_node = packet.estimated_valid_graph_node; if (m_estimated_valid_graph_node >= max_node) { Log::warn("TrackSector", "Server has different graph node list."); m_estimated_valid_graph_node = 0; } - m_last_valid_graph_node = b.getUInt32(); + m_last_valid_graph_node = packet.last_valid_graph_node; if (m_last_valid_graph_node >= max_node) { Log::warn("TrackSector", "Server has different graph node list."); m_last_valid_graph_node = 0; } - m_current_track_coords = b.getVec3(); - m_estimated_valid_track_coords = b.getVec3(); - m_latest_valid_track_coords = b.getVec3(); - m_on_road = b.getUInt8() == 1; - m_last_triggered_checkline = b.getUInt32(); + m_current_track_coords = packet.current_track_coords; + m_estimated_valid_track_coords = packet.estimated_valid_track_coords; + m_latest_valid_track_coords = packet.latest_valid_track_coords; + m_on_road = packet.on_road; + m_last_triggered_checkline = packet.last_triggered_checkline; } // restoreCompleteState diff --git a/src/tracks/track_sector.hpp b/src/tracks/track_sector.hpp index c57389faf0a..818b88002b0 100644 --- a/src/tracks/track_sector.hpp +++ b/src/tracks/track_sector.hpp @@ -23,6 +23,7 @@ class BareNetworkString; class Track; +class TrackSectorPacket; /** This object keeps track of which sector an object is on. A sector is * actually just the graph node (it's called sector to better distinguish @@ -99,9 +100,9 @@ class TrackSector // ------------------------------------------------------------------------ void rewindTo(BareNetworkString* buffer); // ------------------------------------------------------------------------ - void saveCompleteState(BareNetworkString* bns); + TrackSectorPacket saveCompleteState(); // ------------------------------------------------------------------------ - void restoreCompleteState(const BareNetworkString& b); + void restoreCompleteState(const TrackSectorPacket& packet); }; // TrackSector From da14f6d99ae3212dd04d3366cae34c04467c5112 Mon Sep 17 00:00:00 2001 From: kimden <23140380+kimden@users.noreply.github.com> Date: Thu, 27 Mar 2025 01:58:55 +0400 Subject: [PATCH 03/34] More small packets [skip ci, not able to build yet] --- src/modes/linear_world.cpp | 5 +- src/network/event.cpp | 9 +++ src/network/event.hpp | 3 + src/network/packet_types.hpp | 18 ++++++ src/network/packet_types_base.hpp | 58 ++++++++++++++++++- src/network/protocols/client_lobby.cpp | 10 ++-- src/network/protocols/server_lobby.cpp | 36 +++++++----- .../dialogs/network_player_dialog.cpp | 22 ++++--- 8 files changed, 131 insertions(+), 30 deletions(-) diff --git a/src/modes/linear_world.cpp b/src/modes/linear_world.cpp index b95827e869a..b061c4b745f 100644 --- a/src/modes/linear_world.cpp +++ b/src/modes/linear_world.cpp @@ -1261,7 +1261,10 @@ std::shared_ptr LinearWorld::saveCompleteState(std::shared_ptr const uint8_t cc = (uint8_t)cm->getCheckStructureCount(); packet->check_structure_count = cc; for (unsigned i = 0; i < cc; i++) - packet->check_structures.push_back(cm->getCheckStructure(i)->saveCompleteState()); + { + const auto& item = cm->getCheckStructure(i)->saveCompleteState(); + packet->check_structures.push_back(std::dynamic_pointer_cast(item)); + } return packet; } // saveCompleteState diff --git a/src/network/event.cpp b/src/network/event.cpp index 6c5227ef85f..d6f71528d45 100644 --- a/src/network/event.cpp +++ b/src/network/event.cpp @@ -104,4 +104,13 @@ Event::~Event() { delete m_data; } // ~Event +//----------------------------------------------------------------------------- +template +T Event::getPacket() +{ + T packet; + packet.fromNetworkString(m_data); + return packet; +} // getPacket +//----------------------------------------------------------------------------- \ No newline at end of file diff --git a/src/network/event.hpp b/src/network/event.hpp index 2dab2701c81..f30bb4eb3ad 100644 --- a/src/network/event.hpp +++ b/src/network/event.hpp @@ -127,6 +127,9 @@ class Event // ------------------------------------------------------------------------ PeerDisconnectInfo getPeerDisconnectInfo() const { return m_pdi; } // ------------------------------------------------------------------------ + template + T getPacket(); + // ------------------------------------------------------------------------ }; // class Event diff --git a/src/network/packet_types.hpp b/src/network/packet_types.hpp index 740c499cf49..6e0c76562c8 100644 --- a/src/network/packet_types.hpp +++ b/src/network/packet_types.hpp @@ -129,6 +129,7 @@ struct Name: public Checkable, public Packet { \ #define DEFINE_FIXED_FIELD(Type, Var, Value) Type Var; #define DEFINE_VECTOR(Type, Size, Var) std::vector Var; #define DEFINE_VECTOR_OBJ(Type, Size, Var) std::vector Var; +#define DEFINE_VECTOR_OBJ_PTR(Type, Size, Var) std::vector> Var; #define END_DEFINE_CLASS(Name) }; #include "network/packet_types_base.hpp" @@ -141,6 +142,7 @@ struct Name: public Checkable, public Packet { \ #undef DEFINE_FIELD_OPTIONAL #undef DEFINE_VECTOR #undef DEFINE_VECTOR_OBJ +#undef DEFINE_VECTOR_OBJ_PTR #undef END_DEFINE_CLASS //---------------------- To NetworkString ------------------------------------- @@ -179,6 +181,11 @@ inline void Name::toNetworkString(NetworkString* ns) const \ Value[Value##_cnt].toNetworkString(ns); \ } +#define DEFINE_VECTOR_OBJ_PTR(Type, Size, Value) \ + for (unsigned Value##_cnt = 0; Value##_cnt < Size; ++Value##_cnt) { \ + Value[Value##_cnt]->toNetworkString(ns); \ + } + #define END_DEFINE_CLASS(Name) \ } @@ -192,6 +199,7 @@ inline void Name::toNetworkString(NetworkString* ns) const \ #undef DEFINE_FIELD_OPTIONAL #undef DEFINE_VECTOR #undef DEFINE_VECTOR_OBJ +#undef DEFINE_VECTOR_OBJ_PTR #undef END_DEFINE_CLASS //---------------------- From NetworkString ----------------------------------- @@ -235,6 +243,14 @@ inline void Name::fromNetworkString(NetworkString* ns) \ Var[Var##_cnt].fromNetworkString(ns); \ } +#define DEFINE_VECTOR_OBJ_PTR(Type, Size, Var) \ + Var.resize(Size); \ + for (unsigned Var##_cnt = 0; Var##_cnt < Size; ++Var##_cnt) { \ + Type temp_##Var; \ + temp_##Var.fromNetworkString(ns); \ + Var[Var##_cnt] = std::make_shared(temp_##Var); \ + } + #define END_DEFINE_CLASS(Name) \ } @@ -247,6 +263,8 @@ inline void Name::fromNetworkString(NetworkString* ns) \ #undef DEFINE_FIXED_FIELD #undef DEFINE_FIELD_OPTIONAL #undef DEFINE_VECTOR +#undef DEFINE_VECTOR_OBJ +#undef DEFINE_VECTOR_OBJ_PTR #undef END_DEFINE_CLASS //---------------------- End -------------------------------------------------- diff --git a/src/network/packet_types_base.hpp b/src/network/packet_types_base.hpp index 20651b0d180..af8faa0c73e 100644 --- a/src/network/packet_types_base.hpp +++ b/src/network/packet_types_base.hpp @@ -47,6 +47,7 @@ #include using widestr = irr::core::stringw; +using widestr16 = irr::core::stringw; // but encodeString16 // Note that bools are encoded using int8_t @@ -206,7 +207,7 @@ DEFINE_CLASS(LinearWorldCompleteStatePacket) DEFINE_VECTOR_OBJ(KartInfoPacket, karts_count, kart_infos) DEFINE_VECTOR_OBJ(TrackSectorPacket, track_sectors_count, track_sectors) DEFINE_FIELD(uint8_t, check_structure_count) - DEFINE_VECTOR_OBJ(CheckStructurePacket, check_structure_count, check_structures) + DEFINE_VECTOR_OBJ_PTR(CheckStructurePacket, check_structure_count, check_structures) END_DEFINE_CLASS(LinearWorldCompleteStatePacket) // 0: peer->getClientCapabilities().find("soccer_fixes") != peer->getClientCapabilities().end() @@ -266,4 +267,59 @@ DEFINE_CLASS(LiveJoinPacket) END_DEFINE_CLASS(LiveJoinPacket) +DEFINE_CLASS(ChatPacket) + SYNCHRONOUS(true) + DEFINE_FIXED_FIELD(uint8_t, type, LE_CHAT) + DEFINE_FIELD(widestr16, message) // use encodeString16 ! + // send with PRM_RELIABLE +END_DEFINE_CLASS(ChatPacket) + +DEFINE_CLASS(ChangeTeamPacket) + DEFINE_FIXED_FIELD(uint8_t, type, LE_CHANGE_TEAM) + DEFINE_FIELD(uint8_t, local_id) + // send with PRM_RELIABLE +END_DEFINE_CLASS(ChangeTeamPacket) + +DEFINE_CLASS(KickHostPacket) + DEFINE_FIXED_FIELD(uint8_t, type, LE_KICK_HOST) + DEFINE_FIELD(uint32_t, host_id) + // send with PRM_RELIABLE +END_DEFINE_CLASS(KickHostPacket) + +DEFINE_CLASS(ReportRequestPacket) + DEFINE_FIXED_FIELD(uint8_t, type, LE_REPORT_PLAYER) + DEFINE_FIELD(uint32_t, host_id) + DEFINE_FIELD(widestr16, info) + // send with PRM_RELIABLE +END_DEFINE_CLASS(ReportRequestPacket) + +DEFINE_CLASS(ReportSuccessPacket) + SYNCHRONOUS(true) + DEFINE_FIXED_FIELD(uint8_t, type, LE_REPORT_PLAYER) + DEFINE_FIELD(bool, success) + DEFINE_FIELD(widestr, reported_name) + // send with PRM_RELIABLE +END_DEFINE_CLASS(ReportSuccessPacket) + +DEFINE_CLASS(ChangeHandicapPacket) + DEFINE_FIXED_FIELD(uint8_t, type, LE_CHANGE_HANDICAP) + DEFINE_FIELD(uint8_t, local_id) + DEFINE_FIELD(uint8_t, handicap) + // send with PRM_RELIABLE +END_DEFINE_CLASS(ChangeHandicapPacket) + +DEFINE_CLASS(BackLobbyPacket) + SYNCHRONOUS(true) + DEFINE_FIXED_FIELD(uint8_t, type, LE_BACK_LOBBY) + DEFINE_FIELD(uint8_t, reason) + // send with PRM_RELIABLE +END_DEFINE_CLASS(BackLobbyPacket) + +DEFINE_CLASS(ServerInfoPacket) + SYNCHRONOUS(true) + DEFINE_FIXED_FIELD(uint8_t, type, LE_SERVER_INFO) + //... + // send with PRM_RELIABLE +END_DEFINE_CLASS(ServerInfoPacket) + // end \ No newline at end of file diff --git a/src/network/protocols/client_lobby.cpp b/src/network/protocols/client_lobby.cpp index 79730e05f90..c69bd53a8a2 100644 --- a/src/network/protocols/client_lobby.cpp +++ b/src/network/protocols/client_lobby.cpp @@ -825,10 +825,8 @@ void ClientLobby::handleServerInfo(Event* event) void ClientLobby::updatePlayerList(Event* event) { if (!checkDataSize(event, 1)) return; - NetworkString& data = event->data(); - PlayerListPacket list_packet; - list_packet.fromNetworkString(&data); + auto list_packet = event->getPacket(); bool waiting = list_packet.game_started; if (m_waiting_for_game && !waiting) @@ -1671,9 +1669,11 @@ void ClientLobby::reportSuccess(Event* event) { bool succeeded = false; core::stringw reporting_name; - succeeded = event->data().getUInt8() == 1; + + auto packet = event->getPacket(); + succeeded = packet.success; if (succeeded) - event->data().decodeStringW(&reporting_name); + event->data().decodeStringW(&packet.reported_name); if (succeeded && !reporting_name.empty()) { // I18N: Tell player he has successfully report this named player diff --git a/src/network/protocols/server_lobby.cpp b/src/network/protocols/server_lobby.cpp index 1538bcf0c2f..11b186d479c 100644 --- a/src/network/protocols/server_lobby.cpp +++ b/src/network/protocols/server_lobby.cpp @@ -403,8 +403,8 @@ void ServerLobby::changeTeam(Event* event) if (!checkDataSize(event, 1)) return; - NetworkString& data = event->data(); - uint8_t local_id = data.getUInt8(); + auto packet = event->getPacket(); + uint8_t local_id = packet.local_id; auto& player = event->getPeer()->getPlayerProfiles().at(local_id); getTeamManager()->changeTeam(player); @@ -416,8 +416,8 @@ void ServerLobby::kickHost(Event* event) if (!checkDataSize(event, 4)) return; - NetworkString& data = event->data(); - uint32_t host_id = data.getUInt32(); + auto packet = event->getPacket(); + uint32_t host_id = packet.host_id; std::shared_ptr target = STKHost::get()->findPeerByHostId(host_id); auto initiator = event->getPeerSP(); @@ -581,9 +581,9 @@ void ServerLobby::writePlayerReport(Event* event) return; auto reporter_npp = reporter->getMainProfile(); - uint32_t reporting_host_id = event->data().getUInt32(); - core::stringw info; - event->data().decodeString16(&info); + auto packet = event->getPacket(); + uint32_t reporting_host_id = packet.host_id; + core::stringw info = packet.info; if (info.empty()) return; @@ -597,9 +597,10 @@ void ServerLobby::writePlayerReport(Event* event) if (written) { NetworkString* success = getNetworkString(); - success->setSynchronous(true); - success->addUInt8(LE_REPORT_PLAYER).addUInt8(1) - .encodeString(reporting_npp->getName()); + ReportSuccessPacket packet2; + packet2.success = 1; + packet2.reported_name = reporting_npp->getName(); + packet2.toNetworkString(success); event->getPeer()->sendPacket(success, PRM_RELIABLE); delete success; } @@ -962,8 +963,9 @@ void ServerLobby::asynchronousUpdate() resetPeersReady(); m_state = LOAD_WORLD; - NetworkString* load_world_message = getLoadWorldMessage(players, - false/*live_join*/); + NetworkString* load_world_message; + LoadWorldPacket packet = getLoadWorldMessage(players, false/*live_join*/); + packet.toNetworkString(load_world_message); Comm::sendMessageToPeers(load_world_message); // updatePlayerList so the in lobby players (if any) can see always // spectators join the game @@ -1075,17 +1077,19 @@ bool ServerLobby::canLiveJoinNow() const void ServerLobby::rejectLiveJoin(std::shared_ptr peer, BackLobbyReason blr) { NetworkString* reset = getNetworkString(2); - reset->setSynchronous(true); - reset->addUInt8(LE_BACK_LOBBY).addUInt8(blr); + BackLobbyPacket packet1; + packet1.reason = blr; + packet1.toNetworkString(reset); peer->sendPacket(reset, PRM_RELIABLE); delete reset; updatePlayerList(); NetworkString* server_info = getNetworkString(); - server_info->setSynchronous(true); - server_info->addUInt8(LE_SERVER_INFO); + ServerInfoPacket packet2; + //packet2.server_info = ...; m_game_setup->addServerInfo(server_info); + packet2.toNetworkString(server_info); peer->sendPacket(server_info, PRM_RELIABLE); delete server_info; diff --git a/src/states_screens/dialogs/network_player_dialog.cpp b/src/states_screens/dialogs/network_player_dialog.cpp index 177915bf9e0..2aed23b1c4c 100644 --- a/src/states_screens/dialogs/network_player_dialog.cpp +++ b/src/states_screens/dialogs/network_player_dialog.cpp @@ -27,6 +27,7 @@ #include "guiengine/widgets/text_box_widget.hpp" #include "online/online_profile.hpp" #include "network/network_string.hpp" +#include "network/packet_types.hpp" #include "network/protocols/client_lobby.hpp" #include "network/stk_host.hpp" #include "states_screens/dialogs/general_text_field_dialog.hpp" @@ -204,8 +205,10 @@ void NetworkPlayerDialog::onUpdate(float dt) if (info.empty()) return false; NetworkString report(PROTOCOL_LOBBY_ROOM); - report.addUInt8(LobbyEvent::LE_REPORT_PLAYER) - .addUInt32(host_id).encodeString16(info); + ReportRequestPacket packet; + packet.host_id = host_id; + packet.info = info; + packet.toNetworkString(&report); Comm::sendToServer(&report, PRM_RELIABLE); return true; }); @@ -248,7 +251,9 @@ GUIEngine::EventPropagation else if (selection == m_kick_widget->m_properties[PROP_ID]) { NetworkString kick(PROTOCOL_LOBBY_ROOM); - kick.addUInt8(LobbyEvent::LE_KICK_HOST).addUInt32(m_host_id); + KickHostPacket packet; + packet.host_id = m_host_id; + packet.toNetworkString(&kick); Comm::sendToServer(&kick, PRM_RELIABLE); m_self_destroy = true; return GUIEngine::EVENT_BLOCK; @@ -257,8 +262,9 @@ GUIEngine::EventPropagation selection == m_change_team_widget->m_properties[PROP_ID]) { NetworkString change_team(PROTOCOL_LOBBY_ROOM); - change_team.addUInt8(LobbyEvent::LE_CHANGE_TEAM) - .addUInt8(m_local_id); + ChangeTeamPacket packet; + packet.local_id = m_local_id; + packet.toNetworkString(&change_team); Comm::sendToServer(&change_team, PRM_RELIABLE); m_self_destroy = true; return GUIEngine::EVENT_BLOCK; @@ -272,8 +278,10 @@ GUIEngine::EventPropagation new_handicap = HANDICAP_MEDIUM; } NetworkString change_handicap(PROTOCOL_LOBBY_ROOM); - change_handicap.addUInt8(LobbyEvent::LE_CHANGE_HANDICAP) - .addUInt8(m_local_id).addUInt8(new_handicap); + ChangeHandicapPacket packet; + packet.local_id = m_local_id; + packet.handicap = new_handicap; + packet.toNetworkString(&change_handicap); Comm::sendToServer(&change_handicap, PRM_RELIABLE); m_self_destroy = true; return GUIEngine::EVENT_BLOCK; From ebb90b7e3eef92631fb75a91a19d2d29fc77e4b4 Mon Sep 17 00:00:00 2001 From: kimden <23140380+kimden@users.noreply.github.com> Date: Sat, 29 Mar 2025 03:38:27 +0400 Subject: [PATCH 04/34] A few more unfinished packets for today [skip ci] It's getting slightly annoying tho with all those 'arbitrary' options. I should reconsider some syntax things --- src/network/kart_data.cpp | 14 ++-- src/network/kart_data.hpp | 2 +- src/network/packet_types_base.hpp | 52 +++++++++++++- src/network/protocols/server_lobby.cpp | 97 ++++++++++++-------------- src/network/protocols/server_lobby.hpp | 2 +- src/utils/chat_manager.cpp | 5 ++ 6 files changed, 109 insertions(+), 63 deletions(-) diff --git a/src/network/kart_data.cpp b/src/network/kart_data.cpp index ad00fbc7588..f3ecefc14de 100644 --- a/src/network/kart_data.cpp +++ b/src/network/kart_data.cpp @@ -24,15 +24,15 @@ KartData::KartData(const KartProperties* kp) } // KartData(KartProperties*) // ---------------------------------------------------------------------------- -KartData::KartData(const BareNetworkString& ns) +KartData::KartData(const KartDataPacket& packet) { - ns.decodeString(&m_kart_type); + m_kart_type = packet.kart_type; if (!m_kart_type.empty()) { - m_width = ns.getFloat(); - m_height = ns.getFloat(); - m_length = ns.getFloat(); - m_gravity_shift = ns.getVec3(); + m_width = packet.parameters->width; + m_height = packet.parameters->height; + m_length = packet.parameters->length; + m_gravity_shift = packet.parameters->gravity_shift; } else { @@ -40,7 +40,7 @@ KartData::KartData(const BareNetworkString& ns) m_height = 0.0f; m_length = 0.0f; } -} // KartData(BareNetworkString&) +} // KartData(KartDataPacket&) // ---------------------------------------------------------------------------- KartDataPacket KartData::encode() const diff --git a/src/network/kart_data.hpp b/src/network/kart_data.hpp index 1d4ec033509..95cbc08d83e 100644 --- a/src/network/kart_data.hpp +++ b/src/network/kart_data.hpp @@ -27,7 +27,7 @@ class KartData // ------------------------------------------------------------------------ KartData(const KartProperties* kp); // ------------------------------------------------------------------------ - KartData(const BareNetworkString& ns); + KartData(const KartDataPacket& packet); // ------------------------------------------------------------------------ KartDataPacket encode() const; diff --git a/src/network/packet_types_base.hpp b/src/network/packet_types_base.hpp index af8faa0c73e..415024d03b6 100644 --- a/src/network/packet_types_base.hpp +++ b/src/network/packet_types_base.hpp @@ -49,6 +49,9 @@ using widestr = irr::core::stringw; using widestr16 = irr::core::stringw; // but encodeString16 +// temp +constexpr int IDONT_KNOW = 0; + // Note that bools are encoded using int8_t DEFINE_CLASS(PlayerListProfilePacket) @@ -270,7 +273,8 @@ END_DEFINE_CLASS(LiveJoinPacket) DEFINE_CLASS(ChatPacket) SYNCHRONOUS(true) DEFINE_FIXED_FIELD(uint8_t, type, LE_CHAT) - DEFINE_FIELD(widestr16, message) // use encodeString16 ! + DEFINE_FIELD(widestr16, message) // use encodeString16 ! max len is 360 + DEFINE_FIELD_OPTIONAL(KartTeam, kart_team) // KartTeam is uint8_t // send with PRM_RELIABLE END_DEFINE_CLASS(ChatPacket) @@ -318,8 +322,52 @@ END_DEFINE_CLASS(BackLobbyPacket) DEFINE_CLASS(ServerInfoPacket) SYNCHRONOUS(true) DEFINE_FIXED_FIELD(uint8_t, type, LE_SERVER_INFO) - //... + //...kimden: fill this // send with PRM_RELIABLE END_DEFINE_CLASS(ServerInfoPacket) +DEFINE_CLASS(AssetsPacket) + DEFINE_FIELD(uint16_t, karts_number) + DEFINE_VECTOR(std::string, karts_number, karts) + DEFINE_FIELD(uint16_t, maps_number) + DEFINE_VECTOR(std::string, maps_number, maps) +END_DEFINE_CLASS(AssetsPacket) + +DEFINE_CLASS(NewAssetsPacket) + DEFINE_FIXED_FIELD(uint8_t, type, LE_ASSETS_UPDATE) + DEFINE_FIELD(AssetsPacket, assets) +END_DEFINE_CLASS(NewAssetsPacket) + +DEFINE_CLASS(PlayerKartsPacket) + DEFINE_FIELD(uint8_t, players_count) + DEFINE_VECTOR_OBJ(std::string, players_count, karts) + + // I don't care about compilation for now but don't want extra macroses yet either. + DEFINE_VECTOR_OBJ/*_OPTIONAL*/(KartDataPacket, players_count, kart_data/*, IDONT_KNOW*/) // if has "real_addon_karts" in cap AND anything is sent +END_DEFINE_CLASS(PlayerKartsPacket) + +DEFINE_CLASS(LiveJoinRequestPacket) + DEFINE_FIXED_FIELD(uint8_t, type, LE_LIVE_JOIN) + DEFINE_FIELD(bool, is_spectator) + DEFINE_FIELD_OPTIONAL(PlayerKartsPacket, player_karts) // is it optional? +END_DEFINE_CLASS(LiveJoinRequestPacket) + +DEFINE_CLASS(FinishedLoadingLiveJoinPacket) + DEFINE_FIXED_FIELD(uint8_t, type, LE_CLIENT_LOADED_WORLD) +END_DEFINE_CLASS(FinishedLoadingLiveJoinPacket) + +DEFINE_CLASS(ConnectionRequestedPacket) + DEFINE_FIELD(uint32_t, version) + DEFINE_FIELD(std::string, user_version) + DEFINE_FIELD(uint16_t, capabilities_count) + DEFINE_VECTOR(std::string, capabilities_count, capabilities) + DEFINE_FIELD(AssetsPacket, assets) + DEFINE_FIELD(uint8_t, players_count) + DEFINE_FIELD(uint32_t, online_id) + DEFINE_FIELD(uint32_t, encrypted_size) + // to be continued +END_DEFINE_CLASS(ConnectionRequestedPacket) + + + // end \ No newline at end of file diff --git a/src/network/protocols/server_lobby.cpp b/src/network/protocols/server_lobby.cpp index 11b186d479c..bfb4343904c 100644 --- a/src/network/protocols/server_lobby.cpp +++ b/src/network/protocols/server_lobby.cpp @@ -363,35 +363,12 @@ void ServerLobby::handleChat(Event* event) if (!checkDataSize(event, 1) || !getChatManager()->getChat()) return; auto peer = event->getPeerSP(); + auto packet = event->getPacket(); - core::stringw message; - event->data().decodeString16(&message, 360/*max_len*/); - - // Check if the message starts with "(the name of main profile): " to prevent - // impersonation, see #5121. - std::string message_utf8 = StringUtils::wideToUtf8(message); - std::string prefix = StringUtils::wideToUtf8( - event->getPeer()->getPlayerProfiles()[0]->getName()) + ": "; - - if (!StringUtils::startsWith(message_utf8, prefix)) - { - NetworkString* chat = getNetworkString(); - chat->setSynchronous(true); - // This string is not set to be translatable, because it is - // currently written by the server. The server would have - // to send a warning for interpretation by the client to - // allow proper translation. Also, this string can only be - // triggered with modified STK clients anyways. - core::stringw warn = "Don't try to impersonate others!"; - chat->addUInt8(LE_CHAT).encodeString16(warn); - event->getPeer()->sendPacket(chat, PRM_RELIABLE); - delete chat; - return; - } - + core::stringw message = packet.message; KartTeam target_team = KART_TEAM_NONE; - if (event->data().size() > 0) - target_team = (KartTeam)event->data().getUInt8(); + if (packet.kart_team) + target_team = *(packet.kart_team); getChatManager()->handleNormalChatMessage(peer, StringUtils::wideToUtf8(message), target_team, m_name_decorator); @@ -405,8 +382,8 @@ void ServerLobby::changeTeam(Event* event) auto packet = event->getPacket(); uint8_t local_id = packet.local_id; - auto& player = event->getPeer()->getPlayerProfiles().at(local_id); + auto& player = event->getPeer()->getPlayerProfiles().at(local_id); getTeamManager()->changeTeam(player); } // changeTeam @@ -1106,8 +1083,8 @@ void ServerLobby::liveJoinRequest(Event* event) // in general, but you know what caused it if smth goes wrong. std::shared_ptr peer = event->getPeerSP(); - const NetworkString& data = event->data(); - bool spectator = data.getUInt8() == 1; + auto packet = event->getPacket(); + bool spectator = packet.is_spectator; if (!canLiveJoinNow()) { @@ -1125,7 +1102,7 @@ void ServerLobby::liveJoinRequest(Event* event) if (!spectator) { auto& spectators_by_limit = getCrownManager()->getSpectatorsByLimit(); - setPlayerKarts(data, peer); + setPlayerKarts(packet.player_karts, peer); std::vector used_id; for (unsigned i = 0; i < peer->getPlayerProfiles().size(); i++) @@ -1166,10 +1143,13 @@ void ServerLobby::liveJoinRequest(Event* event) std::vector > players = getLivePlayers(); - NetworkString* load_world_message = getLoadWorldMessage(players, - true/*live_join*/); + + NetworkString* load_world_message; + LoadWorldPacket load_world_packet = getLoadWorldMessage(players, true/*live_join*/); + load_world_packet.toNetworkString(load_world_message); peer->sendPacket(load_world_message, PRM_RELIABLE); delete load_world_message; + peer->updateLastActivity(); } // liveJoinRequest @@ -1243,6 +1223,7 @@ int ServerLobby::getReservedId(std::shared_ptr& p, void ServerLobby::finishedLoadingLiveJoinClient(Event* event) { std::shared_ptr peer = event->getPeerSP(); + auto unused = event->getPacket(); if (!canLiveJoinNow()) { rejectLiveJoin(peer, BLR_NO_GAME_FOR_LIVE_JOIN); @@ -2270,10 +2251,16 @@ void ServerLobby::saveIPBanTable(const SocketAddress& addr) bool ServerLobby::handleAssets(Event* event) { const NetworkString& ns = event->data(); + auto packet = event->getPacket(); std::shared_ptr peer = event->getPeerSP(); - std::set client_karts, client_maps; - getClientAssetsFromNetworkString(ns, client_karts, client_maps); + std::set client_karts; + for (const std::string& item: packet.assets.karts) + client_karts.insert(item); + + std::set client_maps; + for (const std::string& item: packet.assets.maps) + client_maps.insert(item); return handleAssetsAndAddonScores(peer, client_karts, client_maps); } // handleAssets @@ -2345,7 +2332,7 @@ bool ServerLobby::handleAssetsAndAddonScores(std::shared_ptr peer, void ServerLobby::connectionRequested(Event* event) { std::shared_ptr peer = event->getPeerSP(); - NetworkString& data = event->data(); + auto packet = event->getPacket(); if (!checkDataSize(event, 14)) return; peer->cleanPlayerProfiles(); @@ -2367,7 +2354,7 @@ void ServerLobby::connectionRequested(Event* event) } // Check server version - int version = data.getUInt32(); + int version = packet.version; auto& stk_config = STKConfig::get(); @@ -2384,30 +2371,36 @@ void ServerLobby::connectionRequested(Event* event) Log::verbose("ServerLobby", "Player refused: wrong server version"); return; } - std::string user_version; - data.decodeString(&user_version); + std::string user_version = packet.user_version; event->getPeer()->setUserVersion(user_version); - unsigned list_caps = data.getUInt16(); + unsigned list_caps = packet.capabilities_count; std::set caps; for (unsigned i = 0; i < list_caps; i++) { - std::string cap; - data.decodeString(&cap); + std::string cap = packet.capabilities[i]; caps.insert(cap); } event->getPeer()->setClientCapabilities(caps); std::set client_karts, client_maps; - getClientAssetsFromNetworkString(data, client_karts, client_maps); + + std::set client_karts; + for (const std::string& item: packet.assets.karts) + client_karts.insert(item); + + std::set client_maps; + for (const std::string& item: packet.assets.maps) + client_maps.insert(item); + if (!handleAssetsAndAddonScores(event->getPeerSP(), client_karts, client_maps)) return; - unsigned player_count = data.getUInt8(); + unsigned player_count = packet.players_count; uint32_t online_id = 0; uint32_t encrypted_size = 0; - online_id = data.getUInt32(); - encrypted_size = data.getUInt32(); + online_id = packet.online_id; + encrypted_size = packet.encrypted_size; // Will be disconnected if banned by IP testBannedForIP(peer); @@ -3947,14 +3940,13 @@ void ServerLobby::addLiveJoinPlaceholder( } // addLiveJoinPlaceholder //----------------------------------------------------------------------------- -void ServerLobby::setPlayerKarts(const NetworkString& ns, std::shared_ptr peer) const +void ServerLobby::setPlayerKarts(const PlayerKartsPacket& packet, std::shared_ptr peer) const { - unsigned player_count = ns.getUInt8(); + unsigned player_count = packet.players_count; player_count = std::min(player_count, (unsigned)peer->getPlayerProfiles().size()); for (unsigned i = 0; i < player_count; i++) { - std::string kart; - ns.decodeString(&kart); + std::string kart = packet.karts[i]; std::string username = StringUtils::wideToUtf8( peer->getPlayerProfiles()[i]->getName()); if (getKartElimination()->isEliminated(username)) @@ -3975,12 +3967,13 @@ void ServerLobby::setPlayerKarts(const NetworkString& ns, std::shared_ptrgetPlayerProfiles()[i]->setKartName( getAssetManager()->getKartForBadKartChoice(peer, name, current_kart)); } + /* packet.kart_data should be a pointer later*/ if (peer->getClientCapabilities().find("real_addon_karts") == - peer->getClientCapabilities().end() || ns.size() == 0) + peer->getClientCapabilities().end() || packet.kart_data.empty()) return; for (unsigned i = 0; i < player_count; i++) { - KartData kart_data(ns); + KartData kart_data(packet.kart_data[i]); std::string type = kart_data.m_kart_type; auto& player = peer->getPlayerProfiles()[i]; const std::string& kart_id = player->getKartName(); diff --git a/src/network/protocols/server_lobby.hpp b/src/network/protocols/server_lobby.hpp index 137b633a449..0ad0e569757 100644 --- a/src/network/protocols/server_lobby.hpp +++ b/src/network/protocols/server_lobby.hpp @@ -263,7 +263,7 @@ class ServerLobby : public LobbyProtocol, public LobbyContextUser LoadWorldPacket getLoadWorldMessage( std::vector >& players, bool live_join) const; - void setPlayerKarts(const NetworkString& ns, std::shared_ptr peer) const; + void setPlayerKarts(const PlayerKartsPacket& packet, std::shared_ptr peer) const; bool handleAssets(Event* event); bool handleAssetsAndAddonScores(std::shared_ptr peer, diff --git a/src/utils/chat_manager.cpp b/src/utils/chat_manager.cpp index 2f2abffd8ff..d076cd7a04f 100644 --- a/src/utils/chat_manager.cpp +++ b/src/utils/chat_manager.cpp @@ -193,6 +193,11 @@ void ChatManager::handleNormalChatMessage(std::shared_ptr peer, if (!StringUtils::startsWith(message, prefix)) { + // This string is not set to be translatable, because it is + // currently written by the server. The server would have + // to send a warning for interpretation by the client to + // allow proper translation. Also, this string can only be + // triggered with modified STK clients anyways. Comm::sendStringToPeer(peer, "Don't try to impersonate others!"); return; } From a6f43f2b8463b314297d77c03241359e6dc0c306 Mon Sep 17 00:00:00 2001 From: kimden <23140380+kimden@users.noreply.github.com> Date: Thu, 3 Apr 2025 02:53:54 +0400 Subject: [PATCH 05/34] Process simple packets in the bottom half of ServerLobby --- src/network/packet_types.hpp | 2 +- src/network/packet_types_base.hpp | 82 ++++++ src/network/peer_vote.hpp | 11 +- src/network/protocols/client_lobby.cpp | 2 +- src/network/protocols/server_lobby.cpp | 331 ++++++++++++++----------- src/network/protocols/server_lobby.hpp | 1 + src/utils/communication.cpp | 16 +- 7 files changed, 286 insertions(+), 159 deletions(-) diff --git a/src/network/packet_types.hpp b/src/network/packet_types.hpp index 6e0c76562c8..196c63b6d3b 100644 --- a/src/network/packet_types.hpp +++ b/src/network/packet_types.hpp @@ -88,7 +88,7 @@ enum BackLobbyReason : uint8_t BLR_NO_GAME_FOR_LIVE_JOIN = 1, BLR_NO_PLACE_FOR_LIVE_JOIN = 2, BLR_ONE_PLAYER_IN_RANKED_MATCH = 3, - BLR_SERVER_ONWER_QUITED_THE_GAME = 4, + BLR_SERVER_OWNER_QUIT_THE_GAME = 4, BLR_SPECTATING_NEXT_GAME = 5 }; diff --git a/src/network/packet_types_base.hpp b/src/network/packet_types_base.hpp index 415024d03b6..3abe1157e90 100644 --- a/src/network/packet_types_base.hpp +++ b/src/network/packet_types_base.hpp @@ -322,6 +322,7 @@ END_DEFINE_CLASS(BackLobbyPacket) DEFINE_CLASS(ServerInfoPacket) SYNCHRONOUS(true) DEFINE_FIXED_FIELD(uint8_t, type, LE_SERVER_INFO) + DEFINE_FIELD(uint8_t, placeholder) //...kimden: fill this // send with PRM_RELIABLE END_DEFINE_CLASS(ServerInfoPacket) @@ -346,6 +347,11 @@ DEFINE_CLASS(PlayerKartsPacket) DEFINE_VECTOR_OBJ/*_OPTIONAL*/(KartDataPacket, players_count, kart_data/*, IDONT_KNOW*/) // if has "real_addon_karts" in cap AND anything is sent END_DEFINE_CLASS(PlayerKartsPacket) +DEFINE_CLASS(KartSelectionRequestPacket) + DEFINE_FIXED_FIELD(uint8_t, type, LE_KART_SELECTION) + DEFINE_FIELD(PlayerKartsPacket, karts) +END_DEFINE_CLASS(KartSelectionRequestPacket) + DEFINE_CLASS(LiveJoinRequestPacket) DEFINE_FIXED_FIELD(uint8_t, type, LE_LIVE_JOIN) DEFINE_FIELD(bool, is_spectator) @@ -368,6 +374,82 @@ DEFINE_CLASS(ConnectionRequestedPacket) // to be continued END_DEFINE_CLASS(ConnectionRequestedPacket) +DEFINE_CLASS(KartInfoRequestPacket) + // check if synch + DEFINE_FIXED_FIELD(uint8_t, type, LE_KART_INFO) + DEFINE_FIELD(uint8_t, kart_id) +END_DEFINE_CLASS(KartInfoRequestPacket) + +DEFINE_CLASS(KartInfoPacket) + SYNCHRONOUS(true) + DEFINE_FIXED_FIELD(uint8_t, type, LE_KART_INFO) + DEFINE_FIELD(uint32_t, live_join_util_ticks) + DEFINE_FIELD(uint8_t, kart_id) + DEFINE_FIELD(widestr, player_name) + DEFINE_FIELD(uint32_t, host_id) + DEFINE_FIELD(float, default_kart_color) + DEFINE_FIELD(uint32_t, online_id) + DEFINE_FIELD(uint8_t, handicap) + DEFINE_FIELD(uint8_t, local_player_id) + DEFINE_FIELD(std::string, kart_name) + DEFINE_FIELD(std::string, country_code) + // The field below is present if "real_addon_karts" is in capabilities + DEFINE_FIELD_OBJ(KartDataPacket, kart_data) + // send with PRM_RELIABLE +END_DEFINE_CLASS(KartInfoPacket) + +DEFINE_CLASS(ConfigServerPacket) + DEFINE_FIXED_FIELD(uint8_t, type, LE_CONFIG_SERVER) + DEFINE_FIELD(uint8_t, difficulty) + DEFINE_FIELD(uint8_t, game_mode) + DEFINE_FIELD(bool, soccer_goal_target) +END_DEFINE_CLASS(ConfigServerPacket) +DEFINE_CLASS(ConnectionRefusedPacket) + SYNCHRONOUS(true) + DEFINE_FIXED_FIELD(uint8_t, type, LE_CONNECTION_REFUSED) + DEFINE_FIELD(uint8_t, reason) + DEFINE_FIELD_OPTIONAL(std::string, message); + // send with PRM_RELIABLE, warning! can be sent unencrypted! +END_DEFINE_CLASS(ConnectionRefusedPacket) + +DEFINE_CLASS(StartGamePacket) + SYNCHRONOUS(true) + DEFINE_FIXED_FIELD(uint8_t, type, LE_START_RACE) + DEFINE_FIELD(uint64_t, start_time) + DEFINE_FIELD(uint8_t, check_count) + DEFINE_FIELD(ItemCompleteStatePacket, item_complete_state) /* this had operator += instead */ + // send with PRM_RELIABLE +END_DEFINE_CLASS(StartGamePacket) + +DEFINE_CLASS(VotePacket) /* vote of a player sent to others */ + SYNCHRONOUS(true) + DEFINE_FIXED_FIELD(uint8_t, type, LE_VOTE) + DEFINE_FIELD(uint32_t, host_id) + DEFINE_FIELD(PeerVotePacket, vote) +END_DEFINE_CLASS(VotePacket) + +DEFINE_CLASS(VoteRequestPacket) + DEFINE_FIXED_FIELD(uint8_t, type, LE_VOTE) + DEFINE_FIELD(PeerVotePacket, vote) +END_DEFINE_CLASS(VoteRequestPacket) + +DEFINE_CLASS(ServerOwnershipPacket) + SYNCHRONOUS(true) + DEFINE_FIXED_FIELD(uint8_t, type, LE_SERVER_OWNERSHIP) +END_DEFINE_CLASS(ServerOwnershipPacket) + +DEFINE_CLASS(ConnectionAcceptedPacket) + SYNCHRONOUS(true) + DEFINE_FIXED_FIELD(uint8_t, type, LE_CONNECTION_ACCEPTED) + DEFINE_FIELD(uint32_t, host_id) + DEFINE_FIELD(uint32_t, server_version) + DEFINE_FIELD(uint16_t, capabilities_size) + DEFINE_VECTOR(std::string, capabilities_size, capabilities) + DEFINE_FIELD(float, auto_start_timer) + DEFINE_FIELD(uint32_t, state_frequency) + DEFINE_FIELD(bool, chat_allowed) + DEFINE_FIELD(bool, reports_allowed) +END_DEFINE_CLASS(ConnectionAcceptedPacket) // end \ No newline at end of file diff --git a/src/network/peer_vote.hpp b/src/network/peer_vote.hpp index 4ead5b211e9..a955ee8b108 100644 --- a/src/network/peer_vote.hpp +++ b/src/network/peer_vote.hpp @@ -52,13 +52,12 @@ class PeerVote // ------------------------------------------------------ /** Initialised this object from a data in a network string. */ - PeerVote(NetworkString &ns) + PeerVote(const PeerVotePacket& packet) { - ns.decodeStringW(&m_player_name); - ns.decodeString(&m_track_name); - m_num_laps = ns.getUInt8(); - m_reverse = ns.getUInt8()!=0; - + m_player_name = packet.player_name; + m_track_name = packet.track_name; + m_num_laps = packet.num_laps; + m_reverse = packet.is_reverse; } // PeerVote(NetworkString &) // ------------------------------------------------------ diff --git a/src/network/protocols/client_lobby.cpp b/src/network/protocols/client_lobby.cpp index c69bd53a8a2..7d3d25d904b 100644 --- a/src/network/protocols/client_lobby.cpp +++ b/src/network/protocols/client_lobby.cpp @@ -1272,7 +1272,7 @@ void ClientLobby::backToLobby(Event *event) // I18N: Error message shown if only 1 player remains in network msg = _("Only 1 player remaining, returning to lobby."); break; - case BLR_SERVER_ONWER_QUITED_THE_GAME: + case BLR_SERVER_OWNER_QUIT_THE_GAME: // I18N: Error message shown when all players will go back to lobby // when server owner quited the game if (!STKHost::get()->isClientServer()) diff --git a/src/network/protocols/server_lobby.cpp b/src/network/protocols/server_lobby.cpp index bfb4343904c..ed6daff47fa 100644 --- a/src/network/protocols/server_lobby.cpp +++ b/src/network/protocols/server_lobby.cpp @@ -2230,11 +2230,14 @@ void ServerLobby::clientDisconnected(Event* event) void ServerLobby::kickPlayerWithReason(std::shared_ptr peer, const char* reason) const { NetworkString *message = getNetworkString(2); - message->setSynchronous(true); - message->addUInt8(LE_CONNECTION_REFUSED).addUInt8(RR_BANNED); - message->encodeString(std::string(reason)); - peer->cleanPlayerProfiles(); + + ConnectionRefusedPacket packet; + packet.reason = RR_BANNED; + packet.message = reason; + packet.toNetworkString(message); peer->sendPacket(message, PRM_RELIABLE, PEM_UNENCRYPTED); + + peer->cleanPlayerProfiles(); peer->reset(); delete message; } // kickPlayerWithReason @@ -2250,7 +2253,6 @@ void ServerLobby::saveIPBanTable(const SocketAddress& addr) bool ServerLobby::handleAssets(Event* event) { - const NetworkString& ns = event->data(); auto packet = event->getPacket(); std::shared_ptr peer = event->getPeerSP(); @@ -2280,25 +2282,13 @@ bool ServerLobby::handleAssetsAndAddonScores(std::shared_ptr peer, else { NetworkString *message = getNetworkString(2); - message->setSynchronous(true); - message->addUInt8(LE_CONNECTION_REFUSED) - .addUInt8(RR_INCOMPATIBLE_DATA); - - std::string advice = getSettings()->getIncompatibleAdvice(); - if (!advice.empty()) { - NetworkString *incompatible_reason = getNetworkString(); - incompatible_reason->addUInt8(LE_CHAT); - incompatible_reason->setSynchronous(true); - incompatible_reason->encodeString16( - StringUtils::utf8ToWide(advice)); - peer->sendPacket(incompatible_reason, - PRM_RELIABLE, PEM_UNENCRYPTED); - Log::info("ServerLobby", "Sent advice"); - delete incompatible_reason; - } + ConnectionRefusedPacket packet; + packet.reason = RR_INCOMPATIBLE_DATA; + packet.message = getSettings()->getIncompatibleAdvice(); + packet.toNetworkString(message); + peer->sendPacket(message, PRM_RELIABLE, PEM_UNENCRYPTED); peer->cleanPlayerProfiles(); - peer->sendPacket(message, PRM_RELIABLE, PEM_UNENCRYPTED); peer->reset(); delete message; } @@ -2343,12 +2333,14 @@ void ServerLobby::connectionRequested(Event* event) m_game_setup->isGrandPrixStarted()*/)) { NetworkString *message = getNetworkString(2); - message->setSynchronous(true); - message->addUInt8(LE_CONNECTION_REFUSED).addUInt8(RR_BUSY); + ConnectionRefusedPacket packet; + packet.reason = RR_BUSY; + packet.toNetworkString(message); // send only to the peer that made the request and disconnect it now peer->sendPacket(message, PRM_RELIABLE, PEM_UNENCRYPTED); - peer->reset(); delete message; + + peer->reset(); Log::verbose("ServerLobby", "Player refused: selection started"); return; } @@ -2362,12 +2354,13 @@ void ServerLobby::connectionRequested(Event* event) version > stk_config->m_max_server_version) { NetworkString *message = getNetworkString(2); - message->setSynchronous(true); - message->addUInt8(LE_CONNECTION_REFUSED) - .addUInt8(RR_INCOMPATIBLE_DATA); + ConnectionRefusedPacket packet; + packet.reason = RR_INCOMPATIBLE_DATA; + packet.toNetworkString(message); peer->sendPacket(message, PRM_RELIABLE, PEM_UNENCRYPTED); - peer->reset(); delete message; + + peer->reset(); Log::verbose("ServerLobby", "Player refused: wrong server version"); return; } @@ -2423,11 +2416,13 @@ void ServerLobby::connectionRequested(Event* event) (unsigned)getSettings()->getServerMaxPlayers()) { NetworkString *message = getNetworkString(2); - message->setSynchronous(true); - message->addUInt8(LE_CONNECTION_REFUSED).addUInt8(RR_TOO_MANY_PLAYERS); + ConnectionRefusedPacket packet; + packet.reason = RR_TOO_MANY_PLAYERS; + packet.toNetworkString(message); peer->sendPacket(message, PRM_RELIABLE, PEM_UNENCRYPTED); - peer->reset(); delete message; + + peer->reset(); Log::verbose("ServerLobby", "Player refused: too many players"); return; } @@ -2464,11 +2459,13 @@ void ServerLobby::connectionRequested(Event* event) if (failed_validation || failed_strictness || failed_anywhere_ai || failed_unhandled_ai) { NetworkString* message = getNetworkString(2); - message->setSynchronous(true); - message->addUInt8(LE_CONNECTION_REFUSED).addUInt8(RR_INVALID_PLAYER); + ConnectionRefusedPacket packet; + packet.reason = RR_INVALID_PLAYER; + packet.toNetworkString(message); peer->sendPacket(message, PRM_RELIABLE, PEM_UNENCRYPTED); - peer->reset(); delete message; + + peer->reset(); Log::verbose("ServerLobby", "Player refused: invalid player"); return; } @@ -2509,14 +2506,14 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr peer, if (getSettings()->isTempBanned(username)) { NetworkString* message = getNetworkString(2); - message->setSynchronous(true); - message->addUInt8(LE_CONNECTION_REFUSED) - .addUInt8(RR_BANNED); - std::string tempban = "Please behave well next time."; - message->encodeString(tempban); + ConnectionRefusedPacket packet; + packet.reason = RR_BANNED; + packet.message = "Please behave well next time."; + packet.toNetworkString(message); peer->sendPacket(message, PRM_RELIABLE, PEM_UNENCRYPTED); - peer->reset(); delete message; + + peer->reset(); Log::verbose("ServerLobby", "Player refused: invalid player"); return; } @@ -2526,12 +2523,13 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr peer, if (password != server_pw) { NetworkString *message = getNetworkString(2); - message->setSynchronous(true); - message->addUInt8(LE_CONNECTION_REFUSED) - .addUInt8(RR_INCORRECT_PASSWORD); + ConnectionRefusedPacket packet; + packet.reason = RR_INCORRECT_PASSWORD; + packet.toNetworkString(message); peer->sendPacket(message, PRM_RELIABLE, PEM_UNENCRYPTED); - peer->reset(); delete message; + + peer->reset(); Log::verbose("ServerLobby", "Player refused: incorrect password"); return; } @@ -2548,12 +2546,13 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr peer, (unsigned)getSettings()->getServerMaxPlayers()) { NetworkString *message = getNetworkString(2); - message->setSynchronous(true); - message->addUInt8(LE_CONNECTION_REFUSED) - .addUInt8(RR_TOO_MANY_PLAYERS); + ConnectionRefusedPacket packet; + packet.reason = RR_TOO_MANY_PLAYERS; + packet.toNetworkString(message); peer->sendPacket(message, PRM_RELIABLE, PEM_UNENCRYPTED); - peer->reset(); delete message; + + peer->reset(); Log::verbose("ServerLobby", "Player refused: too many players"); return; } @@ -2565,12 +2564,13 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr peer, if (getSettings()->isRanked() && duplicated_ranked_player) { NetworkString* message = getNetworkString(2); - message->setSynchronous(true); - message->addUInt8(LE_CONNECTION_REFUSED) - .addUInt8(RR_INVALID_PLAYER); + ConnectionRefusedPacket packet; + packet.reason = RR_INVALID_PLAYER; + packet.toNetworkString(message); peer->sendPacket(message, PRM_RELIABLE, PEM_UNENCRYPTED); - peer->reset(); delete message; + + peer->reset(); Log::verbose("ServerLobby", "Player refused: invalid player"); return; } @@ -2661,33 +2661,32 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr peer, // send a message to the one that asked to connect NetworkString* server_info = getNetworkString(); - server_info->setSynchronous(true); - server_info->addUInt8(LE_SERVER_INFO); - m_game_setup->addServerInfo(server_info); + getServerInfoPacket().toNetworkString(server_info); peer->sendPacket(server_info); delete server_info; peer->updateLastActivity(); const bool game_started = m_state.load() != WAITING_FOR_START_GAME; - NetworkString* message_ack = getNetworkString(4); - message_ack->setSynchronous(true); - // connection success -- return the host id of peer - float auto_start_timer = getTimeUntilExpiration(); - message_ack->addUInt8(LE_CONNECTION_ACCEPTED).addUInt32(peer->getHostId()) - .addUInt32(ServerConfig::m_server_version); auto& stk_config = STKConfig::get(); + NetworkString* message_ack = getNetworkString(4); + ConnectionAcceptedPacket packet; - message_ack->addUInt16( - (uint16_t)stk_config->m_network_capabilities.size()); + // connection success -- return the host id of peer + float auto_start_timer = getTimeUntilExpiration(); + packet.host_id = peer->getHostId(); + packet.server_version = ServerConfig::m_server_version; + packet.capabilities_size = (uint16_t)stk_config->m_network_capabilities.size(); for (const std::string& cap : stk_config->m_network_capabilities) - message_ack->encodeString(cap); + packet.capabilities.push_back(cap); + + packet.auto_start_timer = auto_start_timer; + packet.state_frequency = getSettings()->getStateFrequency(); + packet.chat_allowed = getChatManager()->getChat(); + packet.reports_allowed = playerReportsTableExists(); - message_ack->addFloat(auto_start_timer) - .addUInt32(getSettings()->getStateFrequency()) - .addUInt8(getChatManager()->getChat() ? 1 : 0) - .addUInt8(playerReportsTableExists() ? 1 : 0); + packet.toNetworkString(message_ack); peer->setSpectator(false); @@ -2768,13 +2767,9 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr peer, break; } } - NetworkString* chat = getNetworkString(); - chat->addUInt8(LE_CHAT); - chat->setSynchronous(true); - std::string warning = getKartElimination()->getWarningMessage(hasEliminatedPlayer); - chat->encodeString16(StringUtils::utf8ToWide(warning)); - peer->sendPacket(chat, PRM_RELIABLE); - delete chat; + + // This ns packet wasn't replaced with function immediately, I could mess up then... + sendStringToPeer(peer, getKartElimination()->getWarningMessage(hasEliminatedPlayer)); } if (getSettings()->isRecordingReplays()) { @@ -2999,8 +2994,8 @@ void ServerLobby::updateServerOwner(bool force) if (m_server_owner.expired() || m_server_owner.lock() != owner) { NetworkString* ns = getNetworkString(); - ns->setSynchronous(true); - ns->addUInt8(LE_SERVER_OWNERSHIP); + ServerOwnershipPacket packet; + packet.toNetworkString(ns); owner->sendPacket(ns); delete ns; } @@ -3026,9 +3021,9 @@ void ServerLobby::kartSelectionRequested(Event* event) event->getPeer()->getPlayerProfiles().empty()) return; - const NetworkString& data = event->data(); + auto packet = event->getPacket(); std::shared_ptr peer = event->getPeerSP(); - setPlayerKarts(data, peer); + setPlayerKarts(packet.karts, peer); } // kartSelectionRequested //----------------------------------------------------------------------------- @@ -3054,8 +3049,8 @@ void ServerLobby::handlePlayerVote(Event* event) if (!canVote(event->getPeerSP())) return; - NetworkString& data = event->data(); - PeerVote vote(data); + auto packet = event->getPacket(); + PeerVote vote(packet.vote); Log::debug("ServerLobby", "Vote from client: host %d, track %s, laps %d, reverse %d.", event->getPeer()->getHostId(), vote.m_track_name.c_str(), @@ -3088,10 +3083,10 @@ void ServerLobby::handlePlayerVote(Event* event) // Now inform all clients about the vote NetworkString other = NetworkString(PROTOCOL_LOBBY_ROOM); - other.setSynchronous(true); - other.addUInt8(LE_VOTE); - other.addUInt32(event->getPeer()->getHostId()); - vote.encode(&other); + VotePacket packet; + packet.host_id = event->getPeer()->getHostId(); + packet.vote = vote.encode(); + packet.toNetworkString(&other); Comm::sendMessageToPeers(&other); } // handlePlayerVote @@ -3346,15 +3341,17 @@ void ServerLobby::configPeersStartTime() // (due to packet loss), the start time will still ahead of current time uint64_t start_time = STKHost::get()->getNetworkTimer() + (uint64_t)2500; powerup_manager->setRandomSeed(start_time); + NetworkString* ns = getNetworkString(10); - ns->setSynchronous(true); - ns->addUInt8(LE_START_RACE).addUInt64(start_time); - const uint8_t cc = (uint8_t)Track::getCurrentTrack()->getCheckManager()->getCheckStructureCount(); - ns->addUInt8(cc); - *ns += *m_items_complete_state; - m_client_starting_time = start_time; + StartGamePacket packet; + packet.start_time = start_time; + packet.check_count = (uint8_t)Track::getCurrentTrack()->getCheckManager()->getCheckStructureCount(); + packet.item_complete_state = m_items_complete_state; // was operator += + packet.toNetworkString(ns); Comm::sendMessageToPeers(ns, PRM_RELIABLE); + m_client_starting_time = start_time; + const unsigned jitter_tolerance = getSettings()->getJitterTolerance(); Log::info("ServerLobby", "Max ping from peers: %d, jitter tolerance: %d", max_ping, jitter_tolerance); @@ -3424,10 +3421,9 @@ void ServerLobby::resetServer() addWaitingPlayersToGame(); resetPeersReady(); updatePlayerList(true/*update_when_reset_server*/); + NetworkString* server_info = getNetworkString(); - server_info->setSynchronous(true); - server_info->addUInt8(LE_SERVER_INFO); - m_game_setup->addServerInfo(server_info); + getServerInfoPacket().toNetworkString(server_info); Comm::sendMessageToPeersInServer(server_info); delete server_info; @@ -3688,11 +3684,12 @@ void ServerLobby::handleServerConfiguration(std::shared_ptr peer, if (getAssetManager()->checkIfNoCommonMaps(assets)) { NetworkString *message = getNetworkString(2); - message->setSynchronous(true); - message->addUInt8(LE_CONNECTION_REFUSED) - .addUInt8(RR_INCOMPATIBLE_DATA); - peer->cleanPlayerProfiles(); + ConnectionRefusedPacket packet; + packet.reason = RR_INCOMPATIBLE_DATA; + packet.toNetworkString(message); peer->sendPacket(message, PRM_RELIABLE); + + peer->cleanPlayerProfiles(); peer->reset(); delete message; Log::verbose("ServerLobby", @@ -3725,9 +3722,7 @@ void ServerLobby::handleServerConfiguration(std::shared_ptr peer, } NetworkString* server_info = getNetworkString(); - server_info->setSynchronous(true); - server_info->addUInt8(LE_SERVER_INFO); - m_game_setup->addServerInfo(server_info); + getServerInfoPacket().toNetworkString(server_info); Comm::sendMessageToPeers(server_info); delete server_info; @@ -3767,10 +3762,10 @@ void ServerLobby::handleServerConfiguration(Event* event) bool new_soccer_goal_target = getSettings()->isSoccerGoalTargetInConfig(); if (event != NULL) { - NetworkString& data = event->data(); - new_difficulty = data.getUInt8(); - new_game_mode = data.getUInt8(); - new_soccer_goal_target = data.getUInt8() == 1; + auto packet = event->getPacket(); + new_difficulty = packet.difficulty; + new_game_mode = packet.game_mode; + new_soccer_goal_target = packet.soccer_goal_target; } handleServerConfiguration( (event ? event->getPeerSP() : std::shared_ptr()), @@ -3790,21 +3785,24 @@ void ServerLobby::handleServerConfiguration(Event* event) */ void ServerLobby::changeHandicap(Event* event) { - NetworkString& data = event->data(); + auto packet = event->getPacket(); + if (m_state.load() != WAITING_FOR_START_GAME && !event->getPeer()->isWaitingForGame()) { Log::warn("ServerLobby", "Set handicap at wrong time."); return; } - uint8_t local_id = data.getUInt8(); + + uint8_t local_id = packet.local_id; + uint8_t handicap_id = packet.handicap; auto& player = event->getPeer()->getPlayerProfiles().at(local_id); - uint8_t handicap_id = data.getUInt8(); if (handicap_id >= HANDICAP_COUNT) { Log::warn("ServerLobby", "Wrong handicap %d.", handicap_id); return; } + HandicapLevel h = (HandicapLevel)handicap_id; player->setHandicap(h); updatePlayerList(); @@ -3992,8 +3990,8 @@ void ServerLobby::handleKartInfo(Event* event) return; std::shared_ptr peer = event->getPeerSP(); - const NetworkString& data = event->data(); - uint8_t kart_id = data.getUInt8(); + auto request_packet = event->getPacket(); + uint8_t kart_id = request_packet.kart_id; if (kart_id > RaceManager::get()->getNumPlayers()) return; @@ -4003,16 +4001,23 @@ void ServerLobby::handleKartInfo(Event* event) const RemoteKartInfo& rki = RaceManager::get()->getKartInfo(kart_id); NetworkString* ns = getNetworkString(1); - ns->setSynchronous(true); - ns->addUInt8(LE_KART_INFO).addUInt32(live_join_util_ticks) - .addUInt8(kart_id) .encodeString(rki.getPlayerName()) - .addUInt32(rki.getHostId()).addFloat(rki.getDefaultKartColor()) - .addUInt32(rki.getOnlineId()).addUInt8(rki.getHandicap()) - .addUInt8((uint8_t)rki.getLocalPlayerId()) - .encodeString(rki.getKartName()).encodeString(rki.getCountryCode()); + KartInfoPacket packet; + packet.live_join_util_ticks = live_join_util_ticks; + packet.kart_id = kart_id; + packet.player_name = rki.getPlayerName(); + packet.host_id = rki.getHostId(); + packet.default_kart_color = rki.getDefaultKartColor(); + packet.online_id = rki.getOnlineId(); + packet.handicap = rki.getHandicap(); + packet.local_player_id = (uint8_t)rki.getLocalPlayerId(); + packet.kart_name = rki.getKartName(); + packet.country_code = rki.getCountryCode(); + if (peer->getClientCapabilities().find("real_addon_karts") != peer->getClientCapabilities().end()) - rki.getKartData().encode(ns); + packet.kart_data = rki.getKartData().encode(); + + packet.toNetworkString(ns); peer->sendPacket(ns, PRM_RELIABLE); delete ns; @@ -4059,12 +4064,14 @@ void ServerLobby::clientInGameWantsToBackLobby(Event* event) } else exitGameState(); + NetworkString* back_to_lobby = getNetworkString(2); - back_to_lobby->setSynchronous(true); - back_to_lobby->addUInt8(LE_BACK_LOBBY) - .addUInt8(BLR_SERVER_ONWER_QUITED_THE_GAME); + BackLobbyPacket packet; + packet.reason = BLR_SERVER_OWNER_QUIT_THE_GAME; + packet.toNetworkString(back_to_lobby); Comm::sendMessageToPeersInServer(back_to_lobby, PRM_RELIABLE); delete back_to_lobby; + m_rs_state.store(RS_ASYNC_RESET); return; } @@ -4099,15 +4106,16 @@ void ServerLobby::clientInGameWantsToBackLobby(Event* event) peer->setSpectator(false); NetworkString* reset = getNetworkString(2); - reset->setSynchronous(true); - reset->addUInt8(LE_BACK_LOBBY).addUInt8(BLR_NONE); + BackLobbyPacket packet; + packet.reason = BLR_NONE; + packet.toNetworkString(reset); peer->sendPacket(reset, PRM_RELIABLE); delete reset; + updatePlayerList(); + NetworkString* server_info = getNetworkString(); - server_info->setSynchronous(true); - server_info->addUInt8(LE_SERVER_INFO); - m_game_setup->addServerInfo(server_info); + getServerInfoPacket().toNetworkString(server_info); peer->sendPacket(server_info, PRM_RELIABLE); delete server_info; @@ -4133,11 +4141,12 @@ void ServerLobby::clientSelectingAssetsWantsToBackLobby(Event* event) event->getPeer()->getHostId() == m_client_server_host_id.load()) { NetworkString* back_to_lobby = getNetworkString(2); - back_to_lobby->setSynchronous(true); - back_to_lobby->addUInt8(LE_BACK_LOBBY) - .addUInt8(BLR_SERVER_ONWER_QUITED_THE_GAME); + BackLobbyPacket packet; + packet.reason = BLR_SERVER_OWNER_QUIT_THE_GAME; + packet.toNetworkString(back_to_lobby); Comm::sendMessageToPeersInServer(back_to_lobby, PRM_RELIABLE); delete back_to_lobby; + resetVotingTime(); resetServer(); m_rs_state.store(RS_NONE); @@ -4149,15 +4158,16 @@ void ServerLobby::clientSelectingAssetsWantsToBackLobby(Event* event) peer->setSpectator(false); NetworkString* reset = getNetworkString(2); - reset->setSynchronous(true); - reset->addUInt8(LE_BACK_LOBBY).addUInt8(BLR_NONE); + BackLobbyPacket packet; + packet.reason = BLR_NONE; + packet.toNetworkString(reset); peer->sendPacket(reset, PRM_RELIABLE); delete reset; + updatePlayerList(); + NetworkString* server_info = getNetworkString(); - server_info->setSynchronous(true); - server_info->addUInt8(LE_SERVER_INFO); - m_game_setup->addServerInfo(server_info); + getServerInfoPacket().toNetworkString(server_info); peer->sendPacket(server_info, PRM_RELIABLE); delete server_info; @@ -4255,13 +4265,14 @@ void ServerLobby::writeOwnReport(std::shared_ptr reporter, std::shared_ if (written) { NetworkString* success = getNetworkString(); - success->setSynchronous(true); + ReportSuccessPacket packet; + packet.success = 1; if (reporter == reporting) - success->addUInt8(LE_REPORT_PLAYER).addUInt8(1) - .encodeString(m_game_setup->getServerNameUtf8()); + packet.reported_name = StringUtils::utf8ToWide(m_game_setup->getServerNameUtf8()); else - success->addUInt8(LE_REPORT_PLAYER).addUInt8(1) - .encodeString(reporting_npp->getName()); + packet.reported_name = reporting_npp->getName(); + + packet.toNetworkString(success); reporter->sendPacket(success, PRM_RELIABLE); delete success; } @@ -4269,6 +4280,33 @@ void ServerLobby::writeOwnReport(std::shared_ptr reporter, std::shared_ } // writeOwnReport //----------------------------------------------------------------------------- +void ServerLobby::sendStringToPeer(std::shared_ptr peer, const std::string& s) +{ + if (!peer) + { + sendStringToAllPeers(s); + return; + } + NetworkString* chat = getNetworkString(); + chat->addUInt8(LE_CHAT); + chat->setSynchronous(true); + chat->encodeString16(StringUtils::utf8ToWide(s)); + peer->sendPacket(chat, PRM_RELIABLE); + delete chat; +} // sendStringToPeer +//----------------------------------------------------------------------------- + +void ServerLobby::sendStringToAllPeers(const std::string& s) +{ + NetworkString* chat = getNetworkString(); + chat->addUInt8(LE_CHAT); + chat->setSynchronous(true); + chat->encodeString16(StringUtils::utf8ToWide(s)); + sendMessageToPeers(chat, PRM_RELIABLE); + delete chat; +} // sendStringToAllPeers +//----------------------------------------------------------------------------- + std::string ServerLobby::encodeProfileNameForPeer( std::shared_ptr npp, STKPeer* peer) @@ -4465,12 +4503,19 @@ bool ServerLobby::playerReportsTableExists() const //----------------------------------------------------------------------------- +ServerInfoPacket ServerLobby::getServerInfoPacket() const +{ + ServerInfoPacket packet; + packet.placeholder = 0; + // use m_game_setup->addServerInfo(server_info); + return packet; +} // getServerInfoPacket +//----------------------------------------------------------------------------- + void ServerLobby::sendServerInfoToEveryone() const { NetworkString* server_info = getNetworkString(); - server_info->setSynchronous(true); - server_info->addUInt8(LE_SERVER_INFO); - m_game_setup->addServerInfo(server_info); + getServerInfoPacket().toNetworkString(server_info); Comm::sendMessageToPeers(server_info); delete server_info; } // sendServerInfoToEveryone diff --git a/src/network/protocols/server_lobby.hpp b/src/network/protocols/server_lobby.hpp index 0ad0e569757..2a10d9fa120 100644 --- a/src/network/protocols/server_lobby.hpp +++ b/src/network/protocols/server_lobby.hpp @@ -360,6 +360,7 @@ class ServerLobby : public LobbyProtocol, public LobbyContextUser bool playerReportsTableExists() const; + ServerInfoPacket getServerInfoPacket() const; void sendServerInfoToEveryone() const; bool isWorldPicked() const { return m_state.load() >= LOAD_WORLD; } diff --git a/src/utils/communication.cpp b/src/utils/communication.cpp index cc7ee3e5544..e3d88046cb8 100644 --- a/src/utils/communication.cpp +++ b/src/utils/communication.cpp @@ -73,11 +73,11 @@ void sendStringToPeer(std::shared_ptr peer, const std::string& s) { sendStringToAllPeers(s); return; - } + } NetworkString* chat = new NetworkString(ProtocolType::PROTOCOL_LOBBY_ROOM); - chat->addUInt8(LE_CHAT); - chat->setSynchronous(true); - chat->encodeString16(StringUtils::utf8ToWide(s)); + ChatPacket packet; + packet.message = StringUtils::utf8ToWide(s); + packet.toNetworkString(chat); peer->sendPacket(chat, PRM_RELIABLE); delete chat; } // sendStringToPeer @@ -86,10 +86,10 @@ void sendStringToPeer(std::shared_ptr peer, const std::string& s) void sendStringToAllPeers(const std::string& s) { NetworkString* chat = new NetworkString(ProtocolType::PROTOCOL_LOBBY_ROOM); - chat->addUInt8(LE_CHAT); - chat->setSynchronous(true); - chat->encodeString16(StringUtils::utf8ToWide(s)); - sendMessageToPeers(chat, PRM_RELIABLE); + ChatPacket packet; + packet.message = StringUtils::utf8ToWide(s); + packet.toNetworkString(chat); + Comm::sendMessageToPeers(chat, PRM_RELIABLE); delete chat; } // sendStringToAllPeers //----------------------------------------------------------------------------- From 6b08222928a3f9510706d0793c16b433f81c934e Mon Sep 17 00:00:00 2001 From: kimden <23140380+kimden@users.noreply.github.com> Date: Fri, 4 Apr 2025 01:42:43 +0400 Subject: [PATCH 06/34] Even more packets in ServerLobby --- src/network/packet_types_base.hpp | 62 ++++ src/network/protocols/server_lobby.cpp | 456 ++++++++++++------------- src/network/protocols/server_lobby.hpp | 4 +- src/utils/communication.cpp | 16 +- src/utils/lobby_asset_manager.cpp | 14 +- src/utils/lobby_asset_manager.hpp | 4 +- src/utils/lobby_gp_manager.cpp | 26 +- src/utils/lobby_gp_manager.hpp | 2 +- 8 files changed, 326 insertions(+), 258 deletions(-) diff --git a/src/network/packet_types_base.hpp b/src/network/packet_types_base.hpp index 3abe1157e90..defe84d37e3 100644 --- a/src/network/packet_types_base.hpp +++ b/src/network/packet_types_base.hpp @@ -334,6 +334,13 @@ DEFINE_CLASS(AssetsPacket) DEFINE_VECTOR(std::string, maps_number, maps) END_DEFINE_CLASS(AssetsPacket) +DEFINE_CLASS(AssetsPacket2) + DEFINE_FIELD(uint16_t, karts_number) + DEFINE_FIELD(uint16_t, maps_number) + DEFINE_VECTOR(std::string, karts_number, karts) + DEFINE_VECTOR(std::string, maps_number, maps) +END_DEFINE_CLASS(AssetsPacket2) + DEFINE_CLASS(NewAssetsPacket) DEFINE_FIXED_FIELD(uint8_t, type, LE_ASSETS_UPDATE) DEFINE_FIELD(AssetsPacket, assets) @@ -452,4 +459,59 @@ DEFINE_CLASS(ConnectionAcceptedPacket) DEFINE_FIELD(bool, reports_allowed) END_DEFINE_CLASS(ConnectionAcceptedPacket) +DEFINE_CLASS(PlayerDisconnectedPacket) + SYNCHRONOUS(true) + DEFINE_FIXED_FIELD(uint8_t, type, LE_PLAYER_DISCONNECTED) + DEFINE_FIELD(uint8_t, players_size) + DEFINE_FIELD(uint32_t, host_id) + DEFINE_VECTOR(std::string, players_size, names) +END_DEFINE_CLASS(PlayerDisconnectedPacket) + +DEFINE_CLASS(PointChangesPacket) + DEFINE_FIELD(uint8_t, player_count) + DEFINE_VECTOR(float, player_count, changes) +END_DEFINE_CLASS(PointChangesPacket) + +DEFINE_CLASS(StartSelectionPacket) + SYNCHRONOUS(true) + DEFINE_FIXED_FIELD(uint8_t, type, LE_START_SELECTION) + DEFINE_FIELD(float, voting_timeout) + DEFINE_FIELD(bool, no_kart_selection) + DEFINE_FIELD(bool, fixed_length) + DEFINE_FIELD(bool, track_voting) + DEFINE_FIELD(AssetsPacket2, assets) + // send with PRM_RELIABLE +END_DEFINE_CLASS(StartSelectionPacket) + +DEFINE_CLASS(BadTeamPacket) + SYNCHRONOUS(true) + DEFINE_FIXED_FIELD(uint8_t, type, LE_BAD_TEAM) + // send with PRM_RELIABLE +END_DEFINE_CLASS(BadTeamPacket) + +DEFINE_CLASS(RaceFinishedPacket) + SYNCHRONOUS(true) + DEFINE_FIXED_FIELD(uint8_t, type, LE_RACE_FINISHED) + DEFINE_FIELD_OPTIONAL(uint32_t, fastest_lap, check(0)) /* if linear (incl. gp) */ + DEFINE_FIELD_OPTIONAL(widestr, fastest_kart_name, check(0)) /* if linear (incl. gp) */ + DEFINE_FIELD_OPTIONAL(GPScoresPacket, gp_scores, check(1)) /* if gp */ + DEFINE_FIELD(bool, point_changes_indication) + DEFINE_FIELD(PointChangesPacket, point_changes) + // send with PRM_RELIABLE +END_DEFINE_CLASS(RaceFinishedPacket) + +DEFINE_CLASS(GPIndividualScorePacket) + DEFINE_FIELD(uint32_t, last_score) + DEFINE_FIELD(uint32_t, cur_score) + DEFINE_FIELD(float, overall_time) +END_DEFINE_CLASS(GPIndividualScorePacket) + +DEFINE_CLASS(GPScoresPacket) + DEFINE_FIELD(uint8_t, total_gp_tracks) + DEFINE_FIELD(uint8_t, all_tracks_size) + DEFINE_VECTOR(std::string, all_tracks_size, all_tracks) + DEFINE_FIELD(uint8_t, num_players) + DEFINE_VECTOR(GPIndividualScorePacket, num_players, scores) +END_DEFINE_CLASS(GPScoresPacket) + // end \ No newline at end of file diff --git a/src/network/protocols/server_lobby.cpp b/src/network/protocols/server_lobby.cpp index ed6daff47fa..0a596709d6e 100644 --- a/src/network/protocols/server_lobby.cpp +++ b/src/network/protocols/server_lobby.cpp @@ -140,29 +140,6 @@ namespace return players; } // getLivePlayers //------------------------------------------------------------------------- - - void getClientAssetsFromNetworkString(const NetworkString& ns, - std::set& client_karts, - std::set& client_maps) - { - client_karts.clear(); - client_maps.clear(); - const unsigned kart_num = ns.getUInt16(); - const unsigned maps_num = ns.getUInt16(); - for (unsigned i = 0; i < kart_num; i++) - { - std::string kart; - ns.decodeString(&kart); - client_karts.insert(kart); - } - for (unsigned i = 0; i < maps_num; i++) - { - std::string map; - ns.decodeString(&map); - client_maps.insert(map); - } - } // getClientAssetsFromNetworkString - //------------------------------------------------------------------------- } // anonymous namespace // ============================================================================ @@ -573,13 +550,13 @@ void ServerLobby::writePlayerReport(Event* event) reporting_peer, reporting_npp, info); if (written) { - NetworkString* success = getNetworkString(); + NetworkString* ns = getNetworkString(); ReportSuccessPacket packet2; packet2.success = 1; packet2.reported_name = reporting_npp->getName(); - packet2.toNetworkString(success); - event->getPeer()->sendPacket(success, PRM_RELIABLE); - delete success; + packet2.toNetworkString(ns); + event->getPeer()->sendPacket(ns, PRM_RELIABLE); + delete ns; } #endif } // writePlayerReport @@ -940,15 +917,15 @@ void ServerLobby::asynchronousUpdate() resetPeersReady(); m_state = LOAD_WORLD; - NetworkString* load_world_message; + NetworkString* ns; LoadWorldPacket packet = getLoadWorldMessage(players, false/*live_join*/); - packet.toNetworkString(load_world_message); - Comm::sendMessageToPeers(load_world_message); + packet.toNetworkString(ns); + Comm::sendMessageToPeers(ns); // updatePlayerList so the in lobby players (if any) can see always // spectators join the game if (has_always_on_spectators || !previous_spectate_mode.empty()) updatePlayerList(); - delete load_world_message; + delete ns; if (RaceManager::get()->getMinorMode() == RaceManager::MINOR_MODE_SOCCER) @@ -1053,22 +1030,22 @@ bool ServerLobby::canLiveJoinNow() const */ void ServerLobby::rejectLiveJoin(std::shared_ptr peer, BackLobbyReason blr) { - NetworkString* reset = getNetworkString(2); + NetworkString* ns = getNetworkString(2); BackLobbyPacket packet1; packet1.reason = blr; - packet1.toNetworkString(reset); - peer->sendPacket(reset, PRM_RELIABLE); - delete reset; + packet1.toNetworkString(ns); + peer->sendPacket(ns, PRM_RELIABLE); + delete ns; updatePlayerList(); - NetworkString* server_info = getNetworkString(); + NetworkString* ns2 = getNetworkString(); ServerInfoPacket packet2; //packet2.server_info = ...; - m_game_setup->addServerInfo(server_info); - packet2.toNetworkString(server_info); - peer->sendPacket(server_info, PRM_RELIABLE); - delete server_info; + m_game_setup->addServerInfo(ns2); + packet2.toNetworkString(ns2); + peer->sendPacket(ns2, PRM_RELIABLE); + delete ns2; peer->updateLastActivity(); } // rejectLiveJoin @@ -1144,11 +1121,11 @@ void ServerLobby::liveJoinRequest(Event* event) std::vector > players = getLivePlayers(); - NetworkString* load_world_message; + NetworkString* ns; LoadWorldPacket load_world_packet = getLoadWorldMessage(players, true/*live_join*/); - load_world_packet.toNetworkString(load_world_message); - peer->sendPacket(load_world_message, PRM_RELIABLE); - delete load_world_message; + load_world_packet.toNetworkString(ns); + peer->sendPacket(ns, PRM_RELIABLE); + delete ns; peer->updateLastActivity(); } // liveJoinRequest @@ -1485,11 +1462,12 @@ void ServerLobby::update(int ticks) { // Send a notification to all players who may have start live join // or spectate to go back to lobby - NetworkString* back_to_lobby = getNetworkString(2); - back_to_lobby->setSynchronous(true); - back_to_lobby->addUInt8(LE_BACK_LOBBY).addUInt8(BLR_NONE); - Comm::sendMessageToPeersInServer(back_to_lobby, PRM_RELIABLE); - delete back_to_lobby; + NetworkString* ns = getNetworkString(2); + BackLobbyPacket packet; + packet.reason = BLR_NONE; + packet.toNetworkString(ns); + Comm::sendMessageToPeersInServer(ns, PRM_RELIABLE); + delete ns; RaceEventManager::get()->stop(); RaceEventManager::get()->getProtocol()->requestTerminate(); @@ -1498,11 +1476,12 @@ void ServerLobby::update(int ticks) else if (auto ai = m_ai_peer.lock()) { // Reset AI peer for empty server, which will delete world - NetworkString* back_to_lobby = getNetworkString(2); - back_to_lobby->setSynchronous(true); - back_to_lobby->addUInt8(LE_BACK_LOBBY).addUInt8(BLR_NONE); - ai->sendPacket(back_to_lobby, PRM_RELIABLE); - delete back_to_lobby; + NetworkString* ns = getNetworkString(2); + BackLobbyPacket packet; + packet.reason = BLR_NONE; + packet.toNetworkString(ns); + ai->sendPacket(ns, PRM_RELIABLE); + delete ns; } if (all_players_in_world_disconnected) m_game_setup->cancelOneRace(); @@ -1521,12 +1500,13 @@ void ServerLobby::update(int ticks) m_state.load() == SELECTING && STKHost::get()->getPlayersInGame() == 1) { - NetworkString* back_lobby = getNetworkString(2); - back_lobby->setSynchronous(true); - back_lobby->addUInt8(LE_BACK_LOBBY) - .addUInt8(BLR_ONE_PLAYER_IN_RANKED_MATCH); - Comm::sendMessageToPeers(back_lobby, PRM_RELIABLE); - delete back_lobby; + NetworkString* ns = getNetworkString(2); + BackLobbyPacket packet; + packet.reason = BLR_ONE_PLAYER_IN_RANKED_MATCH; + packet.toNetworkString(ns); + Comm::sendMessageToPeers(ns, PRM_RELIABLE); + delete ns; + resetVotingTime(); // m_game_setup->cancelOneRace(); //m_game_setup->stopGrandPrix(); @@ -1578,21 +1558,28 @@ void ServerLobby::update(int ticks) // result screen and go back to the lobby setTimeoutFromNow(15); m_state = RESULT_DISPLAY; - Comm::sendMessageToPeers(m_result_ns, PRM_RELIABLE); - delete m_result_ns; + + NetworkString* ns = getNetworkString(); + m_result_packet.toNetworkString(ns); + Comm::sendMessageToPeers(ns, PRM_RELIABLE); + delete ns; + Log::info("ServerLobby", "End of game message sent"); break; + case RESULT_DISPLAY: if (checkPeersReady(true/*ignore_ai_peer*/, AFTER_GAME) || isTimeoutExpired()) { // Send a notification to all clients to exit // the race result screen - NetworkString* back_to_lobby = getNetworkString(2); - back_to_lobby->setSynchronous(true); - back_to_lobby->addUInt8(LE_BACK_LOBBY).addUInt8(BLR_NONE); - Comm::sendMessageToPeersInServer(back_to_lobby, PRM_RELIABLE); - delete back_to_lobby; + NetworkString* ns = getNetworkString(2); + BackLobbyPacket packet; + packet.reason = BLR_NONE; + packet.toNetworkString(ns); + Comm::sendMessageToPeersInServer(ns, PRM_RELIABLE); + delete ns; + m_rs_state.store(RS_ASYNC_RESET); } break; @@ -1768,11 +1755,11 @@ void ServerLobby::startSelection(const Event *event) Log::warn("ServerLobby", "Bad team choosing."); if (event) { - NetworkString* bt = getNetworkString(); - bt->setSynchronous(true); - bt->addUInt8(LE_BAD_TEAM); - event->getPeer()->sendPacket(bt, PRM_RELIABLE); - delete bt; + NetworkString* ns = getNetworkString(); + BadTeamPacket packet; + packet.toNetworkString(ns); + event->getPeer()->sendPacket(ns, PRM_RELIABLE); + delete ns; } return; } @@ -1909,16 +1896,15 @@ void ServerLobby::startSelection(const Event *event) if (!getCrownManager()->canRace(peer) || peer->isWaitingForGame()) continue; // they are handled below - NetworkString *ns = getNetworkString(1); // Start selection - must be synchronous since the receiver pushes // a new screen, which must be done from the main thread. - ns->setSynchronous(true); - ns->addUInt8(LE_START_SELECTION) - .addFloat(getSettings()->getVotingTimeout()) - .addUInt8(/*m_game_setup->isGrandPrixStarted() ? 1 : */0) - .addUInt8((!getSettings()->hasNoLapRestrictions() ? 1 : 0)) - .addUInt8(getSettings()->hasTrackVoting() ? 1 : 0); + NetworkString *ns = getNetworkString(1); + StartSelectionPacket packet; + packet.voting_timeout = getSettings()->getVotingTimeout(); + packet.no_kart_selection = getSettings()->isLegacyGPMode() && m_game_setup->isGrandPrixStarted(); + packet.fixed_length = !getSettings()->hasNoLapRestrictions(); + packet.track_voting = getSettings()->hasTrackVoting(); std::set all_k = peer->getClientAssets().first; std::string username = peer->getMainName(); @@ -1933,7 +1919,8 @@ void ServerLobby::startSelection(const Event *event) all_k = {}; } - getAssetManager()->encodePlayerKartsAndCommonMaps(ns, all_k); + packet.assets = getAssetManager()->encodePlayerKartsAndCommonMaps(all_k); + packet.toNetworkString(ns); peer->sendPacket(ns, PRM_RELIABLE); delete ns; @@ -1945,16 +1932,19 @@ void ServerLobby::startSelection(const Event *event) m_state = SELECTING; if (need_to_update || !always_spectate_peers.empty()) { - NetworkString* back_lobby = getNetworkString(2); - back_lobby->setSynchronous(true); - back_lobby->addUInt8(LE_BACK_LOBBY).addUInt8(BLR_SPECTATING_NEXT_GAME); + NetworkString* ns = getNetworkString(2); + BackLobbyPacket packet; + packet.reason = BLR_SPECTATING_NEXT_GAME; + packet.toNetworkString(ns); + STKHost::get()->sendPacketToAllPeersWith( [always_spectate_peers](std::shared_ptr peer) { return always_spectate_peers.find(peer) != always_spectate_peers.end(); - }, back_lobby, PRM_RELIABLE); - delete back_lobby; + }, ns, PRM_RELIABLE); + delete ns; + updatePlayerList(); } @@ -2057,29 +2047,27 @@ void ServerLobby::checkRaceFinished() GameProtocol::lock()->requestTerminate(); // Save race result before delete the world - m_result_ns = getNetworkString(); - m_result_ns->setSynchronous(true); - m_result_ns->addUInt8(LE_RACE_FINISHED); + m_result_packet = RaceFinishedPacket(); std::vector gp_changes; - if (m_game_setup->isGrandPrix()) - { - getGPManager()->updateGPScores(gp_changes, m_result_ns); - } - else if (RaceManager::get()->modeHasLaps()) + + if (RaceManager::get()->modeHasLaps()) { int fastest_lap = static_cast(World::getWorld())->getFastestLapTicks(); - m_result_ns->addUInt32(fastest_lap); - m_result_ns->encodeString(static_cast(World::getWorld()) - ->getFastestLapKartName()); + m_result_packet.fastest_lap = fastest_lap; + m_result_packet.fastest_kart_name = static_cast(World::getWorld()) + ->getFastestLapKartName(); } - uint8_t ranking_changes_indication = 0; - if (getSettings()->isRanked() && RaceManager::get()->modeHasLaps()) - ranking_changes_indication = 1; if (m_game_setup->isGrandPrix()) - ranking_changes_indication = 1; - m_result_ns->addUInt8(ranking_changes_indication); + { + m_result_packet.gp_scores = std::make_shared( + getGPManager()->updateGPScores(gp_changes)); + } + + m_result_packet.point_changes_indication = + (getSettings()->isRanked() && RaceManager::get()->modeHasLaps()) || + m_game_setup->isGrandPrix(); if (getKartElimination()->isEnabled()) { @@ -2098,17 +2086,20 @@ void ServerLobby::checkRaceFinished() if (getSettings()->isRanked()) { - computeNewRankings(m_result_ns); + m_result_packet.point_changes = computeNewRankings(); submitRankingsToAddons(); } else if (m_game_setup->isGrandPrix()) { + PointChangesPacket subpacket; + unsigned player_count = RaceManager::get()->getNumPlayers(); - m_result_ns->addUInt8((uint8_t)player_count); + subpacket.player_count = (uint8_t)player_count; + for (unsigned i = 0; i < player_count; i++) - { - m_result_ns->addFloat(gp_changes[i]); - } + subpacket.changes.push_back(gp_changes[i]); + + m_result_packet.point_changes = subpacket; } m_state.store(WAIT_FOR_RACE_STOPPED); @@ -2121,7 +2112,7 @@ void ServerLobby::checkRaceFinished() /** Compute the new player's rankings used in ranked servers */ -void ServerLobby::computeNewRankings(NetworkString* ns) +PointChangesPacket ServerLobby::computeNewRankings() { // No ranking for battle mode if (!RaceManager::get()->modeHasLaps()) @@ -2157,13 +2148,15 @@ void ServerLobby::computeNewRankings(NetworkString* ns) m_ranking->computeNewRankings(data, RaceManager::get()->isTimeTrialMode()); // Used to display rating change at the end of a race - ns->addUInt8((uint8_t)player_count); + PointChangesPacket packet; + packet.player_count = (uint8_t)player_count; for (unsigned i = 0; i < player_count; i++) { const uint32_t id = RaceManager::get()->getKartInfo(i).getOnlineId(); double change = m_ranking->getDelta(id); - ns->addFloat((float)change); + packet.changes.push_back((float)change); } + return packet; } // computeNewRankings //----------------------------------------------------------------------------- /** Called when a client disconnects. @@ -2187,20 +2180,22 @@ void ServerLobby::clientDisconnected(Event* event) else Log::warn("ServerLobby", "GameInfo is not accessible??"); - NetworkString* msg = getNetworkString(2); + NetworkString* ns = getNetworkString(2); + PlayerDisconnectedPacket packet; + packet.players_size = (uint8_t)players_on_peer.size(); + packet.host_id = event->getPeer()->getHostId(); + const bool waiting_peer_disconnected = event->getPeer()->isWaitingForGame(); - msg->setSynchronous(true); - msg->addUInt8(LE_PLAYER_DISCONNECTED); - msg->addUInt8((uint8_t)players_on_peer.size()) - .addUInt32(event->getPeer()->getHostId()); + for (auto p : players_on_peer) { std::string name = StringUtils::wideToUtf8(p->getName()); - msg->encodeString(name); + packet.names.push_back(name); Log::info("ServerLobby", "%s disconnected", name.c_str()); getCommandManager()->deleteUser(name); } + packet.toNetworkString(ns); unsigned players_number; STKHost::get()->updatePlayers(NULL, NULL, &players_number); @@ -2216,9 +2211,9 @@ void ServerLobby::clientDisconnected(Event* event) if (!p->isWaitingForGame() && waiting_peer_disconnected) return false; return true; - }, msg); + }, ns); updatePlayerList(); - delete msg; + delete ns; #ifdef ENABLE_SQLITE3 getDbConnector()->writeDisconnectInfoTable(event->getPeerSP()); @@ -2229,17 +2224,17 @@ void ServerLobby::clientDisconnected(Event* event) void ServerLobby::kickPlayerWithReason(std::shared_ptr peer, const char* reason) const { - NetworkString *message = getNetworkString(2); + NetworkString *ns = getNetworkString(2); ConnectionRefusedPacket packet; packet.reason = RR_BANNED; packet.message = reason; - packet.toNetworkString(message); - peer->sendPacket(message, PRM_RELIABLE, PEM_UNENCRYPTED); + packet.toNetworkString(ns); + peer->sendPacket(ns, PRM_RELIABLE, PEM_UNENCRYPTED); peer->cleanPlayerProfiles(); peer->reset(); - delete message; + delete ns; } // kickPlayerWithReason //----------------------------------------------------------------------------- @@ -2281,16 +2276,16 @@ bool ServerLobby::handleAssetsAndAddonScores(std::shared_ptr peer, } else { - NetworkString *message = getNetworkString(2); + NetworkString* ns = getNetworkString(2); ConnectionRefusedPacket packet; packet.reason = RR_INCOMPATIBLE_DATA; packet.message = getSettings()->getIncompatibleAdvice(); - packet.toNetworkString(message); - peer->sendPacket(message, PRM_RELIABLE, PEM_UNENCRYPTED); + packet.toNetworkString(ns); + peer->sendPacket(ns, PRM_RELIABLE, PEM_UNENCRYPTED); peer->cleanPlayerProfiles(); peer->reset(); - delete message; + delete ns; } Log::verbose("ServerLobby", "Player has incompatible karts / tracks."); return false; @@ -2332,13 +2327,13 @@ void ServerLobby::connectionRequested(Event* event) (m_state.load() != WAITING_FOR_START_GAME /*|| m_game_setup->isGrandPrixStarted()*/)) { - NetworkString *message = getNetworkString(2); + NetworkString *ns = getNetworkString(2); ConnectionRefusedPacket packet; packet.reason = RR_BUSY; - packet.toNetworkString(message); + packet.toNetworkString(ns); // send only to the peer that made the request and disconnect it now - peer->sendPacket(message, PRM_RELIABLE, PEM_UNENCRYPTED); - delete message; + peer->sendPacket(ns, PRM_RELIABLE, PEM_UNENCRYPTED); + delete ns; peer->reset(); Log::verbose("ServerLobby", "Player refused: selection started"); @@ -2353,12 +2348,12 @@ void ServerLobby::connectionRequested(Event* event) if (version < stk_config->m_min_server_version || version > stk_config->m_max_server_version) { - NetworkString *message = getNetworkString(2); + NetworkString* ns = getNetworkString(2); ConnectionRefusedPacket packet; packet.reason = RR_INCOMPATIBLE_DATA; - packet.toNetworkString(message); - peer->sendPacket(message, PRM_RELIABLE, PEM_UNENCRYPTED); - delete message; + packet.toNetworkString(ns); + peer->sendPacket(ns, PRM_RELIABLE, PEM_UNENCRYPTED); + delete ns; peer->reset(); Log::verbose("ServerLobby", "Player refused: wrong server version"); @@ -2415,12 +2410,12 @@ void ServerLobby::connectionRequested(Event* event) if (total_players + player_count + m_ai_profiles.size() > (unsigned)getSettings()->getServerMaxPlayers()) { - NetworkString *message = getNetworkString(2); + NetworkString* ns = getNetworkString(2); ConnectionRefusedPacket packet; packet.reason = RR_TOO_MANY_PLAYERS; - packet.toNetworkString(message); - peer->sendPacket(message, PRM_RELIABLE, PEM_UNENCRYPTED); - delete message; + packet.toNetworkString(ns); + peer->sendPacket(ns, PRM_RELIABLE, PEM_UNENCRYPTED); + delete ns; peer->reset(); Log::verbose("ServerLobby", "Player refused: too many players"); @@ -2458,12 +2453,12 @@ void ServerLobby::connectionRequested(Event* event) if (failed_validation || failed_strictness || failed_anywhere_ai || failed_unhandled_ai) { - NetworkString* message = getNetworkString(2); + NetworkString* ns = getNetworkString(2); ConnectionRefusedPacket packet; packet.reason = RR_INVALID_PLAYER; - packet.toNetworkString(message); - peer->sendPacket(message, PRM_RELIABLE, PEM_UNENCRYPTED); - delete message; + packet.toNetworkString(ns); + peer->sendPacket(ns, PRM_RELIABLE, PEM_UNENCRYPTED); + delete ns; peer->reset(); Log::verbose("ServerLobby", "Player refused: invalid player"); @@ -2505,13 +2500,13 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr peer, std::string username = StringUtils::wideToUtf8(online_name); if (getSettings()->isTempBanned(username)) { - NetworkString* message = getNetworkString(2); + NetworkString* ns = getNetworkString(2); ConnectionRefusedPacket packet; packet.reason = RR_BANNED; packet.message = "Please behave well next time."; - packet.toNetworkString(message); - peer->sendPacket(message, PRM_RELIABLE, PEM_UNENCRYPTED); - delete message; + packet.toNetworkString(ns); + peer->sendPacket(ns, PRM_RELIABLE, PEM_UNENCRYPTED); + delete ns; peer->reset(); Log::verbose("ServerLobby", "Player refused: invalid player"); @@ -2522,12 +2517,12 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr peer, } if (password != server_pw) { - NetworkString *message = getNetworkString(2); + NetworkString* ns = getNetworkString(2); ConnectionRefusedPacket packet; packet.reason = RR_INCORRECT_PASSWORD; - packet.toNetworkString(message); - peer->sendPacket(message, PRM_RELIABLE, PEM_UNENCRYPTED); - delete message; + packet.toNetworkString(ns); + peer->sendPacket(ns, PRM_RELIABLE, PEM_UNENCRYPTED); + delete ns; peer->reset(); Log::verbose("ServerLobby", "Player refused: incorrect password"); @@ -2545,12 +2540,12 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr peer, if (total_players + player_count > (unsigned)getSettings()->getServerMaxPlayers()) { - NetworkString *message = getNetworkString(2); + NetworkString* ns = getNetworkString(2); ConnectionRefusedPacket packet; packet.reason = RR_TOO_MANY_PLAYERS; - packet.toNetworkString(message); - peer->sendPacket(message, PRM_RELIABLE, PEM_UNENCRYPTED); - delete message; + packet.toNetworkString(ns); + peer->sendPacket(ns, PRM_RELIABLE, PEM_UNENCRYPTED); + delete ns; peer->reset(); Log::verbose("ServerLobby", "Player refused: too many players"); @@ -2563,12 +2558,12 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr peer, all_online_ids.find(online_id) != all_online_ids.end(); if (getSettings()->isRanked() && duplicated_ranked_player) { - NetworkString* message = getNetworkString(2); + NetworkString* ns = getNetworkString(2); ConnectionRefusedPacket packet; packet.reason = RR_INVALID_PLAYER; - packet.toNetworkString(message); - peer->sendPacket(message, PRM_RELIABLE, PEM_UNENCRYPTED); - delete message; + packet.toNetworkString(ns); + peer->sendPacket(ns, PRM_RELIABLE, PEM_UNENCRYPTED); + delete ns; peer->reset(); Log::verbose("ServerLobby", "Player refused: invalid player"); @@ -2660,17 +2655,17 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr peer, peer->setValidated(true); // send a message to the one that asked to connect - NetworkString* server_info = getNetworkString(); - getServerInfoPacket().toNetworkString(server_info); - peer->sendPacket(server_info); - delete server_info; + NetworkString* si = getNetworkString(); + getServerInfoPacket().toNetworkString(si); + peer->sendPacket(si); + delete si; peer->updateLastActivity(); const bool game_started = m_state.load() != WAITING_FOR_START_GAME; auto& stk_config = STKConfig::get(); - NetworkString* message_ack = getNetworkString(4); + NetworkString* ns = getNetworkString(4); ConnectionAcceptedPacket packet; // connection success -- return the host id of peer @@ -2686,7 +2681,7 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr peer, packet.chat_allowed = getChatManager()->getChat(); packet.reports_allowed = playerReportsTableExists(); - packet.toNetworkString(message_ack); + packet.toNetworkString(ns); peer->setSpectator(false); @@ -2722,8 +2717,8 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr peer, { peer->setWaitingForGame(true); updatePlayerList(); - peer->sendPacket(message_ack); - delete message_ack; + peer->sendPacket(ns); + delete ns; } else { @@ -2742,8 +2737,8 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr peer, } } updatePlayerList(); - peer->sendPacket(message_ack); - delete message_ack; + peer->sendPacket(ns); + delete ns; if (getSettings()->isRanked()) { @@ -2928,8 +2923,8 @@ void ServerLobby::updatePlayerList(bool update_when_reset_server) list_packet.all_profiles.push_back(packet); } - NetworkString* pl = getNetworkString(); - list_packet.toNetworkString(pl); + NetworkString* ns = getNetworkString(); + list_packet.toNetworkString(ns); // Don't send this message to in-game players STKHost::get()->sendPacketToAllPeersWith([game_started] @@ -2940,8 +2935,8 @@ void ServerLobby::updatePlayerList(bool update_when_reset_server) if (!p->isWaitingForGame() && game_started) return false; return true; - }, pl); - delete pl; + }, ns); + delete ns; } // updatePlayerList //----------------------------------------------------------------------------- @@ -3082,12 +3077,13 @@ void ServerLobby::handlePlayerVote(Event* event) vote.m_player_name = event->getPeer()->getMainProfile()->getDecoratedName(m_name_decorator); // Now inform all clients about the vote - NetworkString other = NetworkString(PROTOCOL_LOBBY_ROOM); + NetworkString* ns = getNetworkString(); VotePacket packet; packet.host_id = event->getPeer()->getHostId(); packet.vote = vote.encode(); - packet.toNetworkString(&other); - Comm::sendMessageToPeers(&other); + packet.toNetworkString(ns); + Comm::sendMessageToPeers(ns); + delete ns; } // handlePlayerVote @@ -3422,10 +3418,10 @@ void ServerLobby::resetServer() resetPeersReady(); updatePlayerList(true/*update_when_reset_server*/); - NetworkString* server_info = getNetworkString(); - getServerInfoPacket().toNetworkString(server_info); - Comm::sendMessageToPeersInServer(server_info); - delete server_info; + NetworkString* si = getNetworkString(); + getServerInfoPacket().toNetworkString(si); + Comm::sendMessageToPeersInServer(si); + delete si; for (auto p : m_peers_ready) { @@ -3683,15 +3679,15 @@ void ServerLobby::handleServerConfiguration(std::shared_ptr peer, if (getAssetManager()->checkIfNoCommonMaps(assets)) { - NetworkString *message = getNetworkString(2); + NetworkString *ns = getNetworkString(2); ConnectionRefusedPacket packet; packet.reason = RR_INCOMPATIBLE_DATA; - packet.toNetworkString(message); - peer->sendPacket(message, PRM_RELIABLE); + packet.toNetworkString(ns); + peer->sendPacket(ns, PRM_RELIABLE); + delete ns; peer->cleanPlayerProfiles(); peer->reset(); - delete message; Log::verbose("ServerLobby", "Player has incompatible tracks for new game mode."); } @@ -3721,10 +3717,10 @@ void ServerLobby::handleServerConfiguration(std::shared_ptr peer, } } - NetworkString* server_info = getNetworkString(); - getServerInfoPacket().toNetworkString(server_info); - Comm::sendMessageToPeers(server_info); - delete server_info; + NetworkString* si = getNetworkString(); + getServerInfoPacket().toNetworkString(si); + Comm::sendMessageToPeers(si); + delete si; updatePlayerList(); @@ -4065,12 +4061,12 @@ void ServerLobby::clientInGameWantsToBackLobby(Event* event) else exitGameState(); - NetworkString* back_to_lobby = getNetworkString(2); + NetworkString* ns = getNetworkString(2); BackLobbyPacket packet; packet.reason = BLR_SERVER_OWNER_QUIT_THE_GAME; - packet.toNetworkString(back_to_lobby); - Comm::sendMessageToPeersInServer(back_to_lobby, PRM_RELIABLE); - delete back_to_lobby; + packet.toNetworkString(ns); + Comm::sendMessageToPeersInServer(ns, PRM_RELIABLE); + delete ns; m_rs_state.store(RS_ASYNC_RESET); return; @@ -4105,19 +4101,19 @@ void ServerLobby::clientInGameWantsToBackLobby(Event* event) peer->setWaitingForGame(true); peer->setSpectator(false); - NetworkString* reset = getNetworkString(2); + NetworkString* ns = getNetworkString(2); BackLobbyPacket packet; packet.reason = BLR_NONE; - packet.toNetworkString(reset); - peer->sendPacket(reset, PRM_RELIABLE); - delete reset; + packet.toNetworkString(ns); + peer->sendPacket(ns, PRM_RELIABLE); + delete ns; updatePlayerList(); - NetworkString* server_info = getNetworkString(); - getServerInfoPacket().toNetworkString(server_info); - peer->sendPacket(server_info, PRM_RELIABLE); - delete server_info; + NetworkString* si = getNetworkString(); + getServerInfoPacket().toNetworkString(si); + peer->sendPacket(si, PRM_RELIABLE); + delete si; peer->updateLastActivity(); } // clientInGameWantsToBackLobby @@ -4140,12 +4136,12 @@ void ServerLobby::clientSelectingAssetsWantsToBackLobby(Event* event) if (m_process_type == PT_CHILD && event->getPeer()->getHostId() == m_client_server_host_id.load()) { - NetworkString* back_to_lobby = getNetworkString(2); + NetworkString* ns = getNetworkString(2); BackLobbyPacket packet; packet.reason = BLR_SERVER_OWNER_QUIT_THE_GAME; - packet.toNetworkString(back_to_lobby); - Comm::sendMessageToPeersInServer(back_to_lobby, PRM_RELIABLE); - delete back_to_lobby; + packet.toNetworkString(ns); + Comm::sendMessageToPeersInServer(ns, PRM_RELIABLE); + delete ns; resetVotingTime(); resetServer(); @@ -4157,19 +4153,19 @@ void ServerLobby::clientSelectingAssetsWantsToBackLobby(Event* event) peer->setWaitingForGame(true); peer->setSpectator(false); - NetworkString* reset = getNetworkString(2); + NetworkString* ns = getNetworkString(2); BackLobbyPacket packet; packet.reason = BLR_NONE; - packet.toNetworkString(reset); - peer->sendPacket(reset, PRM_RELIABLE); - delete reset; + packet.toNetworkString(ns); + peer->sendPacket(ns, PRM_RELIABLE); + delete ns; updatePlayerList(); - NetworkString* server_info = getNetworkString(); - getServerInfoPacket().toNetworkString(server_info); - peer->sendPacket(server_info, PRM_RELIABLE); - delete server_info; + NetworkString* si = getNetworkString(); + getServerInfoPacket().toNetworkString(si); + peer->sendPacket(si, PRM_RELIABLE); + delete si; peer->updateLastActivity(); } // clientSelectingAssetsWantsToBackLobby @@ -4264,7 +4260,7 @@ void ServerLobby::writeOwnReport(std::shared_ptr reporter, std::shared_ reporting, reporting_npp, info_w); if (written) { - NetworkString* success = getNetworkString(); + NetworkString* ns = getNetworkString(); ReportSuccessPacket packet; packet.success = 1; if (reporter == reporting) @@ -4272,9 +4268,9 @@ void ServerLobby::writeOwnReport(std::shared_ptr reporter, std::shared_ else packet.reported_name = reporting_npp->getName(); - packet.toNetworkString(success); - reporter->sendPacket(success, PRM_RELIABLE); - delete success; + packet.toNetworkString(ns); + reporter->sendPacket(ns, PRM_RELIABLE); + delete ns; } #endif } // writeOwnReport @@ -4287,23 +4283,23 @@ void ServerLobby::sendStringToPeer(std::shared_ptr peer, const std::str sendStringToAllPeers(s); return; } - NetworkString* chat = getNetworkString(); - chat->addUInt8(LE_CHAT); - chat->setSynchronous(true); - chat->encodeString16(StringUtils::utf8ToWide(s)); - peer->sendPacket(chat, PRM_RELIABLE); - delete chat; + NetworkString* ns = getNetworkString(); + ChatPacket packet; + packet.message = StringUtils::utf8ToWide(s); + packet.toNetworkString(ns); + peer->sendPacket(ns, PRM_RELIABLE); + delete ns; } // sendStringToPeer //----------------------------------------------------------------------------- void ServerLobby::sendStringToAllPeers(const std::string& s) { - NetworkString* chat = getNetworkString(); - chat->addUInt8(LE_CHAT); - chat->setSynchronous(true); - chat->encodeString16(StringUtils::utf8ToWide(s)); - sendMessageToPeers(chat, PRM_RELIABLE); - delete chat; + NetworkString* ns = getNetworkString(); + ChatPacket packet; + packet.message = StringUtils::utf8ToWide(s); + packet.toNetworkString(ns); + sendMessageToPeers(ns, PRM_RELIABLE); + delete ns; } // sendStringToAllPeers //----------------------------------------------------------------------------- @@ -4514,10 +4510,10 @@ ServerInfoPacket ServerLobby::getServerInfoPacket() const void ServerLobby::sendServerInfoToEveryone() const { - NetworkString* server_info = getNetworkString(); - getServerInfoPacket().toNetworkString(server_info); - Comm::sendMessageToPeers(server_info); - delete server_info; + NetworkString* si = getNetworkString(); + getServerInfoPacket().toNetworkString(si); + Comm::sendMessageToPeers(si); + delete si; } // sendServerInfoToEveryone //----------------------------------------------------------------------------- diff --git a/src/network/protocols/server_lobby.hpp b/src/network/protocols/server_lobby.hpp index 2a10d9fa120..9f010b32cda 100644 --- a/src/network/protocols/server_lobby.hpp +++ b/src/network/protocols/server_lobby.hpp @@ -149,7 +149,7 @@ class ServerLobby : public LobbyProtocol, public LobbyContextUser std::map m_pending_peer_connection; /* Saved the last game result */ - NetworkString* m_result_ns; + RaceFinishedPacket m_result_packet; /* Used to make sure clients are having same item list at start */ BareNetworkString* m_items_complete_state; @@ -251,7 +251,7 @@ class ServerLobby : public LobbyProtocol, public LobbyContextUser bool handleAllVotes(PeerVote* winner); void getRankingForPlayer(std::shared_ptr p); void submitRankingsToAddons(); - void computeNewRankings(NetworkString* ns); + PointChangesPacket computeNewRankings(); void checkRaceFinished(); void configPeersStartTime(); void resetServer(); diff --git a/src/utils/communication.cpp b/src/utils/communication.cpp index e3d88046cb8..d807705f221 100644 --- a/src/utils/communication.cpp +++ b/src/utils/communication.cpp @@ -74,23 +74,23 @@ void sendStringToPeer(std::shared_ptr peer, const std::string& s) sendStringToAllPeers(s); return; } - NetworkString* chat = new NetworkString(ProtocolType::PROTOCOL_LOBBY_ROOM); + NetworkString* ns = new NetworkString(ProtocolType::PROTOCOL_LOBBY_ROOM); ChatPacket packet; packet.message = StringUtils::utf8ToWide(s); - packet.toNetworkString(chat); - peer->sendPacket(chat, PRM_RELIABLE); - delete chat; + packet.toNetworkString(ns); + peer->sendPacket(ns, PRM_RELIABLE); + delete ns; } // sendStringToPeer //----------------------------------------------------------------------------- void sendStringToAllPeers(const std::string& s) { - NetworkString* chat = new NetworkString(ProtocolType::PROTOCOL_LOBBY_ROOM); + NetworkString* ns = new NetworkString(ProtocolType::PROTOCOL_LOBBY_ROOM); ChatPacket packet; packet.message = StringUtils::utf8ToWide(s); - packet.toNetworkString(chat); - Comm::sendMessageToPeers(chat, PRM_RELIABLE); - delete chat; + packet.toNetworkString(ns); + sendMessageToPeers(ns, PRM_RELIABLE); + delete ns; } // sendStringToAllPeers //----------------------------------------------------------------------------- } // namespace Comm diff --git a/src/utils/lobby_asset_manager.cpp b/src/utils/lobby_asset_manager.cpp index 5bf11455736..f31492bc795 100644 --- a/src/utils/lobby_asset_manager.cpp +++ b/src/utils/lobby_asset_manager.cpp @@ -293,16 +293,22 @@ std::string LobbyAssetManager::getRandomAvailableMap() } // getRandomAvailableMap //----------------------------------------------------------------------------- -void LobbyAssetManager::encodePlayerKartsAndCommonMaps(NetworkString* ns, +AssetsPacket2 LobbyAssetManager::encodePlayerKartsAndCommonMaps( const std::set& all_k) { const auto& all_t = m_available_kts.second; - ns->addUInt16((uint16_t)all_k.size()).addUInt16((uint16_t)all_t.size()); + AssetsPacket2 packet; + packet.karts_number = (uint16_t)all_k.size(); + packet.maps_number = (uint16_t)all_t.size(); + for (const std::string& kart : all_k) - ns->encodeString(kart); + packet.karts.push_back(kart); + for (const std::string& track : all_t) - ns->encodeString(track); + packet.maps.push_back(track); + + return packet; } // encodePlayerKartsAndCommonMaps //----------------------------------------------------------------------------- diff --git a/src/utils/lobby_asset_manager.hpp b/src/utils/lobby_asset_manager.hpp index 6844ac4a1b6..a4bd9c42456 100644 --- a/src/utils/lobby_asset_manager.hpp +++ b/src/utils/lobby_asset_manager.hpp @@ -50,8 +50,8 @@ class LobbyAssetManager: public LobbyContextComponent bool tryApplyingMapFilters(); std::string getRandomAvailableMap(); - void encodePlayerKartsAndCommonMaps( - NetworkString* ns, const std::set& all_k); + AssetsPacket2 encodePlayerKartsAndCommonMaps( + const std::set& all_k); bool handleAssetsForPeer(std::shared_ptr peer, const std::set& client_karts, diff --git a/src/utils/lobby_gp_manager.cpp b/src/utils/lobby_gp_manager.cpp index 874122aec36..7d4644b1a82 100644 --- a/src/utils/lobby_gp_manager.cpp +++ b/src/utils/lobby_gp_manager.cpp @@ -163,7 +163,7 @@ void LobbyGPManager::shuffleGPScoresWithPermutation(const std::map& pe } // shuffleGPScoresWithPermutation //----------------------------------------------------------------------------- -void LobbyGPManager::updateGPScores(std::vector& gp_changes, NetworkString* ns) +GPScoresPacket LobbyGPManager::updateGPScores(std::vector& gp_changes) { // fastest lap int fastest_lap = @@ -234,22 +234,26 @@ void LobbyGPManager::updateGPScores(std::vector& gp_changes, NetworkStrin overall_times.push_back(overall_time); } - ns->addUInt32(fastest_lap); - ns->encodeString(fastest_kart_wide); - - ns->addUInt8((uint8_t)game_setup->getTotalGrandPrixTracks()) - .addUInt8((uint8_t)game_setup->getAllTracks().size()); + GPScoresPacket packet; + packet.fastest_lap = fastest_lap; + packet.fastest_kart = fastest_kart_wide; + packet.total_gp_tracks = (uint8_t)game_setup->getTotalGrandPrixTracks(); + packet.all_tracks_size = (uint8_t)game_setup->getAllTracks().size(); for (const std::string& gp_track : game_setup->getAllTracks()) - ns->encodeString(gp_track); + packet.all_tracks.push_back(gp_track); - ns->addUInt8((uint8_t)RaceManager::get()->getNumPlayers()); + packet.num_players = (uint8_t)RaceManager::get()->getNumPlayers(); for (unsigned i = 0; i < RaceManager::get()->getNumPlayers(); i++) { - ns->addUInt32(last_scores[i]) - .addUInt32(cur_scores[i]) - .addFloat(overall_times[i]); + GPIndividualScorePacket subpacket; + subpacket.last_score = last_scores[i]; + subpacket.cur_score = cur_scores[i]; + subpacket.overall_time = overall_times[i]; + packet.scores.push_back(subpacket); } + + return packet; } // updateGPScores //----------------------------------------------------------------------------- diff --git a/src/utils/lobby_gp_manager.hpp b/src/utils/lobby_gp_manager.hpp index aa8f0b1ec99..9ebf28ce736 100644 --- a/src/utils/lobby_gp_manager.hpp +++ b/src/utils/lobby_gp_manager.hpp @@ -61,7 +61,7 @@ class LobbyGPManager: public LobbyContextComponent void shuffleGPScoresWithPermutation(const std::map& permutation); - void updateGPScores(std::vector& gp_changes, NetworkString* ns); + GPScoresPacket updateGPScores(std::vector& gp_changes); bool trySettingGPScoring(const std::string& input); From e70f0761771dc1ed88e26c607cabd710e4b6bcce Mon Sep 17 00:00:00 2001 From: kimden <23140380+kimden@users.noreply.github.com> Date: Sat, 5 Apr 2025 14:13:01 +0400 Subject: [PATCH 07/34] Seemingle finished SL packets, some other reworks --- src/modes/capture_the_flag.cpp | 4 +- src/modes/capture_the_flag.hpp | 4 +- src/modes/free_for_all.cpp | 4 +- src/modes/free_for_all.hpp | 4 +- src/modes/linear_world.cpp | 4 +- src/modes/linear_world.hpp | 4 +- src/modes/soccer_world.cpp | 12 ++-- src/modes/soccer_world.hpp | 4 +- src/modes/world.hpp | 4 +- src/network/game_setup.cpp | 52 +++++++++++------ src/network/game_setup.hpp | 2 +- src/network/packet_types.hpp | 21 ++++++- src/network/packet_types_base.hpp | 31 +++++++--- src/network/protocols/server_lobby.cpp | 81 ++++++++++++-------------- src/network/protocols/server_lobby.hpp | 2 - src/network/stk_host.cpp | 12 ++-- src/network/stk_peer.cpp | 15 ++++- src/network/stk_peer.hpp | 5 +- src/tracks/check_line.cpp | 4 +- src/tracks/check_line.hpp | 4 +- src/tracks/check_structure.cpp | 4 +- src/tracks/check_structure.hpp | 4 +- 22 files changed, 165 insertions(+), 116 deletions(-) diff --git a/src/modes/capture_the_flag.cpp b/src/modes/capture_the_flag.cpp index 1f1187e7143..2b0d8afe6a3 100644 --- a/src/modes/capture_the_flag.cpp +++ b/src/modes/capture_the_flag.cpp @@ -553,7 +553,7 @@ const std::string& CaptureTheFlag::getIdent() const } // getIdent // ---------------------------------------------------------------------------- -std::shared_ptr CaptureTheFlag::saveCompleteState(std::shared_ptr peer) +std::shared_ptr CaptureTheFlag::saveCompleteState(std::shared_ptr peer) { auto packet = std::make_shared(); @@ -565,7 +565,7 @@ std::shared_ptr CaptureTheFlag::saveCompleteState(std::shared_ptr& packet) +void CaptureTheFlag::restoreCompleteState(const std::shared_ptr& packet) { std::shared_ptr ctf_packet = std::dynamic_pointer_cast(packet); diff --git a/src/modes/capture_the_flag.hpp b/src/modes/capture_the_flag.hpp index 33b014a8d14..64c5148f4e4 100644 --- a/src/modes/capture_the_flag.hpp +++ b/src/modes/capture_the_flag.hpp @@ -157,10 +157,10 @@ class CaptureTheFlag : public FreeForAll return progress; } // ------------------------------------------------------------------------ - virtual std::shared_ptr saveCompleteState( + virtual std::shared_ptr saveCompleteState( std::shared_ptr peer) OVERRIDE; // ------------------------------------------------------------------------ - virtual void restoreCompleteState(const std::shared_ptr& b) OVERRIDE; + virtual void restoreCompleteState(const std::shared_ptr& b) OVERRIDE; }; // CaptureTheFlag #endif diff --git a/src/modes/free_for_all.cpp b/src/modes/free_for_all.cpp index 9b9b93a1b4e..b814bfc9730 100644 --- a/src/modes/free_for_all.cpp +++ b/src/modes/free_for_all.cpp @@ -295,7 +295,7 @@ bool FreeForAll::getKartFFAResult(int kart_id) const } // getKartFFAResult // ---------------------------------------------------------------------------- -std::shared_ptr FreeForAll::saveCompleteState(std::shared_ptr peer) +std::shared_ptr FreeForAll::saveCompleteState(std::shared_ptr peer) { auto packet = std::make_shared(); for (unsigned i = 0; i < m_scores.size(); i++) @@ -303,7 +303,7 @@ std::shared_ptr FreeForAll::saveCompleteState(std::shared_ptr p } // saveCompleteState // ---------------------------------------------------------------------------- -void FreeForAll::restoreCompleteState(const std::shared_ptr& packet) +void FreeForAll::restoreCompleteState(const std::shared_ptr& packet) { std::shared_ptr ffa_packet = std::dynamic_pointer_cast(packet); diff --git a/src/modes/free_for_all.hpp b/src/modes/free_for_all.hpp index 28f087349cc..1cc2cb88fda 100644 --- a/src/modes/free_for_all.hpp +++ b/src/modes/free_for_all.hpp @@ -85,9 +85,9 @@ class FreeForAll : public WorldWithRank m_scores.at(kart_id) = param; } // ------------------------------------------------------------------------ - virtual std::shared_ptr saveCompleteState(std::shared_ptr peer) OVERRIDE; + virtual std::shared_ptr saveCompleteState(std::shared_ptr peer) OVERRIDE; // ------------------------------------------------------------------------ - virtual void restoreCompleteState(const std::shared_ptr& b) OVERRIDE; + virtual void restoreCompleteState(const std::shared_ptr& b) OVERRIDE; // ------------------------------------------------------------------------ void notifyAboutScoreIfNonzero(int id); }; // FreeForAll diff --git a/src/modes/linear_world.cpp b/src/modes/linear_world.cpp index b061c4b745f..cae06ac8fb4 100644 --- a/src/modes/linear_world.cpp +++ b/src/modes/linear_world.cpp @@ -1239,7 +1239,7 @@ void LinearWorld::KartInfo::restoreCompleteState(const KartInfoPacket& packet) } // restoreCompleteState // ---------------------------------------------------------------------------- -std::shared_ptr LinearWorld::saveCompleteState(std::shared_ptr peer) +std::shared_ptr LinearWorld::saveCompleteState(std::shared_ptr peer) { auto packet = std::make_shared(); @@ -1269,7 +1269,7 @@ std::shared_ptr LinearWorld::saveCompleteState(std::shared_ptr } // saveCompleteState // ---------------------------------------------------------------------------- -void LinearWorld::restoreCompleteState(const std::shared_ptr& packet) +void LinearWorld::restoreCompleteState(const std::shared_ptr& packet) { std::shared_ptr linear_packet = std::dynamic_pointer_cast(packet); diff --git a/src/modes/linear_world.hpp b/src/modes/linear_world.hpp index a68eba2d52a..f4cfa4ca634 100644 --- a/src/modes/linear_world.hpp +++ b/src/modes/linear_world.hpp @@ -276,9 +276,9 @@ class LinearWorld : public WorldWithRank virtual std::pair getGameStartedProgress() const OVERRIDE; // ------------------------------------------------------------------------ - virtual std::shared_ptr saveCompleteState(std::shared_ptr peer) OVERRIDE; + virtual std::shared_ptr saveCompleteState(std::shared_ptr peer) OVERRIDE; // ------------------------------------------------------------------------ - virtual void restoreCompleteState(const std::shared_ptr& b) OVERRIDE; + virtual void restoreCompleteState(const std::shared_ptr& b) OVERRIDE; // ------------------------------------------------------------------------ void updateCheckLinesServer(int check_id, int kart_id); // ------------------------------------------------------------------------ diff --git a/src/modes/soccer_world.cpp b/src/modes/soccer_world.cpp index c5da60e2c34..d3fa9a443b5 100644 --- a/src/modes/soccer_world.cpp +++ b/src/modes/soccer_world.cpp @@ -707,11 +707,11 @@ void SoccerWorld::onCheckGoalTriggered(bool first_goal) if (peer->getClientCapabilities().find("soccer_fixes") != peer->getClientCapabilities().end()) { - peer->sendPacket(&p_1_1, PRM_RELIABLE); + peer->sendNetstring(&p_1_1, PRM_RELIABLE); } else { - peer->sendPacket(&p, PRM_RELIABLE); + peer->sendNetstring(&p, PRM_RELIABLE); } } } @@ -1214,7 +1214,7 @@ void SoccerWorld::enterRaceOverState() } // enterRaceOverState // ---------------------------------------------------------------------------- -std::shared_ptr SoccerWorld::saveCompleteState(std::shared_ptr peer) +std::shared_ptr SoccerWorld::saveCompleteState(std::shared_ptr peer) { auto packet = std::make_shared(); @@ -1238,7 +1238,7 @@ std::shared_ptr SoccerWorld::saveCompleteState(std::shared_ptr } // saveCompleteState // ---------------------------------------------------------------------------- -void SoccerWorld::restoreCompleteState(const std::shared_ptr& packet) +void SoccerWorld::restoreCompleteState(const std::shared_ptr& packet) { std::shared_ptr soccer_packet = std::dynamic_pointer_cast(packet); @@ -1375,7 +1375,7 @@ void SoccerWorld::tellCountToEveryoneInGame() const chat->encodeString16(StringUtils::utf8ToWide(real_count)); for (auto& peer : peers) if (peer->isValidated() && !peer->isWaitingForGame()) - peer->sendPacket(chat, PRM_RELIABLE); + peer->sendNetstring(chat, PRM_RELIABLE); delete chat; } // tellCountToEveryoneInGame @@ -1393,7 +1393,7 @@ void SoccerWorld::tellCount(std::shared_ptr peer) const std::string real_count = std::to_string(real_red) + " : " + std::to_string(real_blue); chat->encodeString16(StringUtils::utf8ToWide(real_count)); - peer->sendPacket(chat, PRM_RELIABLE); + peer->sendNetstring(chat, PRM_RELIABLE); delete chat; } // tellCount // ---------------------------------------------------------------------------- diff --git a/src/modes/soccer_world.hpp b/src/modes/soccer_world.hpp index 1499301bf62..7aaf8651aa0 100644 --- a/src/modes/soccer_world.hpp +++ b/src/modes/soccer_world.hpp @@ -266,9 +266,9 @@ class SoccerWorld : public WorldWithRank return progress; } // ------------------------------------------------------------------------ - virtual std::shared_ptr saveCompleteState(std::shared_ptr peer) OVERRIDE; + virtual std::shared_ptr saveCompleteState(std::shared_ptr peer) OVERRIDE; // ------------------------------------------------------------------------ - virtual void restoreCompleteState(const std::shared_ptr& b) OVERRIDE; + virtual void restoreCompleteState(const std::shared_ptr& b) OVERRIDE; // ------------------------------------------------------------------------ virtual bool isGoalPhase() const OVERRIDE { diff --git a/src/modes/world.hpp b/src/modes/world.hpp index f6d15cf37f7..f2f0c206c1b 100644 --- a/src/modes/world.hpp +++ b/src/modes/world.hpp @@ -376,9 +376,9 @@ class World : public WorldStatus m_eliminated_karts--; } // ------------------------------------------------------------------------ - virtual std::shared_ptr saveCompleteState(std::shared_ptr peer) { return {}; } + virtual std::shared_ptr saveCompleteState(std::shared_ptr peer) { return {}; } // ------------------------------------------------------------------------ - virtual void restoreCompleteState(const std::shared_ptr& buffer) {} + virtual void restoreCompleteState(const std::shared_ptr& buffer) {} // ------------------------------------------------------------------------ /** The code that draws the timer should call this first to know * whether the game mode wants a timer drawn. */ diff --git a/src/network/game_setup.cpp b/src/network/game_setup.cpp index 326b0da6e69..41be5e30728 100644 --- a/src/network/game_setup.cpp +++ b/src/network/game_setup.cpp @@ -102,51 +102,67 @@ void GameSetup::loadWorld() } // loadWorld //----------------------------------------------------------------------------- -void GameSetup::addServerInfo(NetworkString* ns) +ServerInfoPacket GameSetup::addServerInfo() { #ifdef DEBUG assert(NetworkConfig::get()->isServer()); #endif - ns->encodeString(m_server_name_utf8); + ServerInfoPacket packet; + + packet.server_name = m_server_name_utf8; + auto sl = LobbyProtocol::get(); assert(sl); - ns->addUInt8((uint8_t)sl->getDifficulty()) - .addUInt8((uint8_t)ServerConfig::m_server_max_players) - // Reserve for extra spectators - .addUInt8(0) - .addUInt8((uint8_t)sl->getGameMode()); + + packet.difficulty = (uint8_t)sl->getDifficulty(); + + // probably getSettings()-> + packet.max_players = (uint8_t)ServerConfig::m_server_max_players; + + packet.extra_spectators_zero = 0; + packet.game_mode = (uint8_t)sl->getGameMode(); + if (hasExtraServerInfo()) { if (isGrandPrix()) { + // has_extra_server_info is used for current track index uint8_t cur_track = (uint8_t)m_tracks.size(); if (!isGrandPrixStarted()) cur_track = 0; - ns->addUInt8((uint8_t)2).addUInt8(cur_track) - .addUInt8(getExtraServerInfo()); + + packet.has_extra_server_info = cur_track; + packet.extra_server_info = std::make_shared(m_extra_server_info); } else { // Soccer mode - ns->addUInt8((uint8_t)1).addUInt8(getExtraServerInfo()); + packet.has_extra_server_info = 1; + packet.extra_server_info = std::make_shared(m_extra_server_info); } } else { - // No extra server info - ns->addUInt8((uint8_t)0); + packet.has_extra_server_info = 0; + packet.extra_server_info = {}; } + if (ServerConfig::m_owner_less) { - ns->addUInt8(ServerConfig::m_min_start_game_players) - .addFloat(std::max(0.0f, getSettings()->getStartGameCounter())); + // probably getSettings()-> also + packet.min_start_game_players = ServerConfig::m_min_start_game_players; + packet.start_game_counter = std::max(0.0f, getSettings()->getStartGameCounter()); } else - ns->addUInt8(0).addFloat(0.0f); + { + packet.min_start_game_players = 0; + packet.start_game_counter = 0.0f; + } - ns->encodeString16(m_message_of_today); - ns->addUInt8((uint8_t)getSettings()->isServerConfigurable()); - ns->addUInt8(getSettings()->isLivePlayers() ? 1 : 0); + packet.motd = m_message_of_today; + packet.is_configurable = getSettings()->isServerConfigurable(); + packet.has_live_players = getSettings()->isLivePlayers(); + return packet; } // addServerInfo //----------------------------------------------------------------------------- diff --git a/src/network/game_setup.hpp b/src/network/game_setup.hpp index 20c4c35c3f7..d380dcd21af 100644 --- a/src/network/game_setup.hpp +++ b/src/network/game_setup.hpp @@ -94,7 +94,7 @@ class GameSetup: public LobbyContextUser m_extra_server_info = tracks_no; } // ------------------------------------------------------------------------ - void addServerInfo(NetworkString* ns); + ServerInfoPacket addServerInfo(); // ------------------------------------------------------------------------ void loadWorld(); // ------------------------------------------------------------------------ diff --git a/src/network/packet_types.hpp b/src/network/packet_types.hpp index 196c63b6d3b..9fd0f6c075b 100644 --- a/src/network/packet_types.hpp +++ b/src/network/packet_types.hpp @@ -96,6 +96,8 @@ struct Packet { // Needed to dynamic_cast virtual ~Packet() {} + virtual void toNetworkString(NetworkString* ns) const {} + virtual void fromNetworkString(NetworkString* ns) {} }; struct Checkable @@ -118,8 +120,14 @@ struct Checkable #define DEFINE_CLASS(Name) \ struct Name: public Checkable, public Packet { \ public: \ - void toNetworkString(NetworkString* ns) const; \ - void fromNetworkString(NetworkString* ns); + virtual void toNetworkString(NetworkString* ns) const OVERRIDE; \ + virtual void fromNetworkString(NetworkString* ns) OVERRIDE; + +#define DEFINE_DERIVED_CLASS(Name, Parent) \ +struct Name: public Checkable, public Parent { \ + public: \ + virtual void toNetworkString(NetworkString* ns) const OVERRIDE; \ + virtual void fromNetworkString(NetworkString* ns) OVERRIDE; #define SYNCHRONOUS(Value) bool isSynchronous() { return Value; } #define AUX_VAR(Type, Var) Type Var; @@ -134,6 +142,7 @@ struct Name: public Checkable, public Packet { \ #include "network/packet_types_base.hpp" #undef DEFINE_CLASS +#undef DEFINE_DERIVED_CLASS #undef SYNCHRONOUS #undef AUX_VAR #undef DEFINE_FIELD @@ -149,7 +158,9 @@ struct Name: public Checkable, public Packet { \ #define DEFINE_CLASS(Name) \ inline void Name::toNetworkString(NetworkString* ns) const \ -{ +{ + +#define DEFINE_DERIVED_CLASS(Name, Parent) DEFINE_CLASS(Name) #define SYNCHRONOUS(Value) \ ns->setSynchronous(Value); @@ -191,6 +202,7 @@ inline void Name::toNetworkString(NetworkString* ns) const \ #include "network/packet_types_base.hpp" #undef DEFINE_CLASS +#undef DEFINE_DERIVED_CLASS #undef SYNCHRONOUS #undef AUX_VAR #undef DEFINE_FIELD @@ -208,6 +220,8 @@ inline void Name::toNetworkString(NetworkString* ns) const \ inline void Name::fromNetworkString(NetworkString* ns) \ { +#define DEFINE_DERIVED_CLASS(Name, Parent) DEFINE_CLASS(Name) + #define SYNCHRONOUS(Value) #define AUX_VAR(Type, Var) @@ -256,6 +270,7 @@ inline void Name::fromNetworkString(NetworkString* ns) \ #include "network/packet_types_base.hpp" #undef DEFINE_CLASS +#undef DEFINE_DERIVED_CLASS #undef SYNCHRONOUS #undef AUX_VAR #undef DEFINE_FIELD diff --git a/src/network/packet_types_base.hpp b/src/network/packet_types_base.hpp index defe84d37e3..8c005c263c7 100644 --- a/src/network/packet_types_base.hpp +++ b/src/network/packet_types_base.hpp @@ -181,12 +181,15 @@ DEFINE_CLASS(TrackSectorPacket) DEFINE_FIELD(uint32_t, last_triggered_checkline) END_DEFINE_CLASS(TrackSectorPacket) +DEFINE_CLASS(CheckPacket) +END_DEFINE_CLASS(CheckPacket) + DEFINE_CLASS(CheckStructureSubPacket) DEFINE_FIELD(Vec3, previous_position) DEFINE_FIELD(bool, is_active) END_DEFINE_CLASS(CheckStructureSubPacket) -DEFINE_CLASS(CheckStructurePacket) +DEFINE_DERIVED_CLASS(CheckStructurePacket, CheckPacket) AUX_VAR(uint32_t, karts_count) DEFINE_VECTOR_OBJ(CheckStructureSubPacket, karts_count, player_check_state) END_DEFINE_CLASS(CheckStructurePacket) @@ -195,13 +198,16 @@ DEFINE_CLASS(CheckLineSubPacket) DEFINE_FIELD(bool, previous_sign) END_DEFINE_CLASS(CheckLineSubPacket) -DEFINE_CLASS(CheckLinePacket) +DEFINE_DERIVED_CLASS(CheckLinePacket, CheckPacket) AUX_VAR(uint32_t, karts_count) DEFINE_FIELD_PTR(CheckStructurePacket, check_structure_packet) DEFINE_VECTOR_OBJ(CheckLineSubPacket, karts_count, subpackets) END_DEFINE_CLASS(CheckLinePacket) -DEFINE_CLASS(LinearWorldCompleteStatePacket) +DEFINE_CLASS(WorldPacket) +END_DEFINE_CLASS(WorldPacket) + +DEFINE_DERIVED_CLASS(LinearWorldCompleteStatePacket, WorldPacket) AUX_VAR(uint32_t, karts_count) AUX_VAR(uint32_t, track_sectors_count) DEFINE_FIELD(uint32_t, fastest_lap_ticks) @@ -224,7 +230,7 @@ DEFINE_CLASS(ScorerDataPacket) DEFINE_FIELD_OPTIONAL(uint8_t, handicap_level, check(0)) END_DEFINE_CLASS(ScoreerDataPacket) -DEFINE_CLASS(SoccerWorldCompleteStatePacket) +DEFINE_DERIVED_CLASS(SoccerWorldCompleteStatePacket, WorldPacket) DEFINE_FIELD(uint32_t, red_scorers_count) DEFINE_VECTOR_OBJ(ScorerDataPacket, red_scorers_count, red_scorers) DEFINE_FIELD(uint32_t, blue_scorers_count) @@ -233,12 +239,12 @@ DEFINE_CLASS(SoccerWorldCompleteStatePacket) DEFINE_FIELD(uint32_t, ticks_back_to_own_goal) END_DEFINE_CLASS(SoccerWorldCompleteStatePacket) -DEFINE_CLASS(FFAWorldCompleteStatePacket) +DEFINE_DERIVED_CLASS(FFAWorldCompleteStatePacket, WorldPacket) AUX_VAR(uint32_t, karts_count) DEFINE_VECTOR(uint32_t, karts_count, scores) END_DEFINE_CLASS(FFAWorldCompleteStatePacket) -DEFINE_CLASS(CTFWorldCompleteStatePacket) +DEFINE_DERIVED_CLASS(CTFWorldCompleteStatePacket, WorldPacket) DEFINE_FIELD_PTR(FFAWorldCompleteStatePacket, ffa_packet) DEFINE_FIELD(uint32_t, red_score) DEFINE_FIELD(uint32_t, blue_score) @@ -322,9 +328,20 @@ END_DEFINE_CLASS(BackLobbyPacket) DEFINE_CLASS(ServerInfoPacket) SYNCHRONOUS(true) DEFINE_FIXED_FIELD(uint8_t, type, LE_SERVER_INFO) - DEFINE_FIELD(uint8_t, placeholder) //...kimden: fill this // send with PRM_RELIABLE + DEFINE_FIELD(std::string, server_name); + DEFINE_FIELD(uint8_t, difficulty) + DEFINE_FIELD(uint8_t, max_players) + DEFINE_FIELD(uint8_t, extra_spectators_zero) + DEFINE_FIELD(uint8_t, game_mode) + DEFINE_FIELD(uint8_t, has_extra_server_info) /* can be more than 1 - in gp it's current track number, so not bool */ + DEFINE_FIELD_OPTIONAL(uint8_t, extra_server_info, has_extra_server_info) + DEFINE_FIELD(uint8_t, min_start_game_players) + DEFINE_FIELD(float, start_game_counter) + DEFINE_FIELD(widestr16, motd) + DEFINE_FIELD(bool, is_configurable) + DEFINE_FIELD(bool, has_live_players) END_DEFINE_CLASS(ServerInfoPacket) DEFINE_CLASS(AssetsPacket) diff --git a/src/network/protocols/server_lobby.cpp b/src/network/protocols/server_lobby.cpp index 0a596709d6e..eeaf069d320 100644 --- a/src/network/protocols/server_lobby.cpp +++ b/src/network/protocols/server_lobby.cpp @@ -555,7 +555,7 @@ void ServerLobby::writePlayerReport(Event* event) packet2.success = 1; packet2.reported_name = reporting_npp->getName(); packet2.toNetworkString(ns); - event->getPeer()->sendPacket(ns, PRM_RELIABLE); + event->getPeer()->sendNetstring(ns, PRM_RELIABLE); delete ns; } #endif @@ -1034,7 +1034,7 @@ void ServerLobby::rejectLiveJoin(std::shared_ptr peer, BackLobbyReason BackLobbyPacket packet1; packet1.reason = blr; packet1.toNetworkString(ns); - peer->sendPacket(ns, PRM_RELIABLE); + peer->sendNetstring(ns, PRM_RELIABLE); delete ns; updatePlayerList(); @@ -1044,7 +1044,7 @@ void ServerLobby::rejectLiveJoin(std::shared_ptr peer, BackLobbyReason //packet2.server_info = ...; m_game_setup->addServerInfo(ns2); packet2.toNetworkString(ns2); - peer->sendPacket(ns2, PRM_RELIABLE); + peer->sendNetstring(ns2, PRM_RELIABLE); delete ns2; peer->updateLastActivity(); @@ -1124,7 +1124,7 @@ void ServerLobby::liveJoinRequest(Event* event) NetworkString* ns; LoadWorldPacket load_world_packet = getLoadWorldMessage(players, true/*live_join*/); load_world_packet.toNetworkString(ns); - peer->sendPacket(ns, PRM_RELIABLE); + peer->sendNetstring(ns, PRM_RELIABLE); delete ns; peer->updateLastActivity(); @@ -1310,7 +1310,7 @@ void ServerLobby::finishedLoadingLiveJoinClient(Event* event) peer->setSpectator(spectator); packet.toNetworkString(ns); - peer->sendPacket(ns, PRM_RELIABLE); + peer->sendNetstring(ns, PRM_RELIABLE); delete ns; updatePlayerList(); peer->updateLastActivity(); @@ -1480,7 +1480,7 @@ void ServerLobby::update(int ticks) BackLobbyPacket packet; packet.reason = BLR_NONE; packet.toNetworkString(ns); - ai->sendPacket(ns, PRM_RELIABLE); + ai->sendNetstring(ns, PRM_RELIABLE); delete ns; } if (all_players_in_world_disconnected) @@ -1758,7 +1758,7 @@ void ServerLobby::startSelection(const Event *event) NetworkString* ns = getNetworkString(); BadTeamPacket packet; packet.toNetworkString(ns); - event->getPeer()->sendPacket(ns, PRM_RELIABLE); + event->getPeer()->sendNetstring(ns, PRM_RELIABLE); delete ns; } return; @@ -1922,7 +1922,7 @@ void ServerLobby::startSelection(const Event *event) packet.assets = getAssetManager()->encodePlayerKartsAndCommonMaps(all_k); packet.toNetworkString(ns); - peer->sendPacket(ns, PRM_RELIABLE); + peer->sendNetstring(ns, PRM_RELIABLE); delete ns; if (getQueues()->areKartFiltersIgnoringKarts()) @@ -2230,7 +2230,7 @@ void ServerLobby::kickPlayerWithReason(std::shared_ptr peer, const char packet.reason = RR_BANNED; packet.message = reason; packet.toNetworkString(ns); - peer->sendPacket(ns, PRM_RELIABLE, PEM_UNENCRYPTED); + peer->sendNetstring(ns, PRM_RELIABLE, PEM_UNENCRYPTED); peer->cleanPlayerProfiles(); peer->reset(); @@ -2281,7 +2281,7 @@ bool ServerLobby::handleAssetsAndAddonScores(std::shared_ptr peer, packet.reason = RR_INCOMPATIBLE_DATA; packet.message = getSettings()->getIncompatibleAdvice(); packet.toNetworkString(ns); - peer->sendPacket(ns, PRM_RELIABLE, PEM_UNENCRYPTED); + peer->sendNetstring(ns, PRM_RELIABLE, PEM_UNENCRYPTED); peer->cleanPlayerProfiles(); peer->reset(); @@ -2332,7 +2332,7 @@ void ServerLobby::connectionRequested(Event* event) packet.reason = RR_BUSY; packet.toNetworkString(ns); // send only to the peer that made the request and disconnect it now - peer->sendPacket(ns, PRM_RELIABLE, PEM_UNENCRYPTED); + peer->sendNetstring(ns, PRM_RELIABLE, PEM_UNENCRYPTED); delete ns; peer->reset(); @@ -2352,7 +2352,7 @@ void ServerLobby::connectionRequested(Event* event) ConnectionRefusedPacket packet; packet.reason = RR_INCOMPATIBLE_DATA; packet.toNetworkString(ns); - peer->sendPacket(ns, PRM_RELIABLE, PEM_UNENCRYPTED); + peer->sendNetstring(ns, PRM_RELIABLE, PEM_UNENCRYPTED); delete ns; peer->reset(); @@ -2414,7 +2414,7 @@ void ServerLobby::connectionRequested(Event* event) ConnectionRefusedPacket packet; packet.reason = RR_TOO_MANY_PLAYERS; packet.toNetworkString(ns); - peer->sendPacket(ns, PRM_RELIABLE, PEM_UNENCRYPTED); + peer->sendNetstring(ns, PRM_RELIABLE, PEM_UNENCRYPTED); delete ns; peer->reset(); @@ -2457,7 +2457,7 @@ void ServerLobby::connectionRequested(Event* event) ConnectionRefusedPacket packet; packet.reason = RR_INVALID_PLAYER; packet.toNetworkString(ns); - peer->sendPacket(ns, PRM_RELIABLE, PEM_UNENCRYPTED); + peer->sendNetstring(ns, PRM_RELIABLE, PEM_UNENCRYPTED); delete ns; peer->reset(); @@ -2505,7 +2505,7 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr peer, packet.reason = RR_BANNED; packet.message = "Please behave well next time."; packet.toNetworkString(ns); - peer->sendPacket(ns, PRM_RELIABLE, PEM_UNENCRYPTED); + peer->sendNetstring(ns, PRM_RELIABLE, PEM_UNENCRYPTED); delete ns; peer->reset(); @@ -2521,7 +2521,7 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr peer, ConnectionRefusedPacket packet; packet.reason = RR_INCORRECT_PASSWORD; packet.toNetworkString(ns); - peer->sendPacket(ns, PRM_RELIABLE, PEM_UNENCRYPTED); + peer->sendNetstring(ns, PRM_RELIABLE, PEM_UNENCRYPTED); delete ns; peer->reset(); @@ -2544,7 +2544,7 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr peer, ConnectionRefusedPacket packet; packet.reason = RR_TOO_MANY_PLAYERS; packet.toNetworkString(ns); - peer->sendPacket(ns, PRM_RELIABLE, PEM_UNENCRYPTED); + peer->sendNetstring(ns, PRM_RELIABLE, PEM_UNENCRYPTED); delete ns; peer->reset(); @@ -2562,7 +2562,7 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr peer, ConnectionRefusedPacket packet; packet.reason = RR_INVALID_PLAYER; packet.toNetworkString(ns); - peer->sendPacket(ns, PRM_RELIABLE, PEM_UNENCRYPTED); + peer->sendNetstring(ns, PRM_RELIABLE, PEM_UNENCRYPTED); delete ns; peer->reset(); @@ -2656,8 +2656,8 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr peer, // send a message to the one that asked to connect NetworkString* si = getNetworkString(); - getServerInfoPacket().toNetworkString(si); - peer->sendPacket(si); + m_game_setup->addServerInfo().toNetworkString(si); + peer->sendNetstring(si); delete si; peer->updateLastActivity(); @@ -2717,7 +2717,7 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr peer, { peer->setWaitingForGame(true); updatePlayerList(); - peer->sendPacket(ns); + peer->sendNetstring(ns); delete ns; } else @@ -2737,7 +2737,7 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr peer, } } updatePlayerList(); - peer->sendPacket(ns); + peer->sendNetstring(ns); delete ns; if (getSettings()->isRanked()) @@ -2991,7 +2991,7 @@ void ServerLobby::updateServerOwner(bool force) NetworkString* ns = getNetworkString(); ServerOwnershipPacket packet; packet.toNetworkString(ns); - owner->sendPacket(ns); + owner->sendNetstring(ns); delete ns; } m_server_owner = owner; @@ -3419,7 +3419,7 @@ void ServerLobby::resetServer() updatePlayerList(true/*update_when_reset_server*/); NetworkString* si = getNetworkString(); - getServerInfoPacket().toNetworkString(si); + m_game_setup->addServerInfo().toNetworkString(si); Comm::sendMessageToPeersInServer(si); delete si; @@ -3683,7 +3683,7 @@ void ServerLobby::handleServerConfiguration(std::shared_ptr peer, ConnectionRefusedPacket packet; packet.reason = RR_INCOMPATIBLE_DATA; packet.toNetworkString(ns); - peer->sendPacket(ns, PRM_RELIABLE); + peer->sendNetstring(ns, PRM_RELIABLE); delete ns; peer->cleanPlayerProfiles(); @@ -3718,7 +3718,7 @@ void ServerLobby::handleServerConfiguration(std::shared_ptr peer, } NetworkString* si = getNetworkString(); - getServerInfoPacket().toNetworkString(si); + m_game_setup->addServerInfo().toNetworkString(si); Comm::sendMessageToPeers(si); delete si; @@ -4014,7 +4014,7 @@ void ServerLobby::handleKartInfo(Event* event) packet.kart_data = rki.getKartData().encode(); packet.toNetworkString(ns); - peer->sendPacket(ns, PRM_RELIABLE); + peer->sendNetstring(ns, PRM_RELIABLE); delete ns; @@ -4105,14 +4105,14 @@ void ServerLobby::clientInGameWantsToBackLobby(Event* event) BackLobbyPacket packet; packet.reason = BLR_NONE; packet.toNetworkString(ns); - peer->sendPacket(ns, PRM_RELIABLE); + peer->sendNetstring(ns, PRM_RELIABLE); delete ns; updatePlayerList(); NetworkString* si = getNetworkString(); - getServerInfoPacket().toNetworkString(si); - peer->sendPacket(si, PRM_RELIABLE); + m_game_setup->addServerInfo().toNetworkString(si); + peer->sendNetstring(si, PRM_RELIABLE); delete si; peer->updateLastActivity(); @@ -4157,14 +4157,14 @@ void ServerLobby::clientSelectingAssetsWantsToBackLobby(Event* event) BackLobbyPacket packet; packet.reason = BLR_NONE; packet.toNetworkString(ns); - peer->sendPacket(ns, PRM_RELIABLE); + peer->sendNetstring(ns, PRM_RELIABLE); delete ns; updatePlayerList(); NetworkString* si = getNetworkString(); - getServerInfoPacket().toNetworkString(si); - peer->sendPacket(si, PRM_RELIABLE); + m_game_setup->addServerInfo().toNetworkString(si); + peer->sendNetstring(si, PRM_RELIABLE); delete si; peer->updateLastActivity(); @@ -4269,7 +4269,7 @@ void ServerLobby::writeOwnReport(std::shared_ptr reporter, std::shared_ packet.reported_name = reporting_npp->getName(); packet.toNetworkString(ns); - reporter->sendPacket(ns, PRM_RELIABLE); + reporter->sendNetstring(ns, PRM_RELIABLE); delete ns; } #endif @@ -4287,7 +4287,7 @@ void ServerLobby::sendStringToPeer(std::shared_ptr peer, const std::str ChatPacket packet; packet.message = StringUtils::utf8ToWide(s); packet.toNetworkString(ns); - peer->sendPacket(ns, PRM_RELIABLE); + peer->sendNetstring(ns, PRM_RELIABLE); delete ns; } // sendStringToPeer //----------------------------------------------------------------------------- @@ -4499,19 +4499,10 @@ bool ServerLobby::playerReportsTableExists() const //----------------------------------------------------------------------------- -ServerInfoPacket ServerLobby::getServerInfoPacket() const -{ - ServerInfoPacket packet; - packet.placeholder = 0; - // use m_game_setup->addServerInfo(server_info); - return packet; -} // getServerInfoPacket -//----------------------------------------------------------------------------- - void ServerLobby::sendServerInfoToEveryone() const { NetworkString* si = getNetworkString(); - getServerInfoPacket().toNetworkString(si); + m_game_setup->addServerInfo().toNetworkString(si); Comm::sendMessageToPeers(si); delete si; } // sendServerInfoToEveryone diff --git a/src/network/protocols/server_lobby.hpp b/src/network/protocols/server_lobby.hpp index 9f010b32cda..b120def19e5 100644 --- a/src/network/protocols/server_lobby.hpp +++ b/src/network/protocols/server_lobby.hpp @@ -359,8 +359,6 @@ class ServerLobby : public LobbyProtocol, public LobbyContextUser const std::string& type) const; bool playerReportsTableExists() const; - - ServerInfoPacket getServerInfoPacket() const; void sendServerInfoToEveryone() const; bool isWorldPicked() const { return m_state.load() >= LOAD_WORLD; } diff --git a/src/network/stk_host.cpp b/src/network/stk_host.cpp index c378114da14..37a806dac52 100644 --- a/src/network/stk_host.cpp +++ b/src/network/stk_host.cpp @@ -925,7 +925,7 @@ void STKHost::mainLoop(ProcessType pt) NetworkString msg(PROTOCOL_LOBBY_ROOM); msg.setSynchronous(true); msg.addUInt8(LobbyEvent::LE_BAD_CONNECTION); - p.second->sendPacket(&msg, PRM_RELIABLE); + p.second->sendNetstring(&msg, PRM_RELIABLE); } } } @@ -1344,7 +1344,7 @@ void STKHost::sendPacketToAllPeersInServer(NetworkString *data, PacketReliabilit for (auto p : m_peers) { if (p.second->isValidated()) - p.second->sendPacket(data, reliable); + p.second->sendNetstring(data, reliable); } } // sendPacketToAllPeersInServer @@ -1359,7 +1359,7 @@ void STKHost::sendPacketToAllPeers(NetworkString *data, PacketReliabilityMode re for (auto p : m_peers) { if (p.second->isValidated() && !p.second->isWaitingForGame()) - p.second->sendPacket(data, reliable); + p.second->sendNetstring(data, reliable); } } // sendPacketToAllPeers @@ -1379,7 +1379,7 @@ void STKHost::sendPacketExcept(std::shared_ptr peer, NetworkString *dat if (!stk_peer->isSamePeer(peer.get()) && p.second->isValidated() && !p.second->isWaitingForGame()) { - stk_peer->sendPacket(data, reliable); + stk_peer->sendNetstring(data, reliable); } } } // sendPacketExcept @@ -1400,7 +1400,7 @@ void STKHost::sendPacketToAllPeersWith(std::functionisValidated()) continue; if (predicate(stk_peer)) - stk_peer->sendPacket(data, reliable); + stk_peer->sendNetstring(data, reliable); } } // sendPacketToAllPeersWith @@ -1412,7 +1412,7 @@ void STKHost::sendToServer(NetworkString *data, PacketReliabilityMode reliable) if (m_peers.empty()) return; assert(NetworkConfig::get()->isClient()); - m_peers.begin()->second->sendPacket(data, reliable); + m_peers.begin()->second->sendNetstring(data, reliable); } // sendToServer //----------------------------------------------------------------------------- diff --git a/src/network/stk_peer.cpp b/src/network/stk_peer.cpp index 4b1a978376c..cec69aafdda 100644 --- a/src/network/stk_peer.cpp +++ b/src/network/stk_peer.cpp @@ -99,12 +99,12 @@ void STKPeer::reset() } // reset //----------------------------------------------------------------------------- -/** Sends a packet to this host. +/** Sends a network string to this host. * \param data The data to send. * \param reliable If the data is sent reliable or not. * \param encrypted If the data is sent encrypted or not. */ -void STKPeer::sendPacket(NetworkString *data, PacketReliabilityMode reliable, PacketEncryptionMode encrypted) +void STKPeer::sendNetstring(NetworkString *data, PacketReliabilityMode reliable, PacketEncryptionMode encrypted) { if (m_disconnected.load()) return; @@ -135,8 +135,17 @@ void STKPeer::sendPacket(NetworkString *data, PacketReliabilityMode reliable, Pa encrypted ? EVENT_CHANNEL_NORMAL : EVENT_CHANNEL_UNENCRYPTED, ECT_SEND_PACKET, m_address); } -} // sendPacket +} // sendNetstring + +//----------------------------------------------------------------------------- +void STKPeer::sendPacket(const Packet& packet, unsigned capacity, PacketReliabilityMode reliable, PacketEncryptionMode encrypted) +{ + NetworkString* ns = getNetworkString(capacity); + packet.toNetworkString(ns); + sendNetstring(ns, reliable, encrypted); + delete ns; +} // sendPacket //----------------------------------------------------------------------------- /** Returns if the peer is connected or not. */ diff --git a/src/network/stk_peer.hpp b/src/network/stk_peer.hpp index ebed54e3d92..3090162b88d 100644 --- a/src/network/stk_peer.hpp +++ b/src/network/stk_peer.hpp @@ -145,9 +145,12 @@ class STKPeer : public NoCopy // ------------------------------------------------------------------------ ~STKPeer(); // ------------------------------------------------------------------------ - void sendPacket(NetworkString *data, PacketReliabilityMode reliable = PRM_RELIABLE, + void sendNetstring(NetworkString *data, PacketReliabilityMode reliable = PRM_RELIABLE, PacketEncryptionMode encrypted = PEM_ENCRYPTED); // ------------------------------------------------------------------------ + void sendPacket(const Packet& packet, PacketReliabilityMode reliable = PRM_RELIABLE, + PacketEncryptionMode encrypted = PEM_ENCRYPTED); + ------------------------------------------------------------------------ void disconnect(); // ------------------------------------------------------------------------ void kick(); diff --git a/src/tracks/check_line.cpp b/src/tracks/check_line.cpp index 4fe5b724e7e..1e23525b72e 100644 --- a/src/tracks/check_line.cpp +++ b/src/tracks/check_line.cpp @@ -254,7 +254,7 @@ bool CheckLine::isTriggered(const Vec3 &old_pos, const Vec3 &new_pos, } // isTriggered // ---------------------------------------------------------------------------- -std::shared_ptr CheckLine::saveCompleteState() +std::shared_ptr CheckLine::saveCompleteState() { World* world = World::getWorld(); @@ -273,7 +273,7 @@ std::shared_ptr CheckLine::saveCompleteState() return packet; } // saveCompleteState // ---------------------------------------------------------------------------- -void CheckLine::restoreCompleteState(const std::shared_ptr& packet) +void CheckLine::restoreCompleteState(const std::shared_ptr& packet) { std::shared_ptr cl_packet = std::dynamic_pointer_cast(packet); diff --git a/src/tracks/check_line.hpp b/src/tracks/check_line.hpp index bf33270591a..cddf3ca2e22 100644 --- a/src/tracks/check_line.hpp +++ b/src/tracks/check_line.hpp @@ -86,9 +86,9 @@ class CheckLine : public CheckStructure * be too heigh to otherwise trigger he cannon). */ void setIgnoreHeight(bool b) { m_ignore_height = b; } // ------------------------------------------------------------------------ - virtual std::shared_ptr saveCompleteState() OVERRIDE; + virtual std::shared_ptr saveCompleteState() OVERRIDE; // ------------------------------------------------------------------------ - virtual void restoreCompleteState(const std::shared_ptr& packet) OVERRIDE; + virtual void restoreCompleteState(const std::shared_ptr& packet) OVERRIDE; // ------------------------------------------------------------------------ const Vec3 &getLeftPoint() const { return m_left_point; } // ------------------------------------------------------------------------ diff --git a/src/tracks/check_structure.cpp b/src/tracks/check_structure.cpp index 14c387b7d44..0f620bba407 100644 --- a/src/tracks/check_structure.cpp +++ b/src/tracks/check_structure.cpp @@ -247,7 +247,7 @@ void CheckStructure::trigger(unsigned int kart_index) } // trigger // ---------------------------------------------------------------------------- -std::shared_ptr CheckStructure::saveCompleteState() +std::shared_ptr CheckStructure::saveCompleteState() { std::shared_ptr packet = std::make_shared(); World* world = World::getWorld(); @@ -262,7 +262,7 @@ std::shared_ptr CheckStructure::saveCompleteState() } // saveCompleteState // ---------------------------------------------------------------------------- -void CheckStructure::restoreCompleteState(const std::shared_ptr& packet) +void CheckStructure::restoreCompleteState(const std::shared_ptr& packet) { std::shared_ptr check_packet = std::dynamic_pointer_cast(packet); diff --git a/src/tracks/check_structure.hpp b/src/tracks/check_structure.hpp index 1f6fc89e432..29ea2cb2b7c 100644 --- a/src/tracks/check_structure.hpp +++ b/src/tracks/check_structure.hpp @@ -137,9 +137,9 @@ class CheckStructure // ------------------------------------------------------------------------ virtual bool triggeringCheckline() const { return false; } // ------------------------------------------------------------------------ - virtual std::shared_ptr saveCompleteState(); + virtual std::shared_ptr saveCompleteState(); // ------------------------------------------------------------------------ - virtual void restoreCompleteState(const std::shared_ptr& packet); + virtual void restoreCompleteState(const std::shared_ptr& packet); // ------------------------------------------------------------------------ void saveIsActive(int kart_id, BareNetworkString* bns); // ------------------------------------------------------------------------ From 695563d9ded45b005fdab7ca71fb4484951d2c6f Mon Sep 17 00:00:00 2001 From: kimden <23140380+kimden@users.noreply.github.com> Date: Sun, 6 Apr 2025 03:24:48 +0400 Subject: [PATCH 08/34] Process packets from worlds, start editing client lobby --- src/modes/capture_the_flag.cpp | 14 +-- src/modes/free_for_all.cpp | 31 +++++-- src/modes/free_for_all.hpp | 4 +- src/modes/linear_world.cpp | 26 +++--- src/modes/soccer_world.cpp | 87 +++++++++++------- src/modes/soccer_world.hpp | 5 +- src/network/game_setup.hpp | 1 - src/network/packet_types_base.hpp | 73 +++++++++++++++ src/network/peer_vote.hpp | 2 +- src/network/protocols/client_lobby.cpp | 91 ++++++++++--------- src/network/protocols/client_lobby.hpp | 4 +- .../protocols/game_events_protocol.cpp | 15 ++- src/network/stk_host.cpp | 5 +- src/tracks/check_structure.cpp | 11 ++- src/tracks/check_structure.hpp | 4 +- 15 files changed, 236 insertions(+), 137 deletions(-) diff --git a/src/modes/capture_the_flag.cpp b/src/modes/capture_the_flag.cpp index 2b0d8afe6a3..c6f7be35feb 100644 --- a/src/modes/capture_the_flag.cpp +++ b/src/modes/capture_the_flag.cpp @@ -341,13 +341,13 @@ void CaptureTheFlag::checkScoring(FlagColor color) if (NetworkConfig::get()->isServer()) { NetworkString p(PROTOCOL_GAME_EVENTS); - p.setSynchronous(true); - p.addUInt8(GameEventsProtocol::GE_CTF_SCORED) - .addUInt8((int8_t)active_holder) - .addUInt8((red_active) ? 0 : 1 /*red_team_scored*/) - .addUInt16((int16_t)new_kart_score) - .addUInt8((uint8_t)new_red_score) - .addUInt8((uint8_t)new_blue_score); + InsideCtfPacket packet; + packet.active_holder = (int8_t)active_holder; + packet.red_inactive = !red_active; + packet.kart_score = (int16_t)new_kart_score; + packet.red_score = (uint8_t)new_red_score; + packet.blue_score = (uint8_t)new_blue_score; + packet.toNetworkString(&p); STKHost::get()->sendPacketToAllPeers(&p, PRM_RELIABLE); } ctfScored(active_holder, (red_active) ? false : true /*red_team_scored*/, diff --git a/src/modes/free_for_all.cpp b/src/modes/free_for_all.cpp index b814bfc9730..9a510f24437 100644 --- a/src/modes/free_for_all.cpp +++ b/src/modes/free_for_all.cpp @@ -124,21 +124,29 @@ void FreeForAll::handleScoreInServer(int kart_id, int hitter) NetworkConfig::get()->isServer()) { NetworkString p(PROTOCOL_GAME_EVENTS); - p.setSynchronous(true); - p.addUInt8(GameEventsProtocol::GE_BATTLE_KART_SCORE); + InsideFfaPacket packet; + if (kart_id == hitter || hitter == -1) - p.addUInt8((uint8_t)kart_id).addUInt16((int16_t)new_score); + { + packet.hitter_kart = (uint8_t)kart_id; + packet.new_score = (int16_t)new_score; + } else - p.addUInt8((uint8_t)hitter).addUInt16((int16_t)new_score); + { + packet.hitter_kart = (uint8_t)hitter; + packet.new_score = (int16_t)new_score; + } + + packet.toNetworkString(&p); STKHost::get()->sendPacketToAllPeers(&p, PRM_RELIABLE); } } // handleScoreInServer // ---------------------------------------------------------------------------- -void FreeForAll::setKartScoreFromServer(NetworkString& ns) +void FreeForAll::setKartScoreFromServer(const InsideFfaPacket& packet) { - int kart_id = ns.getUInt8(); - int16_t score = ns.getUInt16(); + int kart_id = packet.hitter_kart; + int16_t score = packet.new_score; m_scores.at(kart_id) = score; } // setKartScoreFromServer @@ -351,9 +359,12 @@ void FreeForAll::notifyAboutScoreIfNonzero(int id) m_scores[id] != 0) { NetworkString p(PROTOCOL_GAME_EVENTS); - p.setSynchronous(true); - p.addUInt8(GameEventsProtocol::GE_BATTLE_KART_SCORE); - p.addUInt8((uint8_t)id).addUInt16((int16_t)m_scores[id]); + + InsideFfaPacket packet; + packet.hitter_kart = (uint8_t)id; + packet.new_score = (int16_t)m_scores[id]; + packet.toNetworkString(&p); + STKHost::get()->sendPacketToAllPeers(&p, PRM_RELIABLE); } } // notifyAboutScoreIfNonzero diff --git a/src/modes/free_for_all.hpp b/src/modes/free_for_all.hpp index 1cc2cb88fda..98ca93abd2c 100644 --- a/src/modes/free_for_all.hpp +++ b/src/modes/free_for_all.hpp @@ -23,8 +23,6 @@ #include -class NetworkString; - class FreeForAll : public WorldWithRank { protected: @@ -70,7 +68,7 @@ class FreeForAll : public WorldWithRank // ------------------------------------------------------------------------ virtual void terminateRace() OVERRIDE; // ------------------------------------------------------------------------ - void setKartScoreFromServer(NetworkString& ns); + void setKartScoreFromServer(const InsideFfaPacket& packet); // ------------------------------------------------------------------------ int getKartScore(int kart_id) const { return m_scores.at(kart_id); } // ------------------------------------------------------------------------ diff --git a/src/modes/linear_world.cpp b/src/modes/linear_world.cpp index cae06ac8fb4..79ee102ad9b 100644 --- a/src/modes/linear_world.cpp +++ b/src/modes/linear_world.cpp @@ -1340,26 +1340,26 @@ void LinearWorld::updateCheckLinesServer(int check_id, int kart_id) return; NetworkString cl(PROTOCOL_GAME_EVENTS); - cl.setSynchronous(true); - cl.addUInt8(GameEventsProtocol::GE_CHECK_LINE).addUInt8((uint8_t)check_id) - .addUInt8((uint8_t)kart_id); - int8_t finished_laps = (int8_t)m_kart_info[kart_id].m_finished_laps; - cl.addUInt8(finished_laps); + InsideChecklinePacket packet; + packet.kart_id = (uint8_t)kart_id; + packet.finished_laps = (int8_t)m_kart_info[kart_id].m_finished_laps; + packet.last_triggered_checkline = + (int8_t)m_kart_track_sector[kart_id]->getLastTriggeredCheckline(); - int8_t ltcl = - (int8_t)m_kart_track_sector[kart_id]->getLastTriggeredCheckline(); - cl.addUInt8(ltcl); - - cl.addUInt32(m_fastest_lap_ticks); - cl.encodeString(m_fastest_lap_kart_name); + packet.fastest_lap_ticks = m_fastest_lap_ticks; + packet.fastest_kart_name = m_fastest_lap_kart_name; CheckManager* cm = Track::getCurrentTrack()->getCheckManager(); const uint8_t cc = (uint8_t)cm->getCheckStructureCount(); - cl.addUInt8(cc); + packet.check_structure_count = cc; for (unsigned i = 0; i < cc; i++) - cm->getCheckStructure(i)->saveIsActive(kart_id, &cl); + { + packet.check_active.push_back( + cm->getCheckStructure(i)->saveIsActive(kart_id)); + } + packet.toNetworkString(&cl); STKHost::get()->sendPacketToAllPeers(&cl, PRM_RELIABLE); } // updateCheckLinesServer diff --git a/src/modes/soccer_world.cpp b/src/modes/soccer_world.cpp index d3fa9a443b5..ed2786e6d38 100644 --- a/src/modes/soccer_world.cpp +++ b/src/modes/soccer_world.cpp @@ -687,17 +687,24 @@ void SoccerWorld::onCheckGoalTriggered(bool first_goal) if (NetworkConfig::get()->isNetworking() && NetworkConfig::get()->isServer()) { - NetworkString p(PROTOCOL_GAME_EVENTS); - p.setSynchronous(true); - p.addUInt8(GameEventsProtocol::GE_PLAYER_GOAL) - .addUInt8((uint8_t)sd.m_id).addUInt8(sd.m_correct_goal) - .addUInt8(first_goal).addFloat(sd.m_time) - .addTime(m_ticks_back_to_own_goal) - .encodeString(sd.m_kart).encodeString(sd.m_player); + InternalGoalPacket packet; + packet.id = (uint8_t)sd.m_id; + packet.correct_goal = sd.m_correct_goal; + packet.first_goal = first_goal; + packet.time = sd.m_time; + packet.ticks_back_to_own_goal = m_ticks_back_to_own_goal; + packet.kart = sd.m_kart; + packet.player = sd.m_player; + // Added in 1.1, add missing handicap info and country code - NetworkString p_1_1 = p; - p_1_1.encodeString(sd.m_country_code) - .addUInt8(sd.m_handicap_level); + InternalGoalPacket packet_1_1 = packet; + packet_1_1.country_code = std::make_shared(sd.m_country_code); + packet_1_1.handicap = std::make_shared(sd.m_handicap_level); + + NetworkString p(PROTOCOL_GAME_EVENTS); + NetworkString p_1_1(PROTOCOL_GAME_EVENTS); + packet.toNetworkString(&p); + packet.toNetworkString(&p_1_1); auto peers = STKHost::get()->getPeers(); for (auto& peer : peers) @@ -737,10 +744,10 @@ void SoccerWorld::onCheckGoalTriggered(bool first_goal) } // onCheckGoalTriggered //----------------------------------------------------------------------------- -void SoccerWorld::handleResetBallFromServer(const NetworkString& ns) +void SoccerWorld::handleResetBallFromServer(const ResetBallPacket& packet) { int ticks_now = World::getWorld()->getTicksSinceStart(); - int ticks_back_to_own_goal = ns.getTime(); + int ticks_back_to_own_goal = packet.reset_ball_ticks; if (ticks_now >= ticks_back_to_own_goal) { Log::warn("SoccerWorld", "Server ticks %d is too close to client ticks " @@ -751,23 +758,26 @@ void SoccerWorld::handleResetBallFromServer(const NetworkString& ns) } // handleResetBallFromServer //----------------------------------------------------------------------------- -void SoccerWorld::handlePlayerGoalFromServer(const NetworkString& ns) +void SoccerWorld::handlePlayerGoalFromServer(const InternalGoalPacket& packet) { ScorerData sd = {}; - sd.m_id = ns.getUInt8(); - sd.m_correct_goal = ns.getUInt8() == 1; - bool first_goal = ns.getUInt8() == 1; - sd.m_time = ns.getFloat(); + sd.m_id = packet.id; + sd.m_correct_goal = packet.correct_goal; + bool first_goal = packet.first_goal; + sd.m_time = packet.time; int ticks_now = World::getWorld()->getTicksSinceStart(); - int ticks_back_to_own_goal = ns.getTime(); - ns.decodeString(&sd.m_kart); - ns.decodeStringW(&sd.m_player); + int ticks_back_to_own_goal = packet.ticks_back_to_own_goal; + sd.m_kart = packet.kart; + sd.m_player = packet.player; // Added in 1.1, add missing handicap info and country code if (NetworkConfig::get()->getServerCapabilities().find("soccer_fixes") != NetworkConfig::get()->getServerCapabilities().end()) { - ns.decodeString(&sd.m_country_code); - sd.m_handicap_level = (HandicapLevel)ns.getUInt8(); + if (packet.country_code) + sd.m_country_code = *packet.country_code; + + if (packet.handicap) + sd.m_handicap_level = (HandicapLevel)(*packet.handicap); } if (first_goal) @@ -973,9 +983,9 @@ void SoccerWorld::updateBallPosition(int ticks) stk_config->time2Ticks(2.0f); NetworkString p(PROTOCOL_GAME_EVENTS); - p.setSynchronous(true); - p.addUInt8(GameEventsProtocol::GE_RESET_BALL) - .addTime(m_reset_ball_ticks); + ResetBallPacket packet; + packet.reset_ball_ticks = m_reset_ball_ticks; + packet.toNetworkString(&p); STKHost::get()->sendPacketToAllPeers(&p, PRM_RELIABLE); } else if (!NetworkConfig::get()->isNetworking()) @@ -1364,15 +1374,18 @@ std::pair SoccerWorld::getCount() const { void SoccerWorld::tellCountToEveryoneInGame() const { auto peers = STKHost::get()->getPeers(); - NetworkString* chat = new NetworkString(PROTOCOL_LOBBY_ROOM); - chat->addUInt8(17); // LE_CHAT - chat->setSynchronous(true); auto real_score = getCount(); int real_red = real_score.first; int real_blue = real_score.second; - std::string real_count = - std::to_string(real_red) + " : " + std::to_string(real_blue); - chat->encodeString16(StringUtils::utf8ToWide(real_count)); + std::string real_count = std::to_string(real_red) + + " : " + std::to_string(real_blue); + + // This should be done using sendStringTo... + NetworkString* chat = new NetworkString(PROTOCOL_LOBBY_ROOM); + ChatPacket packet; + packet.message = StringUtils::utf8ToWide(real_count); + packet.toNetworkString(chat); + for (auto& peer : peers) if (peer->isValidated() && !peer->isWaitingForGame()) peer->sendNetstring(chat, PRM_RELIABLE); @@ -1384,15 +1397,19 @@ void SoccerWorld::tellCount(std::shared_ptr peer) const { if (!peer->isValidated()) return; - NetworkString* chat = new NetworkString(PROTOCOL_LOBBY_ROOM); - chat->addUInt8(17); // LE_CHAT - chat->setSynchronous(true); + auto real_score = getCount(); int real_red = real_score.first; int real_blue = real_score.second; std::string real_count = std::to_string(real_red) + " : " + std::to_string(real_blue); - chat->encodeString16(StringUtils::utf8ToWide(real_count)); + + // This should be done using sendStringTo... + NetworkString* chat = new NetworkString(PROTOCOL_LOBBY_ROOM); + ChatPacket packet; + packet.message = StringUtils::utf8ToWide(real_count); + packet.toNetworkString(chat); + peer->sendNetstring(chat, PRM_RELIABLE); delete chat; } // tellCount diff --git a/src/modes/soccer_world.hpp b/src/modes/soccer_world.hpp index 7aaf8651aa0..17758894efc 100644 --- a/src/modes/soccer_world.hpp +++ b/src/modes/soccer_world.hpp @@ -28,7 +28,6 @@ class AbstractKart; class BallGoalData; class Controller; -class NetworkString; class TrackObject; class TrackSector; @@ -237,9 +236,9 @@ class SoccerWorld : public WorldWithRank /** Get the AI who will attack the other team ball chaser. */ int getAttacker(KartTeam team) const; // ------------------------------------------------------------------------ - void handlePlayerGoalFromServer(const NetworkString& ns); + void handlePlayerGoalFromServer(const InternalGoalPacket& packet); // ------------------------------------------------------------------------ - void handleResetBallFromServer(const NetworkString& ns); + void handleResetBallFromServer(const ResetBallPacket& packet); // ------------------------------------------------------------------------ virtual bool hasTeam() const OVERRIDE { return true; } // ------------------------------------------------------------------------ diff --git a/src/network/game_setup.hpp b/src/network/game_setup.hpp index d380dcd21af..140e2d0a26f 100644 --- a/src/network/game_setup.hpp +++ b/src/network/game_setup.hpp @@ -32,7 +32,6 @@ #include class NetworkPlayerProfile; -class NetworkString; class PeerVote; // ============================================================================ diff --git a/src/network/packet_types_base.hpp b/src/network/packet_types_base.hpp index 8c005c263c7..053b8fb9a08 100644 --- a/src/network/packet_types_base.hpp +++ b/src/network/packet_types_base.hpp @@ -531,4 +531,77 @@ DEFINE_CLASS(GPScoresPacket) DEFINE_VECTOR(GPIndividualScorePacket, num_players, scores) END_DEFINE_CLASS(GPScoresPacket) +DEFINE_CLASS(InsideCtfPacket) + SYNCHRONOUS(true) + DEFINE_FIXED_FIELD(uint8_t, type, GameEventsProtocol::GE_CTF_SCORED) + DEFINE_FIELD(uint8_t, active_holder) + DEFINE_FIELD(bool, red_inactive) /* actually, red scored */ + DEFINE_FIELD(uint16_t, kart_score) + DEFINE_FIELD(uint8_t, red_score) + DEFINE_FIELD(uint8_t, blue_score) + // send with PRM_RELIABLE +END_DEFINE_CLASS(InsideCtfPacket) + +DEFINE_CLASS(InsideFfaPacket) + SYNCHRONOUS(true) + DEFINE_FIXED_FIELD(uint8_t, type, GameEventsProtocol::GE_BATTLE_KART_SCORE) + DEFINE_FIELD(uint8_t, hitter_kart) + DEFINE_FIELD(uint16_t, new_score) + // send with PRM_RELIABLE +END_DEFINE_CLASS(InsideFfaPacket) + +/* Separation is needed because it's filled in check structure itself */ +DEFINE_CLASS(CheckActivePacket) + DEFINE_FIELD(bool, active) +END_DEFINE_CLASS(CheckActivePacket) + +DEFINE_CLASS(InsideChecklinePacket) + SYNCHRONOUS(true) + DEFINE_FIXED_FIELD(uint8_t, type, GameEventsProtocol::GE_CHECK_LINE) + DEFINE_FIELD(uint8_t, check_id) + DEFINE_FIELD(uint8_t, kart_id) + DEFINE_FIELD(uint8_t, finished_laps) + DEFINE_FIELD(uint8_t, last_triggered_checkline) + DEFINE_FIELD(uint32_t, fastest_lap_ticks) + DEFINE_FIELD(widestr, fastest_kart_name) + DEFINE_FIELD(uint8_t, check_structure_count) + DEFINE_VECTOR_OBJ(CheckActivePacket, check_structure_count, check_active) +END_DEFINE_CLASS(InsideChecklinePacket) + + +DEFINE_CLASS(InternalGoalPacket) + SYNCHRONOUS(true) + DEFINE_FIXED_FIELD(uint8_t, type, GameEventsProtocol::GE_PLAYER_GOAL) + DEFINE_FIELD(uint8_t, id) + DEFINE_FIELD(bool, correct_goal) + DEFINE_FIELD(bool, first_goal) + DEFINE_FIELD(float, time) + DEFINE_FIELD(uint32_t, ticks_back_to_own_goal) + DEFINE_FIELD(std::string, kart) + DEFINE_FIELD(widestr, player) + /* what follows is only since 1.1, that is, when capabilities have "soccer_fixes" */ + DEFINE_FIELD_OPTIONAL(std::string, country_code, check(0)) + DEFINE_FIELD_OPTIONAL(uint8_t, handicap, check(0)) + // send with PRM_RELIABLE +END_DEFINE_CLASS(InternalGoalPacket) + +DEFINE_CLASS(ResetBallPacket) + SYNCHRONOUS(true) + DEFINE_FIXED_FIELD(uint8_t, type, GameEventsProtocol::GE_RESET_BALL) + DEFINE_FIELD(uint32_t, reset_ball_ticks) + // send with PRM_RELIABLE +END_DEFINE_CLASS(ResetBallPacket) + +DEFINE_CLASS(BadConnectionPacket) + SYNCHRONOUS(true) + DEFINE_FIXED_FIELD(uint8_t, type, LobbyEvent::LE_BAD_CONNECTION) + // send with PRM_RELIABLE +END_DEFINE_CLASS(BadConnectionPacket) + +DEFINE_CLASS(RaceFinishedAckPacket) + SYNCHRONOUS(true) + DEFINE_FIXED_FIELD(uint8_t, type, LE_RACE_FINISHED_ACK) + // send with PRM_RELIABLE +END_DEFINE_CLASS(RaceFinishedAckPacket) + // end \ No newline at end of file diff --git a/src/network/peer_vote.hpp b/src/network/peer_vote.hpp index a955ee8b108..60f1c6f82cd 100644 --- a/src/network/peer_vote.hpp +++ b/src/network/peer_vote.hpp @@ -58,7 +58,7 @@ class PeerVote m_track_name = packet.track_name; m_num_laps = packet.num_laps; m_reverse = packet.is_reverse; - } // PeerVote(NetworkString &) + } // PeerVote(PeerVotePacket &) // ------------------------------------------------------ /** Encodes this vote object into a network string. */ diff --git a/src/network/protocols/client_lobby.cpp b/src/network/protocols/client_lobby.cpp index 7d3d25d904b..dc1570493fe 100644 --- a/src/network/protocols/client_lobby.cpp +++ b/src/network/protocols/client_lobby.cpp @@ -178,8 +178,8 @@ void ClientLobby::setup() void ClientLobby::doneWithResults() { NetworkString* done = getNetworkString(1); - done->setSynchronous(true); - done->addUInt8(LE_RACE_FINISHED_ACK); + RaceFinishedAckPacket packet; + packet.toNetworkString(done); Comm::sendToServer(done, PRM_RELIABLE); delete done; } // doneWithResults @@ -306,9 +306,9 @@ void ClientLobby::addAllPlayers(Event* event) STKHost::get()->getNetworkTimerSynchronizer()->enableForceSetTimer(); } - NetworkString& data = event->data(); - uint32_t winner_peer_id = data.getUInt32(); - PeerVote winner_vote(data); + auto packet = event->getPacket(); + uint32_t winner_peer_id = packet.default_vote.winner_peer_id; + PeerVote winner_vote(packet.default_vote.default_vote); m_game_setup->setRace(winner_vote); if (!GUIEngine::isNoGraphics()) @@ -316,24 +316,29 @@ void ClientLobby::addAllPlayers(Event* event) std::shared_ptr peer = event->getPeerSP(); peer->cleanPlayerProfiles(); - m_server_send_live_load_world = data.getUInt8() == 1; + m_server_send_live_load_world = packet.live_join; bool is_spectator = true; - std::vector > players = - decodePlayers(data, peer, &is_spectator); + std::vector > players; + unsigned player_count = packet.players_size; + for (unsigned i = 0; i < player_count; ++i) + players.push_back(decodePlayer(packet.all_players[i], peer, &is_spectator)); setSpectator(is_spectator); - uint32_t random_seed = data.getUInt32(); - ItemManager::updateRandomSeed(random_seed); + ItemManager::updateRandomSeed(packet.item_seed); if (RaceManager::get()->isBattleMode()) { - int hit_capture_limit = data.getUInt32(); - float time_limit = data.getFloat(); - m_game_setup->setHitCaptureTime(hit_capture_limit, time_limit); - uint16_t flag_return_timeout = data.getUInt16(); - RaceManager::get()->setFlagReturnTicks(flag_return_timeout); - unsigned flag_deactivated_time = data.getUInt16(); - RaceManager::get()->setFlagDeactivatedTicks(flag_deactivated_time); + // kimden: double checking when it's not needed? + if (packet.battle_info) + { + BattleInfoPacket subpacket = *packet.battle_info; + + m_game_setup->setHitCaptureTime(subpacket.battle_hit_capture_limit, + subpacket.battle_time_limit); + + RaceManager::get()->setFlagReturnTicks(subpacket.flag_return_time); + RaceManager::get()->setFlagDeactivatedTicks(subpacket.flag_deactivated_time); + } } getPlayersAddonKartType(data, players); configRemoteKart(players, isSpectator() ? 1 : @@ -370,35 +375,29 @@ void ClientLobby::addAllPlayers(Event* event) //----------------------------------------------------------------------------- /* Get list of players from server and see if we are spectating it. */ -std::vector > - ClientLobby::decodePlayers(const BareNetworkString& data, +std::shared_ptr + ClientLobby::decodePlayer(const EncodedSinglePlayerPacket& packet, std::shared_ptr peer, bool* is_spectator) const { - std::vector > players; - unsigned player_count = data.getUInt8(); - for (unsigned i = 0; i < player_count; i++) - { - core::stringw player_name; - data.decodeStringW(&player_name); - uint32_t host_id = data.getUInt32(); - float kart_color = data.getFloat(); - uint32_t online_id = data.getUInt32(); - HandicapLevel handicap = (HandicapLevel)data.getUInt8(); - uint8_t local_id = data.getUInt8(); - KartTeam team = (KartTeam)data.getUInt8(); - std::string country_code; - data.decodeString(&country_code); - if (is_spectator && host_id == STKHost::get()->getMyHostId()) - *is_spectator = false; - auto player = std::make_shared(peer, player_name, - host_id, kart_color, online_id, handicap, local_id, team, country_code); - std::string kart_name; - data.decodeString(&kart_name); - player->setKartName(kart_name); - players.push_back(player); - } - return players; + core::stringw player_name; + data.decodeStringW(&player_name); + uint32_t host_id = data.getUInt32(); + float kart_color = data.getFloat(); + uint32_t online_id = data.getUInt32(); + HandicapLevel handicap = (HandicapLevel)data.getUInt8(); + uint8_t local_id = data.getUInt8(); + KartTeam team = (KartTeam)data.getUInt8(); + std::string country_code; + data.decodeString(&country_code); + if (is_spectator && host_id == STKHost::get()->getMyHostId()) + *is_spectator = false; + auto player = std::make_shared(peer, player_name, + host_id, kart_color, online_id, handicap, local_id, team, country_code); + std::string kart_name; + data.decodeString(&kart_name); + player->setKartName(kart_name); + return player; } // decodePlayers //----------------------------------------------------------------------------- @@ -1345,8 +1344,10 @@ void ClientLobby::liveJoinAcknowledged(Event* event) { // Get and update the players list 1 more time in case the was // player connection or disconnection - std::vector > players = - decodePlayers(data); + std::vector > players; + unsigned player_count = data.getUInt8(); + for (unsigned i = 0; i < player_count; ++i) + players.push_back(decodePlayer(data)); getPlayersAddonKartType(data, players); w->resetElimination(); for (unsigned i = 0; i < players.size(); i++) diff --git a/src/network/protocols/client_lobby.hpp b/src/network/protocols/client_lobby.hpp index 5f50dd8b0de..bef3e50e35c 100644 --- a/src/network/protocols/client_lobby.hpp +++ b/src/network/protocols/client_lobby.hpp @@ -144,8 +144,8 @@ class ClientLobby : public LobbyProtocol void liveJoinAcknowledged(Event* event); void handleKartInfo(Event* event); void finishLiveJoin(); - std::vector > - decodePlayers(const BareNetworkString& data, + std::shared_ptr + decodePlayer(const EncodedSinglePlayerPacket& packet, std::shared_ptr peer = nullptr, bool* is_spectator = NULL) const; void getPlayersAddonKartType(const BareNetworkString& data, diff --git a/src/network/protocols/game_events_protocol.cpp b/src/network/protocols/game_events_protocol.cpp index 1e39aae4580..cd57f22075d 100644 --- a/src/network/protocols/game_events_protocol.cpp +++ b/src/network/protocols/game_events_protocol.cpp @@ -86,20 +86,19 @@ bool GameEventsProtocol::notifyEvent(Event* event) { if (!ffa) throw std::invalid_argument("No free-for-all world"); - ffa->setKartScoreFromServer(data); + + auto packet = event->getPacket(); + ffa->setKartScoreFromServer(packet); break; } case GE_CTF_SCORED: { if (!ctf) throw std::invalid_argument("No CTF world"); - uint8_t kart_id = data.getUInt8(); - bool red_team_scored = data.getUInt8() == 1; - int16_t new_kart_scores = data.getUInt16(); - int new_red_scores = data.getUInt8(); - int new_blue_scores = data.getUInt8(); - ctf->ctfScored(kart_id, red_team_scored, new_kart_scores, - new_red_scores, new_blue_scores); + + auto packet = event->getPacket(); + ctf->ctfScored(packet.active_holder, packet.red_inactive, packet.kart_score, + packet.red_score, packet.blue_score); break; } case GE_STARTUP_BOOST: diff --git a/src/network/stk_host.cpp b/src/network/stk_host.cpp index 37a806dac52..49ee24e1f43 100644 --- a/src/network/stk_host.cpp +++ b/src/network/stk_host.cpp @@ -922,9 +922,10 @@ void STKHost::mainLoop(ProcessType pt) p.second->getAddress().toString().c_str(), player_name.c_str(), ap, max_ping); p.second->setWarnedForHighPing(true); + NetworkString msg(PROTOCOL_LOBBY_ROOM); - msg.setSynchronous(true); - msg.addUInt8(LobbyEvent::LE_BAD_CONNECTION); + BadConnectionPacket packet; + packet.toNetworkString(&msg); p.second->sendNetstring(&msg, PRM_RELIABLE); } } diff --git a/src/tracks/check_structure.cpp b/src/tracks/check_structure.cpp index 0f620bba407..963cd7998c9 100644 --- a/src/tracks/check_structure.cpp +++ b/src/tracks/check_structure.cpp @@ -287,14 +287,15 @@ void CheckStructure::restoreCompleteState(const std::shared_ptr& pa } // restoreCompleteState // ---------------------------------------------------------------------------- -void CheckStructure::saveIsActive(int kart_id, BareNetworkString* bns) +CheckActivePacket CheckStructure::saveIsActive(int kart_id) { - bns->addUInt8(m_is_active[kart_id] ? 1 : 0); + CheckActivePacket packet; + packet.active = m_is_active[kart_id]; + return packet; } // saveIsActive // ---------------------------------------------------------------------------- -void CheckStructure::restoreIsActive(int kart_id, const BareNetworkString& b) +void CheckStructure::restoreIsActive(int kart_id, const CheckActivePacket& packet) { - bool is_active = b.getUInt8() == 1; - m_is_active.at(kart_id) = is_active; + m_is_active.at(kart_id) = packet.active; } // restoreIsActive diff --git a/src/tracks/check_structure.hpp b/src/tracks/check_structure.hpp index 29ea2cb2b7c..27c79c71876 100644 --- a/src/tracks/check_structure.hpp +++ b/src/tracks/check_structure.hpp @@ -141,9 +141,9 @@ class CheckStructure // ------------------------------------------------------------------------ virtual void restoreCompleteState(const std::shared_ptr& packet); // ------------------------------------------------------------------------ - void saveIsActive(int kart_id, BareNetworkString* bns); + CheckActivePacket saveIsActive(int kart_id); // ------------------------------------------------------------------------ - void restoreIsActive(int kart_id, const BareNetworkString& b); + void restoreIsActive(int kart_id, const CheckActivePacket& packet); // ------------------------------------------------------------------------ int getIndex() const { return m_index; } // ------------------------------------------------------------------------ From 578289d580a419b31354c77cb1b05a3290554a9f Mon Sep 17 00:00:00 2001 From: kimden <23140380+kimden@users.noreply.github.com> Date: Mon, 7 Apr 2025 00:57:04 +0400 Subject: [PATCH 09/34] Packets from various files --- src/network/packet_types.hpp | 15 ++++++++ src/network/packet_types_base.hpp | 35 ++++++++++++----- src/network/protocols/game_protocol.cpp | 6 ++- src/network/protocols/server_lobby.hpp | 1 - src/race/race_manager.cpp | 19 +++++----- src/race/race_manager.hpp | 3 +- .../dialogs/race_paused_dialog.cpp | 4 +- .../dialogs/server_configuration_dialog.cpp | 26 +++++++++---- .../online/network_kart_selection.cpp | 38 ++++++++++++------- .../online/networking_lobby.cpp | 10 ++--- src/states_screens/online/tracks_screen.cpp | 35 ++++++++++------- src/utils/chat_manager.cpp | 5 ++- src/utils/lobby_asset_manager.hpp | 1 - src/utils/lobby_gp_manager.hpp | 1 - src/utils/lobby_settings.cpp | 2 +- src/utils/lobby_settings.hpp | 1 - 16 files changed, 130 insertions(+), 72 deletions(-) diff --git a/src/network/packet_types.hpp b/src/network/packet_types.hpp index 9fd0f6c075b..6e180e27fb3 100644 --- a/src/network/packet_types.hpp +++ b/src/network/packet_types.hpp @@ -92,12 +92,27 @@ enum BackLobbyReason : uint8_t BLR_SPECTATING_NEXT_GAME = 5 }; +//---------------------- Basic packet definitions ----------------------------- + +namespace +{ + const std::string SOCCER_FIXES = "soccer_fixes"; + const std::string REAL_ADDON_KARTS = "real_addon_karts"; +} + + struct Packet { + std::function m_capability_checker; + // Needed to dynamic_cast virtual ~Packet() {} virtual void toNetworkString(NetworkString* ns) const {} virtual void fromNetworkString(NetworkString* ns) {} + + bool cap(const std::string& name) { + return m_capability_checker(name); + } }; struct Checkable diff --git a/src/network/packet_types_base.hpp b/src/network/packet_types_base.hpp index 053b8fb9a08..3a72f052845 100644 --- a/src/network/packet_types_base.hpp +++ b/src/network/packet_types_base.hpp @@ -116,8 +116,9 @@ DEFINE_CLASS(KartParametersPacket) DEFINE_FIELD(Vec3, gravity_shift) END_DEFINE_CLASS(KartParametersPacket) +/* This is only read in CL when cap(REAL_ADDON_KARTS) in LoadWorldPacket. Is it like that in other packets? */ DEFINE_CLASS(KartDataPacket) - DEFINE_FIELD(std::string, kart_type) + DEFINE_FIELD_OPTIONAL(std::string, kart_type) DEFINE_FIELD_OPTIONAL(KartParametersPacket, parameters, !kart_type.empty()) END_DEFINE_CLASS(KartDataPacket) @@ -219,15 +220,14 @@ DEFINE_DERIVED_CLASS(LinearWorldCompleteStatePacket, WorldPacket) DEFINE_VECTOR_OBJ_PTR(CheckStructurePacket, check_structure_count, check_structures) END_DEFINE_CLASS(LinearWorldCompleteStatePacket) -// 0: peer->getClientCapabilities().find("soccer_fixes") != peer->getClientCapabilities().end() DEFINE_CLASS(ScorerDataPacket) DEFINE_FIELD(uint8_t, id) DEFINE_FIELD(uint8_t, correct_goal) DEFINE_FIELD(float, time) DEFINE_FIELD(std::string, kart) DEFINE_FIELD(widestr, player) - DEFINE_FIELD_OPTIONAL(std::string, country_code, check(0)) - DEFINE_FIELD_OPTIONAL(uint8_t, handicap_level, check(0)) + DEFINE_FIELD_OPTIONAL(std::string, country_code, cap(SOCCER_FIXES)) + DEFINE_FIELD_OPTIONAL(uint8_t, handicap_level, cap(SOCCER_FIXES)) END_DEFINE_CLASS(ScoreerDataPacket) DEFINE_DERIVED_CLASS(SoccerWorldCompleteStatePacket, WorldPacket) @@ -328,8 +328,6 @@ END_DEFINE_CLASS(BackLobbyPacket) DEFINE_CLASS(ServerInfoPacket) SYNCHRONOUS(true) DEFINE_FIXED_FIELD(uint8_t, type, LE_SERVER_INFO) - //...kimden: fill this - // send with PRM_RELIABLE DEFINE_FIELD(std::string, server_name); DEFINE_FIELD(uint8_t, difficulty) DEFINE_FIELD(uint8_t, max_players) @@ -342,6 +340,7 @@ DEFINE_CLASS(ServerInfoPacket) DEFINE_FIELD(widestr16, motd) DEFINE_FIELD(bool, is_configurable) DEFINE_FIELD(bool, has_live_players) + // send with PRM_RELIABLE END_DEFINE_CLASS(ServerInfoPacket) DEFINE_CLASS(AssetsPacket) @@ -368,7 +367,7 @@ DEFINE_CLASS(PlayerKartsPacket) DEFINE_VECTOR_OBJ(std::string, players_count, karts) // I don't care about compilation for now but don't want extra macroses yet either. - DEFINE_VECTOR_OBJ/*_OPTIONAL*/(KartDataPacket, players_count, kart_data/*, IDONT_KNOW*/) // if has "real_addon_karts" in cap AND anything is sent + DEFINE_VECTOR_OBJ/*_OPTIONAL*/(KartDataPacket, players_count, kart_data/*, cap(REAL_ADDON_KARTS) && IDONTKNOW*/) // if has "real_addon_karts" in cap AND anything is sent END_DEFINE_CLASS(PlayerKartsPacket) DEFINE_CLASS(KartSelectionRequestPacket) @@ -377,9 +376,10 @@ DEFINE_CLASS(KartSelectionRequestPacket) END_DEFINE_CLASS(KartSelectionRequestPacket) DEFINE_CLASS(LiveJoinRequestPacket) + SYNCHRONOUS(true) DEFINE_FIXED_FIELD(uint8_t, type, LE_LIVE_JOIN) DEFINE_FIELD(bool, is_spectator) - DEFINE_FIELD_OPTIONAL(PlayerKartsPacket, player_karts) // is it optional? + DEFINE_FIELD_OPTIONAL(PlayerKartsPacket, player_karts, check(0)) // check client side for condition! END_DEFINE_CLASS(LiveJoinRequestPacket) DEFINE_CLASS(FinishedLoadingLiveJoinPacket) @@ -580,8 +580,8 @@ DEFINE_CLASS(InternalGoalPacket) DEFINE_FIELD(std::string, kart) DEFINE_FIELD(widestr, player) /* what follows is only since 1.1, that is, when capabilities have "soccer_fixes" */ - DEFINE_FIELD_OPTIONAL(std::string, country_code, check(0)) - DEFINE_FIELD_OPTIONAL(uint8_t, handicap, check(0)) + DEFINE_FIELD_OPTIONAL(std::string, country_code, cap(SOCCER_FIXES)) + DEFINE_FIELD_OPTIONAL(uint8_t, handicap, cap(SOCCER_FIXES)) // send with PRM_RELIABLE END_DEFINE_CLASS(InternalGoalPacket) @@ -604,4 +604,19 @@ DEFINE_CLASS(RaceFinishedAckPacket) // send with PRM_RELIABLE END_DEFINE_CLASS(RaceFinishedAckPacket) +DEFINE_CLASS(RequestBeginPacket) + DEFINE_FIXED_FIELD(uint8_t, type, LE_REQUEST_BEGIN) + // send with PRM_RELIABLE +END_DEFINE_CLASS(RequestBeginPacket) + +DEFINE_CLASS(ClientBackLobbyPacket) + DEFINE_FIXED_FIELD(uint8_t, type, LE_CLIENT_BACK_LOBBY) + // send with PRM_RELIABLE +END_DEFINE_CLASS(ClientBackLobbyPacket) + +DEFINE_CLASS(ItemConfirmationPacket) + DEFINE_FIXED_FIELD(uint8_t, type, GP_ITEM_CONFIRMATION) + DEFINE_FIELD(uint32_t, ticks) +END_DEFINE_CLASS(ItemConfirmationPacket) + // end \ No newline at end of file diff --git a/src/network/protocols/game_protocol.cpp b/src/network/protocols/game_protocol.cpp index ed3144d202d..627bb017e63 100644 --- a/src/network/protocols/game_protocol.cpp +++ b/src/network/protocols/game_protocol.cpp @@ -259,7 +259,11 @@ void GameProtocol::sendItemEventConfirmation(int ticks) { assert(NetworkConfig::get()->isClient()); NetworkString *ns = getNetworkString(5); - ns->addUInt8(GP_ITEM_CONFIRMATION).addUInt32(ticks); + + ItemConfirmationPacket packet; + packet.ticks = ticks; + packet.toNetworkString(ns); + // This message can be sent unreliable, it's not critical if it doesn't // get delivered, a future update will come through Comm::sendToServer(ns, PRM_UNRELIABLE); diff --git a/src/network/protocols/server_lobby.hpp b/src/network/protocols/server_lobby.hpp index b120def19e5..af174205878 100644 --- a/src/network/protocols/server_lobby.hpp +++ b/src/network/protocols/server_lobby.hpp @@ -53,7 +53,6 @@ class LobbySettings; class MapVoteHandler; class NetworkItemManager; class NetworkPlayerProfile; -class NetworkString; class Ranking; class SocketAddress; class STKPeer; diff --git a/src/race/race_manager.cpp b/src/race/race_manager.cpp index e2a6e0d4748..de3f185efc5 100644 --- a/src/race/race_manager.cpp +++ b/src/race/race_manager.cpp @@ -1243,7 +1243,7 @@ void RaceManager::startWatchingReplay(const std::string &track_ident, } // startWatchingReplay //--------------------------------------------------------------------------------------------- -void RaceManager::configGrandPrixResultFromNetwork(NetworkString& ns) +void RaceManager::configGrandPrixResultFromNetwork(const GPScoresPacket& packet) { setMajorMode(MAJOR_MODE_GRAND_PRIX); class NetworkGrandPrixData : public GrandPrixData @@ -1261,15 +1261,13 @@ void RaceManager::configGrandPrixResultFromNetwork(NetworkString& ns) }; NetworkGrandPrixData ngpd; - unsigned int track_size = ns.getUInt8(); - unsigned int all_track_size = ns.getUInt8(); + unsigned int track_size = packet.total_gp_tracks; + unsigned int all_track_size = packet.all_tracks_size; assert(all_track_size > 0); m_track_number = all_track_size -1; for (unsigned i = 0; i < all_track_size; i++) { - std::string t; - ns.decodeString(&t); - ngpd.addNetworkTrack(t); + ngpd.addNetworkTrack(packet.all_tracks[i]); } while (all_track_size < track_size) { @@ -1283,13 +1281,14 @@ void RaceManager::configGrandPrixResultFromNetwork(NetworkString& ns) m_reverse_track.resize(track_size, m_reverse_track[0]); m_grand_prix = ngpd; - unsigned int player_size = ns.getUInt8(); + unsigned int player_size = packet.num_players; assert(player_size == m_kart_status.size()); for (unsigned i = 0; i < player_size; i++) { - int last_score = ns.getUInt32(); - int cur_score = ns.getUInt32(); - float overall_time = ns.getFloat(); + const GPIndividualScorePacket& subpacket = packet.scores[i]; + int last_score = subpacket.last_score; + int cur_score = subpacket.cur_score; + float overall_time = subpacket.overall_time; m_kart_status[i].m_last_score = last_score; m_kart_status[i].m_score = cur_score; m_kart_status[i].m_overall_time = overall_time; diff --git a/src/race/race_manager.hpp b/src/race/race_manager.hpp index 35838c03ea2..7dbe56eb8cf 100644 --- a/src/race/race_manager.hpp +++ b/src/race/race_manager.hpp @@ -39,7 +39,6 @@ class AbstractKart; class HitProcessor; -class NetworkString; class SavedGrandPrix; class Track; @@ -927,7 +926,7 @@ class RaceManager return m_num_spare_tire_karts; } // getNumSpareTireKarts // ---------------------------------------------------------------------------------------- - void configGrandPrixResultFromNetwork(NetworkString& ns); + void configGrandPrixResultFromNetwork(const GPScoresPacket& packet); // ---------------------------------------------------------------------------------------- void clearNetworkGrandPrixResult(); // ---------------------------------------------------------------------------------------- diff --git a/src/states_screens/dialogs/race_paused_dialog.cpp b/src/states_screens/dialogs/race_paused_dialog.cpp index 2c2ed1cfd90..0f4c0c263ff 100644 --- a/src/states_screens/dialogs/race_paused_dialog.cpp +++ b/src/states_screens/dialogs/race_paused_dialog.cpp @@ -387,8 +387,8 @@ GUIEngine::EventPropagation { // back lobby NetworkString back(PROTOCOL_LOBBY_ROOM); - back.setSynchronous(true); - back.addUInt8(LobbyEvent::LE_CLIENT_BACK_LOBBY); + ClientBackLobbyPacket packet; + packet.toNetworkString(&back); Comm::sendToServer(&back, PRM_RELIABLE); } else diff --git a/src/states_screens/dialogs/server_configuration_dialog.cpp b/src/states_screens/dialogs/server_configuration_dialog.cpp index 74fe5d0a577..81666fd00f2 100644 --- a/src/states_screens/dialogs/server_configuration_dialog.cpp +++ b/src/states_screens/dialogs/server_configuration_dialog.cpp @@ -88,34 +88,43 @@ GUIEngine::EventPropagation { m_self_destroy = true; NetworkString change(PROTOCOL_LOBBY_ROOM); - change.addUInt8(LobbyEvent::LE_CONFIG_SERVER); - change.addUInt8((uint8_t)m_difficulty_widget - ->getSelection(PLAYER_ID_GAME_MASTER)); + + ConfigServerPacket packet; + packet.difficulty = (uint8_t)m_difficulty_widget->getSelection(PLAYER_ID_GAME_MASTER); switch (m_game_mode_widget->getSelection(PLAYER_ID_GAME_MASTER)) { case 0: { - change.addUInt8(3).addUInt8(0); + packet.game_mode = 3; + packet.soccer_goal_target = false; break; } case 1: { - change.addUInt8(4).addUInt8(0); + packet.game_mode = 4; + packet.soccer_goal_target = false; break; } case 2: { int v = m_more_options_spinner->getValue(); if (v == 0) - change.addUInt8(7).addUInt8(0); + { + packet.game_mode = 7; + packet.soccer_goal_target = false; + } else - change.addUInt8(8).addUInt8(0); + { + packet.game_mode = 8; + packet.soccer_goal_target = false; + } break; } case 3: { int v = m_more_options_spinner->getValue(); - change.addUInt8(6).addUInt8((uint8_t)v); + packet.game_mode = 6; + packet.soccer_goal_target = v != 0; break; } default: @@ -123,6 +132,7 @@ GUIEngine::EventPropagation break; } } + packet.toNetworkString(&change); Comm::sendToServer(&change, PRM_RELIABLE); return GUIEngine::EVENT_BLOCK; } diff --git a/src/states_screens/online/network_kart_selection.cpp b/src/states_screens/online/network_kart_selection.cpp index 8f64d40b277..532dc99c831 100644 --- a/src/states_screens/online/network_kart_selection.cpp +++ b/src/states_screens/online/network_kart_selection.cpp @@ -124,21 +124,15 @@ void NetworkKartSelectionScreen::allPlayersDone() const uint8_t kart_count = (uint8_t)m_kart_widgets.size(); NetworkString kart(PROTOCOL_LOBBY_ROOM); - if (m_live_join) - { - kart.setSynchronous(true); - kart.addUInt8(LobbyEvent::LE_LIVE_JOIN) - // not spectator - .addUInt8(0); - } - else - kart.addUInt8(LobbyEvent::LE_KART_SELECTION); - kart.addUInt8(kart_count); + + PlayerKartsPacket karts_packet; + karts_packet.players_count = kart_count; + for (unsigned n = 0; n < kart_count; n++) { - // If server recieve an invalid name, it will auto correct to a random + // If server receives an invalid name, it will auto correct to a random // kart - kart.encodeString(m_kart_widgets[n].m_kart_internal_name); + karts_packet.karts.push_back(m_kart_widgets[n].m_kart_internal_name); } NetworkConfig* nc = NetworkConfig::get(); @@ -155,9 +149,24 @@ void NetworkKartSelectionScreen::allPlayersDone() if (kp && kp->isAddon()) kart_data = KartData(kp); } - kart_data.encode(&kart); + karts_packet.kart_data.push_back(kart_data.encode()); } } + + if (m_live_join) + { + LiveJoinRequestPacket packet; + packet.is_spectator = false; + packet.player_karts = std::make_shared(karts_packet); + packet.toNetworkString(&kart); + } + else + { + KartSelectionRequestPacket packet; + packet.karts = karts_packet; + packet.toNetworkString(&kart); + } + Comm::sendToServer(&kart, PRM_RELIABLE); // ---- Switch to assign mode @@ -188,7 +197,8 @@ bool NetworkKartSelectionScreen::onEscapePressed() // server doesn't react in time we exit the server m_exit_timeout = StkTime::getMonoTimeMs() + 5000; NetworkString back(PROTOCOL_LOBBY_ROOM); - back.addUInt8(LobbyEvent::LE_CLIENT_BACK_LOBBY); + ClientBackLobbyPacket packet; + packet.toNetworkString(&back); Comm::sendToServer(&back, PRM_RELIABLE); } return false; diff --git a/src/states_screens/online/networking_lobby.cpp b/src/states_screens/online/networking_lobby.cpp index 0f5332e14bc..9975c6bcc26 100644 --- a/src/states_screens/online/networking_lobby.cpp +++ b/src/states_screens/online/networking_lobby.cpp @@ -863,7 +863,8 @@ void NetworkingLobby::eventCallback(Widget* widget, const std::string& name, { // Send a message to the server to start NetworkString start(PROTOCOL_LOBBY_ROOM); - start.addUInt8(LobbyEvent::LE_REQUEST_BEGIN); + RequestBeginPacket packet; + packet.toNetworkString(&start); Comm::sendToServer(&start, PRM_RELIABLE); } } @@ -880,10 +881,9 @@ void NetworkingLobby::eventCallback(Widget* widget, const std::string& name, if (m_client_live_joinable && cl) { NetworkString start(PROTOCOL_LOBBY_ROOM); - start.setSynchronous(true); - start.addUInt8(LobbyEvent::LE_LIVE_JOIN) - // is spectating - .addUInt8(1); + LiveJoinRequestPacket packet; + packet.is_spectator = true; + packet.toNetworkString(&start); Comm::sendToServer(&start, PRM_RELIABLE); return; } diff --git a/src/states_screens/online/tracks_screen.cpp b/src/states_screens/online/tracks_screen.cpp index 35ddac920ef..fde29a5a1ec 100644 --- a/src/states_screens/online/tracks_screen.cpp +++ b/src/states_screens/online/tracks_screen.cpp @@ -734,36 +734,45 @@ void TracksScreen::voteForPlayer() UserConfigParams::m_random_arena_item = m_reversed->getState(); NetworkString vote(PROTOCOL_LOBBY_ROOM); - vote.addUInt8(LobbyEvent::LE_VOTE); + + PeerVotePacket packet; + core::stringw player_name; if (PlayerManager::getCurrentPlayer()) player_name = PlayerManager::getCurrentPlayer()->getName(); - vote.encodeString(player_name); + + packet.player_name = player_name; + packet.track_name = m_selected_track->getIdent(); + if (RaceManager::get()->getMinorMode() == RaceManager::MINOR_MODE_FREE_FOR_ALL) { - vote.encodeString(m_selected_track->getIdent()) - .addUInt8(0).addUInt8(m_reversed->getState() ? 1 : 0); + packet.num_laps = 0; + packet.is_reverse = m_reversed->getState(); } else if (RaceManager::get()->getMinorMode() == RaceManager::MINOR_MODE_CAPTURE_THE_FLAG) { - vote.encodeString(m_selected_track->getIdent()) - .addUInt8(0).addUInt8(0); + packet.num_laps = 0; + packet.is_reverse = false; } else { - vote.encodeString(m_selected_track->getIdent()) - .addUInt8(m_laps->getValue()) - .addUInt8(m_reversed->getState() ? 1 : 0); + packet.num_laps = m_laps->getValue(); + packet.is_reverse = m_reversed->getState(); } + if (auto lp = LobbyProtocol::get()) { - vote.reset(); - vote.skip(2); - PeerVote pvote(vote); + PeerVote pvote(packet); lp->addVote(STKHost::get()->getMyHostId(), pvote); } - Comm::sendToServer(&vote, PRM_RELIABLE); + else + { + // kimden: I'm not sure if this is the right thing, but seems fine. + // Not encoding packet to netstring before if just in case, too. + packet.toNetworkString(&vote); + Comm::sendToServer(&vote, PRM_RELIABLE); + } } // voteForPlayer // ----------------------------------------------------------------------------- diff --git a/src/utils/chat_manager.cpp b/src/utils/chat_manager.cpp index d076cd7a04f..3f9f5abd702 100644 --- a/src/utils/chat_manager.cpp +++ b/src/utils/chat_manager.cpp @@ -230,8 +230,9 @@ void ChatManager::handleNormalChatMessage(std::shared_ptr peer, message = g_blue_team + message; NetworkString* chat = getLobby()->getNetworkString(); - chat->setSynchronous(true); - chat->addUInt8(LobbyEvent::LE_CHAT).encodeString16(StringUtils::utf8ToWide(message)); + ChatPacket packet; + packet.message = StringUtils::utf8ToWide(message); + packet.toNetworkString(chat); STKHost::get()->sendPacketToAllPeersWith( std::bind(&ChatManager::shouldMessageBeSent, diff --git a/src/utils/lobby_asset_manager.hpp b/src/utils/lobby_asset_manager.hpp index a4bd9c42456..12a85f6b39c 100644 --- a/src/utils/lobby_asset_manager.hpp +++ b/src/utils/lobby_asset_manager.hpp @@ -30,7 +30,6 @@ #include #include -class NetworkString; class ServerLobby; class STKPeer; diff --git a/src/utils/lobby_gp_manager.hpp b/src/utils/lobby_gp_manager.hpp index 9ebf28ce736..9127eeba82e 100644 --- a/src/utils/lobby_gp_manager.hpp +++ b/src/utils/lobby_gp_manager.hpp @@ -27,7 +27,6 @@ #include class NetworkPlayerProfile; -class NetworkString; class GPScoring; struct GPScore diff --git a/src/utils/lobby_settings.cpp b/src/utils/lobby_settings.cpp index f57377640da..28246146f8c 100644 --- a/src/utils/lobby_settings.cpp +++ b/src/utils/lobby_settings.cpp @@ -555,7 +555,7 @@ void LobbySettings::applyRestrictionsOnWinnerVote(PeerVote* winner_vote) const } // applyRestrictionsOnWinnerVote //----------------------------------------------------------------------------- -DefaultVotePacket LobbySettings::encodeDefaultVote(NetworkString* ns) const +DefaultVotePacket LobbySettings::encodeDefaultVote() const { DefaultVotePacket packet; packet.winner_peer_id = m_winner_peer_id; diff --git a/src/utils/lobby_settings.hpp b/src/utils/lobby_settings.hpp index c7c182cae08..c0d6db2d59a 100644 --- a/src/utils/lobby_settings.hpp +++ b/src/utils/lobby_settings.hpp @@ -29,7 +29,6 @@ class GameSetup; class KartElimination; class LobbyAssetManager; class LobbyQueues; -class NetworkString; class PeerVote; class STKPeer; class Tournament; From b80b8548adae0f0dab9e6d473b667c2ddde1b261 Mon Sep 17 00:00:00 2001 From: kimden <23140380+kimden@users.noreply.github.com> Date: Wed, 9 Apr 2025 01:59:19 +0400 Subject: [PATCH 10/34] More packets, some macro redefinitions --- src/modes/linear_world.cpp | 30 ++- src/modes/linear_world.hpp | 6 +- src/network/game_setup.cpp | 1 + src/network/game_setup.hpp | 1 + src/network/kart_data.cpp | 9 +- src/network/packet_types.cpp | 167 +++++++++++++++ src/network/packet_types.hpp | 196 ++++------------- src/network/packet_types_base.hpp | 202 +++++++++--------- src/network/protocols/game_event_types.hpp | 45 ++++ .../protocols/game_events_protocol.hpp | 11 - src/network/protocols/game_protocol.hpp | 8 - src/network/protocols/server_lobby.cpp | 66 +++--- src/network/protocols/server_lobby.hpp | 2 +- src/network/stk_peer.cpp | 2 +- src/network/stk_peer.hpp | 5 +- 15 files changed, 416 insertions(+), 335 deletions(-) create mode 100644 src/network/packet_types.cpp create mode 100644 src/network/protocols/game_event_types.hpp diff --git a/src/modes/linear_world.cpp b/src/modes/linear_world.cpp index 79ee102ad9b..1bb33051af0 100644 --- a/src/modes/linear_world.cpp +++ b/src/modes/linear_world.cpp @@ -1215,9 +1215,9 @@ std::pair LinearWorld::getGameStartedProgress() const } // getGameStartedProgress // ---------------------------------------------------------------------------- -KartInfoPacket LinearWorld::KartInfo::saveCompleteState() +KartInfoInGamePacket LinearWorld::KartInfo::saveCompleteState() { - KartInfoPacket packet; + KartInfoInGamePacket packet; packet.finished_laps = m_finished_laps; packet.ticks_at_last_lap = m_ticks_at_last_lap; packet.lap_start_ticks = m_lap_start_ticks; @@ -1228,7 +1228,7 @@ KartInfoPacket LinearWorld::KartInfo::saveCompleteState() } // saveCompleteState // ---------------------------------------------------------------------------- -void LinearWorld::KartInfo::restoreCompleteState(const KartInfoPacket& packet) +void LinearWorld::KartInfo::restoreCompleteState(const KartInfoInGamePacket& packet) { m_finished_laps = packet.finished_laps; m_ticks_at_last_lap = packet.ticks_at_last_lap; @@ -1365,27 +1365,23 @@ void LinearWorld::updateCheckLinesServer(int check_id, int kart_id) // ---------------------------------------------------------------------------- /* Synchronize with server from the above data. */ -void LinearWorld::updateCheckLinesClient(const BareNetworkString& b) +void LinearWorld::updateCheckLinesClient(const InsideChecklinePacket& packet) { // Reserve for future auto checkline correction - //int check_id = b.getUInt8(); - b.getUInt8(); - int kart_id = b.getUInt8(); - - int8_t finished_laps = b.getUInt8(); - m_kart_info.at(kart_id).m_finished_laps = finished_laps; - - int8_t ltcl = b.getUInt8(); - m_kart_track_sector.at(kart_id)->setLastTriggeredCheckline(ltcl); + //int check_id = packet.check_id; + + int kart_id = packet.kart_id; + m_kart_info.at(kart_id).m_finished_laps = packet.finished_laps; + m_kart_track_sector.at(kart_id)->setLastTriggeredCheckline(packet.last_triggered_checkline); - m_fastest_lap_ticks = b.getUInt32(); - b.decodeStringW(&m_fastest_lap_kart_name); + m_fastest_lap_ticks = packet.fastest_lap_ticks; + m_fastest_lap_kart_name = packet.fastest_kart_name; - const unsigned cc = b.getUInt8(); + const unsigned cc = packet.check_structure_count; if (cc != Track::getCurrentTrack()->getCheckManager()->getCheckStructureCount()) return; for (unsigned i = 0; i < cc; i++) - Track::getCurrentTrack()->getCheckManager()->getCheckStructure(i)->restoreIsActive(kart_id, b); + Track::getCurrentTrack()->getCheckManager()->getCheckStructure(i)->restoreIsActive(kart_id, packet.check_active[i]); } // updateCheckLinesClient diff --git a/src/modes/linear_world.hpp b/src/modes/linear_world.hpp index f4cfa4ca634..8ac7305e45a 100644 --- a/src/modes/linear_world.hpp +++ b/src/modes/linear_world.hpp @@ -135,9 +135,9 @@ class LinearWorld : public WorldWithRank m_warn_issued = 0; } // reset // -------------------------------------------------------------------- - KartInfoPacket saveCompleteState(); + KartInfoInGamePacket saveCompleteState(); // -------------------------------------------------------------------- - void restoreCompleteState(const KartInfoPacket& packet); + void restoreCompleteState(const KartInfoInGamePacket& packet); }; // ------------------------------------------------------------------------ @@ -282,7 +282,7 @@ class LinearWorld : public WorldWithRank // ------------------------------------------------------------------------ void updateCheckLinesServer(int check_id, int kart_id); // ------------------------------------------------------------------------ - void updateCheckLinesClient(const BareNetworkString& b); + void updateCheckLinesClient(const InsideChecklinePacket& packet); // ------------------------------------------------------------------------ void handleServerCheckStructureCount(unsigned count); // ------------------------------------------------------------------------ diff --git a/src/network/game_setup.cpp b/src/network/game_setup.cpp index 41be5e30728..57ecd00c663 100644 --- a/src/network/game_setup.cpp +++ b/src/network/game_setup.cpp @@ -24,6 +24,7 @@ #include "network/network_config.hpp" #endif #include "network/network_player_profile.hpp" +#include "network/packet_types.hpp" #include "network/peer_vote.hpp" #include "network/protocols/server_lobby.hpp" #include "network/server_config.hpp" diff --git a/src/network/game_setup.hpp b/src/network/game_setup.hpp index 140e2d0a26f..2fcca78c933 100644 --- a/src/network/game_setup.hpp +++ b/src/network/game_setup.hpp @@ -33,6 +33,7 @@ class NetworkPlayerProfile; class PeerVote; +class ServerInfoPacket; // ============================================================================ /*! \class GameSetup diff --git a/src/network/kart_data.cpp b/src/network/kart_data.cpp index f3ecefc14de..c90a9fd34a2 100644 --- a/src/network/kart_data.cpp +++ b/src/network/kart_data.cpp @@ -26,7 +26,10 @@ KartData::KartData(const KartProperties* kp) // ---------------------------------------------------------------------------- KartData::KartData(const KartDataPacket& packet) { - m_kart_type = packet.kart_type; + m_kart_type = ""; + if (packet.kart_type) + m_kart_type = *packet.kart_type; + if (!m_kart_type.empty()) { m_width = packet.parameters->width; @@ -46,7 +49,7 @@ KartData::KartData(const KartDataPacket& packet) KartDataPacket KartData::encode() const { KartDataPacket packet; - packet.kart_type = m_kart_type; + packet.kart_type = std::make_shared(m_kart_type); packet.parameters = {}; if (!m_kart_type.empty()) @@ -60,4 +63,4 @@ KartDataPacket KartData::encode() const } return packet; -} // encode(BareNetworkString*) +} // encode() diff --git a/src/network/packet_types.cpp b/src/network/packet_types.cpp new file mode 100644 index 00000000000..1cfc2f9ae3b --- /dev/null +++ b/src/network/packet_types.cpp @@ -0,0 +1,167 @@ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2025 kimden +// +// 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, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#include "network/packet_types.hpp" +#include "network/remote_kart_info.hpp" + +//---------------------- To NetworkString ------------------------------------- + +#define DEFINE_CLASS(Name) \ +inline void Name::toNetworkString(NetworkString* ns) const \ +{ + +#define DEFINE_DERIVED_CLASS(Name, Parent) DEFINE_CLASS(Name) + +#define SYNCHRONOUS(Value) \ + ns->setSynchronous(Value); + +#define AUX_VAR(Type, Var) + +#define DEFINE_FIELD(Type, Var) \ + ns->encode(Var); + +#define DEFINE_FIELD_PACKET(Type, Var) \ + Var.toNetworkString(ns); + +#define DEFINE_FIELD_PTR(Type, Var) \ + if (Var) \ + ns->encode(*Var); + +// We send it if it exists, and receive only if the condition is true +#define DEFINE_FIELD_OPTIONAL(Type, Var, Condition) \ + if (Var) \ + ns->encode(*Var); + +#define DEFINE_TYPE(Type, Var, Value) \ + ns->encode(Value); + +#define DEFINE_VECTOR(Type, Size, Value) \ + for (unsigned Value##_cnt = 0; Value##_cnt < Size; ++Value##_cnt) { \ + ns->encode(Value[Value##_cnt]); \ + } + +#define DEFINE_VECTOR_PACKET(Type, Size, Value) \ + for (unsigned Value##_cnt = 0; Value##_cnt < Size; ++Value##_cnt) { \ + Value[Value##_cnt].toNetworkString(ns); \ + } + +#define DEFINE_VECTOR_PACKET_PTR(Type, Size, Value) \ + for (unsigned Value##_cnt = 0; Value##_cnt < Size; ++Value##_cnt) { \ + Value[Value##_cnt]->toNetworkString(ns); \ + } + +#define RELIABLE() + +#define END_DEFINE_CLASS(Name) \ +} + +#include "network/packet_types_base.hpp" +#undef DEFINE_CLASS +#undef DEFINE_DERIVED_CLASS +#undef SYNCHRONOUS +#undef AUX_VAR +#undef DEFINE_FIELD +#undef DEFINE_FIELD_PACKET +#undef DEFINE_FIELD_PTR +#undef DEFINE_TYPE +#undef DEFINE_FIELD_OPTIONAL +#undef DEFINE_VECTOR +#undef DEFINE_VECTOR_PACKET +#undef DEFINE_VECTOR_PACKET_PTR +#undef RELIABLE +#undef END_DEFINE_CLASS + + + + +//---------------------- From NetworkString ----------------------------------- + +#define DEFINE_CLASS(Name) \ +inline void Name::fromNetworkString(NetworkString* ns) \ +{ + +#define DEFINE_DERIVED_CLASS(Name, Parent) DEFINE_CLASS(Name) + +#define SYNCHRONOUS(Value) + +#define AUX_VAR(Type, Var) + +#define DEFINE_FIELD(Type, Var) \ + ns->decode(Var); + +#define DEFINE_FIELD_PACKET(Type, Var) \ + Var.fromNetworkString(ns); + +// Same as optional but unconditional +#define DEFINE_FIELD_PTR(Type, Var) \ + Type temp_##Var; \ + ns->decode(temp_##Var); \ + Var = std::make_shared(temp_##Var); \ + +// We send it if it exists, and receive only if the condition is true +#define DEFINE_FIELD_OPTIONAL(Type, Var, Condition) \ + if (Condition) { \ + Type temp_##Var; \ + ns->decode(temp_##Var); \ + Var = std::make_shared(temp_##Var); \ + } + +#define DEFINE_TYPE(Type, Var, Value) + +#define DEFINE_VECTOR(Type, Size, Var) \ + Var.resize(Size); \ + for (unsigned Var##_cnt = 0; Var##_cnt < Size; ++Var##_cnt) { \ + ns->decode(Var[Var##_cnt]); \ + } + +#define DEFINE_VECTOR_PACKET(Type, Size, Var) \ + Var.resize(Size); \ + for (unsigned Var##_cnt = 0; Var##_cnt < Size; ++Var##_cnt) { \ + Var[Var##_cnt].fromNetworkString(ns); \ + } + +#define DEFINE_VECTOR_PACKET_PTR(Type, Size, Var) \ + Var.resize(Size); \ + for (unsigned Var##_cnt = 0; Var##_cnt < Size; ++Var##_cnt) { \ + Type temp_##Var; \ + temp_##Var.fromNetworkString(ns); \ + Var[Var##_cnt] = std::make_shared(temp_##Var); \ + } + +#define RELIABLE() + +#define END_DEFINE_CLASS(Name) \ +} + +#include "network/packet_types_base.hpp" +#undef DEFINE_CLASS +#undef DEFINE_DERIVED_CLASS +#undef SYNCHRONOUS +#undef AUX_VAR +#undef DEFINE_FIELD +#undef DEFINE_FIELD_PACKET +#undef DEFINE_FIELD_PTR +#undef DEFINE_TYPE +#undef DEFINE_FIELD_OPTIONAL +#undef DEFINE_VECTOR +#undef DEFINE_VECTOR_PACKET +#undef DEFINE_VECTOR_PACKET_PTR +#undef RELIABLE +#undef END_DEFINE_CLASS + +//---------------------- End -------------------------------------------------- \ No newline at end of file diff --git a/src/network/packet_types.hpp b/src/network/packet_types.hpp index 6e180e27fb3..f9269cb850f 100644 --- a/src/network/packet_types.hpp +++ b/src/network/packet_types.hpp @@ -20,9 +20,13 @@ #define PACKET_TYPES_HPP #include "network/network_string.hpp" +#include "network/protocols/game_event_types.hpp" #include "utils/cpp2011.hpp" +enum KartTeam: int8_t; + #include +#include /** * IMPORTANT! @@ -100,21 +104,6 @@ namespace const std::string REAL_ADDON_KARTS = "real_addon_karts"; } - -struct Packet -{ - std::function m_capability_checker; - - // Needed to dynamic_cast - virtual ~Packet() {} - virtual void toNetworkString(NetworkString* ns) const {} - virtual void fromNetworkString(NetworkString* ns) {} - - bool cap(const std::string& name) { - return m_capability_checker(name); - } -}; - struct Checkable { private: @@ -130,158 +119,47 @@ struct Checkable } }; +struct Packet: public Checkable +{ + std::function m_capability_checker; + + // Needed to dynamic_cast + virtual ~Packet() {} + virtual void toNetworkString(NetworkString* ns) const {} + virtual void fromNetworkString(NetworkString* ns) {} + virtual bool isSynchronous() { return false; } + bool cap(const std::string& name) { return m_capability_checker(name); } +}; + +// temp +constexpr int IDONT_KNOW = 0; + //---------------------- Initialization --------------------------------------- #define DEFINE_CLASS(Name) \ -struct Name: public Checkable, public Packet { \ +struct Name: public Packet { \ public: \ virtual void toNetworkString(NetworkString* ns) const OVERRIDE; \ virtual void fromNetworkString(NetworkString* ns) OVERRIDE; #define DEFINE_DERIVED_CLASS(Name, Parent) \ -struct Name: public Checkable, public Parent { \ +struct Name: public Parent { \ public: \ virtual void toNetworkString(NetworkString* ns) const OVERRIDE; \ virtual void fromNetworkString(NetworkString* ns) OVERRIDE; -#define SYNCHRONOUS(Value) bool isSynchronous() { return Value; } -#define AUX_VAR(Type, Var) Type Var; -#define DEFINE_FIELD(Type, Var) Type Var; -#define DEFINE_FIELD_PTR(Type, Var) std::shared_ptr Var; +#define SYNCHRONOUS(Value) bool isSynchronous() OVERRIDE { return Value; } +#define AUX_VAR(Type, Var) Type Var; +#define DEFINE_FIELD(Type, Var) Type Var; +#define DEFINE_FIELD_PACKET(Type, Var) Type Var; +#define DEFINE_FIELD_PTR(Type, Var) std::shared_ptr Var; #define DEFINE_FIELD_OPTIONAL(Type, Var, Condition) std::shared_ptr Var; -#define DEFINE_FIXED_FIELD(Type, Var, Value) Type Var; -#define DEFINE_VECTOR(Type, Size, Var) std::vector Var; -#define DEFINE_VECTOR_OBJ(Type, Size, Var) std::vector Var; -#define DEFINE_VECTOR_OBJ_PTR(Type, Size, Var) std::vector> Var; -#define END_DEFINE_CLASS(Name) }; - -#include "network/packet_types_base.hpp" -#undef DEFINE_CLASS -#undef DEFINE_DERIVED_CLASS -#undef SYNCHRONOUS -#undef AUX_VAR -#undef DEFINE_FIELD -#undef DEFINE_FIELD_PTR -#undef DEFINE_FIXED_FIELD -#undef DEFINE_FIELD_OPTIONAL -#undef DEFINE_VECTOR -#undef DEFINE_VECTOR_OBJ -#undef DEFINE_VECTOR_OBJ_PTR -#undef END_DEFINE_CLASS - -//---------------------- To NetworkString ------------------------------------- - -#define DEFINE_CLASS(Name) \ -inline void Name::toNetworkString(NetworkString* ns) const \ -{ - -#define DEFINE_DERIVED_CLASS(Name, Parent) DEFINE_CLASS(Name) - -#define SYNCHRONOUS(Value) \ - ns->setSynchronous(Value); - -#define AUX_VAR(Type, Var) - -#define DEFINE_FIELD(Type, Var) \ - ns->encode(Var); - -#define DEFINE_FIELD_PTR(Type, Var) \ - if (Var) \ - ns->encode(*Var); - -// We send it if it exists, and receive only if the condition is true -#define DEFINE_FIELD_OPTIONAL(Type, Var, Condition) \ - if (Var) \ - ns->encode(*Var); - -#define DEFINE_FIXED_FIELD(Type, Var, Value) \ - ns->encode(Value); - -#define DEFINE_VECTOR(Type, Size, Value) \ - for (unsigned Value##_cnt = 0; Value##_cnt < Size; ++Value##_cnt) { \ - ns->encode(Value[Value##_cnt]); \ - } - -#define DEFINE_VECTOR_OBJ(Type, Size, Value) \ - for (unsigned Value##_cnt = 0; Value##_cnt < Size; ++Value##_cnt) { \ - Value[Value##_cnt].toNetworkString(ns); \ - } - -#define DEFINE_VECTOR_OBJ_PTR(Type, Size, Value) \ - for (unsigned Value##_cnt = 0; Value##_cnt < Size; ++Value##_cnt) { \ - Value[Value##_cnt]->toNetworkString(ns); \ - } - -#define END_DEFINE_CLASS(Name) \ -} - -#include "network/packet_types_base.hpp" -#undef DEFINE_CLASS -#undef DEFINE_DERIVED_CLASS -#undef SYNCHRONOUS -#undef AUX_VAR -#undef DEFINE_FIELD -#undef DEFINE_FIELD_PTR -#undef DEFINE_FIXED_FIELD -#undef DEFINE_FIELD_OPTIONAL -#undef DEFINE_VECTOR -#undef DEFINE_VECTOR_OBJ -#undef DEFINE_VECTOR_OBJ_PTR -#undef END_DEFINE_CLASS - -//---------------------- From NetworkString ----------------------------------- - -#define DEFINE_CLASS(Name) \ -inline void Name::fromNetworkString(NetworkString* ns) \ -{ - -#define DEFINE_DERIVED_CLASS(Name, Parent) DEFINE_CLASS(Name) - -#define SYNCHRONOUS(Value) - -#define AUX_VAR(Type, Var) - -#define DEFINE_FIELD(Type, Var) \ - ns->decode(Var); - -// Same as optional but unconditional -#define DEFINE_FIELD_PTR(Type, Var) \ - Type temp_##Var; \ - ns->decode(temp_##Var); \ - Var = std::make_shared(temp_##Var); \ - -// We send it if it exists, and receive only if the condition is true -#define DEFINE_FIELD_OPTIONAL(Type, Var, Condition) \ - if (Condition) { \ - Type temp_##Var; \ - ns->decode(temp_##Var); \ - Var = std::make_shared(temp_##Var); \ - } - -#define DEFINE_FIXED_FIELD(Type, Var, Value) - -#define DEFINE_VECTOR(Type, Size, Var) \ - Var.resize(Size); \ - for (unsigned Var##_cnt = 0; Var##_cnt < Size; ++Var##_cnt) { \ - ns->decode(Var[Var##_cnt]); \ - } - -#define DEFINE_VECTOR_OBJ(Type, Size, Var) \ - Var.resize(Size); \ - for (unsigned Var##_cnt = 0; Var##_cnt < Size; ++Var##_cnt) { \ - Var[Var##_cnt].fromNetworkString(ns); \ - } - -#define DEFINE_VECTOR_OBJ_PTR(Type, Size, Var) \ - Var.resize(Size); \ - for (unsigned Var##_cnt = 0; Var##_cnt < Size; ++Var##_cnt) { \ - Type temp_##Var; \ - temp_##Var.fromNetworkString(ns); \ - Var[Var##_cnt] = std::make_shared(temp_##Var); \ - } - -#define END_DEFINE_CLASS(Name) \ -} +#define DEFINE_TYPE(Type, Var, Value) Type Var; +#define DEFINE_VECTOR(Type, Size, Var) std::vector Var; +#define DEFINE_VECTOR_PACKET(Type, Size, Var) std::vector Var; +#define DEFINE_VECTOR_PACKET_PTR(Type, Size, Var) std::vector> Var; +#define RELIABLE() +#define END_DEFINE_CLASS(Name) }; #include "network/packet_types_base.hpp" #undef DEFINE_CLASS @@ -289,14 +167,16 @@ inline void Name::fromNetworkString(NetworkString* ns) \ #undef SYNCHRONOUS #undef AUX_VAR #undef DEFINE_FIELD +#undef DEFINE_FIELD_PACKET #undef DEFINE_FIELD_PTR -#undef DEFINE_FIXED_FIELD +#undef DEFINE_TYPE #undef DEFINE_FIELD_OPTIONAL #undef DEFINE_VECTOR -#undef DEFINE_VECTOR_OBJ -#undef DEFINE_VECTOR_OBJ_PTR +#undef DEFINE_VECTOR_PACKET +#undef DEFINE_VECTOR_PACKET_PTR +#undef RELIABLE #undef END_DEFINE_CLASS -//---------------------- End -------------------------------------------------- +/* Don't forget to send RELIABLE() packets with PRM_RELIABLE */ #endif // PACKET_TYPES_HPP diff --git a/src/network/packet_types_base.hpp b/src/network/packet_types_base.hpp index 3a72f052845..194610975d9 100644 --- a/src/network/packet_types_base.hpp +++ b/src/network/packet_types_base.hpp @@ -49,9 +49,6 @@ using widestr = irr::core::stringw; using widestr16 = irr::core::stringw; // but encodeString16 -// temp -constexpr int IDONT_KNOW = 0; - // Note that bools are encoded using int8_t DEFINE_CLASS(PlayerListProfilePacket) @@ -67,10 +64,10 @@ END_DEFINE_CLASS(PlayerListProfilePacket) DEFINE_CLASS(PlayerListPacket) SYNCHRONOUS(true) - DEFINE_FIXED_FIELD(uint8_t, type, LE_UPDATE_PLAYER_LIST) + DEFINE_TYPE(uint8_t, type, LE_UPDATE_PLAYER_LIST) DEFINE_FIELD(bool, game_started) DEFINE_FIELD(uint8_t, all_profiles_size) - DEFINE_VECTOR_OBJ(PlayerListProfilePacket, all_profiles_size, all_profiles) + DEFINE_VECTOR_PACKET(PlayerListProfilePacket, all_profiles_size, all_profiles) END_DEFINE_CLASS(PlayerListPacket) DEFINE_CLASS(EncodedSinglePlayerPacket) @@ -118,20 +115,25 @@ END_DEFINE_CLASS(KartParametersPacket) /* This is only read in CL when cap(REAL_ADDON_KARTS) in LoadWorldPacket. Is it like that in other packets? */ DEFINE_CLASS(KartDataPacket) - DEFINE_FIELD_OPTIONAL(std::string, kart_type) - DEFINE_FIELD_OPTIONAL(KartParametersPacket, parameters, !kart_type.empty()) + DEFINE_FIELD_OPTIONAL(std::string, kart_type, check(0)) /* I have no idea when */ + DEFINE_FIELD_OPTIONAL(KartParametersPacket, parameters, check(1) && check(0)) /* check(1) = !kart_type.empty()*/ END_DEFINE_CLASS(KartDataPacket) +DEFINE_CLASS(MultipleKartDataPacket) + AUX_VAR(uint8_t, players_size) + DEFINE_VECTOR_PACKET(KartDataPacket, players_size, players_kart_data) +END_DEFINE_CLASS(MultipleKartDataPacket) + DEFINE_CLASS(LoadWorldPacket) SYNCHRONOUS(true) - DEFINE_FIXED_FIELD(uint8_t, type, LE_LOAD_WORLD) + DEFINE_TYPE(uint8_t, type, LE_LOAD_WORLD) DEFINE_FIELD(DefaultVotePacket, default_vote) DEFINE_FIELD(bool, live_join) - DEFINE_FIELD(uint8_t, players_size) - DEFINE_VECTOR_OBJ(EncodedSinglePlayerPacket, players_size, all_players) + DEFINE_FIELD(uint8_t, players_size) + DEFINE_VECTOR_PACKET(EncodedSinglePlayerPacket, players_size, all_players) DEFINE_FIELD(uint32_t, item_seed) DEFINE_FIELD_OPTIONAL(BattleInfoPacket, battle_info, check(0)) // RaceManager::get()->isBattleMode() - DEFINE_VECTOR_OBJ(KartDataPacket, players_size, players_kart_data) + DEFINE_FIELD_OPTIONAL(MultipleKartDataPacket, karts_data, cap(REAL_ADDON_KARTS)) END_DEFINE_CLASS(LoadWorldPacket) DEFINE_CLASS(PlacementPacket) @@ -159,17 +161,17 @@ DEFINE_CLASS(NimCompleteStatePacket) DEFINE_FIELD(uint32_t, ticks_since_start) DEFINE_FIELD(uint32_t, switch_ticks) DEFINE_FIELD(uint32_t, all_items_size) - DEFINE_VECTOR_OBJ(ItemCompleteStatePacket, all_items_size, all_items) + DEFINE_VECTOR_PACKET(ItemCompleteStatePacket, all_items_size, all_items) END_DEFINE_CLASS(NimCompleteStatePacket) -DEFINE_CLASS(KartInfoPacket) +DEFINE_CLASS(KartInfoInGamePacket) DEFINE_FIELD(uint32_t, finished_laps) DEFINE_FIELD(uint32_t, ticks_at_last_lap) DEFINE_FIELD(uint32_t, lap_start_ticks) DEFINE_FIELD(float, estimated_finish) DEFINE_FIELD(float, overall_distance) DEFINE_FIELD(float, wrong_way_timer) -END_DEFINE_CLASS(KartInfoPacket) +END_DEFINE_CLASS(KartInfoInGamePacket) DEFINE_CLASS(TrackSectorPacket) DEFINE_FIELD(uint32_t, current_graph_node) @@ -192,7 +194,7 @@ END_DEFINE_CLASS(CheckStructureSubPacket) DEFINE_DERIVED_CLASS(CheckStructurePacket, CheckPacket) AUX_VAR(uint32_t, karts_count) - DEFINE_VECTOR_OBJ(CheckStructureSubPacket, karts_count, player_check_state) + DEFINE_VECTOR_PACKET(CheckStructureSubPacket, karts_count, player_check_state) END_DEFINE_CLASS(CheckStructurePacket) DEFINE_CLASS(CheckLineSubPacket) @@ -202,7 +204,7 @@ END_DEFINE_CLASS(CheckLineSubPacket) DEFINE_DERIVED_CLASS(CheckLinePacket, CheckPacket) AUX_VAR(uint32_t, karts_count) DEFINE_FIELD_PTR(CheckStructurePacket, check_structure_packet) - DEFINE_VECTOR_OBJ(CheckLineSubPacket, karts_count, subpackets) + DEFINE_VECTOR_PACKET(CheckLineSubPacket, karts_count, subpackets) END_DEFINE_CLASS(CheckLinePacket) DEFINE_CLASS(WorldPacket) @@ -213,11 +215,11 @@ DEFINE_DERIVED_CLASS(LinearWorldCompleteStatePacket, WorldPacket) AUX_VAR(uint32_t, track_sectors_count) DEFINE_FIELD(uint32_t, fastest_lap_ticks) DEFINE_FIELD(float, distance_increase) - DEFINE_VECTOR_OBJ(PlacementPacket, karts_count, kart_placements) - DEFINE_VECTOR_OBJ(KartInfoPacket, karts_count, kart_infos) - DEFINE_VECTOR_OBJ(TrackSectorPacket, track_sectors_count, track_sectors) + DEFINE_VECTOR_PACKET(PlacementPacket, karts_count, kart_placements) + DEFINE_VECTOR_PACKET(KartInfoInGamePacket, karts_count, kart_infos) + DEFINE_VECTOR_PACKET(TrackSectorPacket, track_sectors_count, track_sectors) DEFINE_FIELD(uint8_t, check_structure_count) - DEFINE_VECTOR_OBJ_PTR(CheckStructurePacket, check_structure_count, check_structures) + DEFINE_VECTOR_PACKET_PTR(CheckStructurePacket, check_structure_count, check_structures) END_DEFINE_CLASS(LinearWorldCompleteStatePacket) DEFINE_CLASS(ScorerDataPacket) @@ -228,13 +230,13 @@ DEFINE_CLASS(ScorerDataPacket) DEFINE_FIELD(widestr, player) DEFINE_FIELD_OPTIONAL(std::string, country_code, cap(SOCCER_FIXES)) DEFINE_FIELD_OPTIONAL(uint8_t, handicap_level, cap(SOCCER_FIXES)) -END_DEFINE_CLASS(ScoreerDataPacket) +END_DEFINE_CLASS(ScorerDataPacket) DEFINE_DERIVED_CLASS(SoccerWorldCompleteStatePacket, WorldPacket) DEFINE_FIELD(uint32_t, red_scorers_count) - DEFINE_VECTOR_OBJ(ScorerDataPacket, red_scorers_count, red_scorers) + DEFINE_VECTOR_PACKET(ScorerDataPacket, red_scorers_count, red_scorers) DEFINE_FIELD(uint32_t, blue_scorers_count) - DEFINE_VECTOR_OBJ(ScorerDataPacket, blue_scorers_count, blue_scorers) + DEFINE_VECTOR_PACKET(ScorerDataPacket, blue_scorers_count, blue_scorers) DEFINE_FIELD(uint32_t, reser_ball_ticks) DEFINE_FIELD(uint32_t, ticks_back_to_own_goal) END_DEFINE_CLASS(SoccerWorldCompleteStatePacket) @@ -259,13 +261,13 @@ END_DEFINE_CLASS(WorldCompleteStatePacket) DEFINE_CLASS(InsideGameInfoPacket) DEFINE_FIELD(uint8_t, players_size) - DEFINE_VECTOR_OBJ(EncodedSinglePlayerPacket, players_size, all_players) - DEFINE_VECTOR_OBJ(KartDataPacket, players_size, players_kart_data) + DEFINE_VECTOR_PACKET(EncodedSinglePlayerPacket, players_size, all_players) + DEFINE_VECTOR_PACKET(KartDataPacket, players_size, players_kart_data) END_DEFINE_CLASS(InsideGameInfoPacket) DEFINE_CLASS(LiveJoinPacket) SYNCHRONOUS(true) - DEFINE_FIXED_FIELD(uint8_t, type, LE_LIVE_JOIN_ACK) + DEFINE_TYPE(uint8_t, type, LE_LIVE_JOIN_ACK) DEFINE_FIELD(uint64_t, client_starting_time) DEFINE_FIELD(uint8_t, check_count); DEFINE_FIELD(uint64_t, live_join_start_time) @@ -275,59 +277,58 @@ DEFINE_CLASS(LiveJoinPacket) DEFINE_FIELD_OPTIONAL(InsideGameInfoPacket, inside_info, check(0)) // RaceManager::get()->supportsLiveJoining() END_DEFINE_CLASS(LiveJoinPacket) - DEFINE_CLASS(ChatPacket) SYNCHRONOUS(true) - DEFINE_FIXED_FIELD(uint8_t, type, LE_CHAT) + DEFINE_TYPE(uint8_t, type, LE_CHAT) DEFINE_FIELD(widestr16, message) // use encodeString16 ! max len is 360 - DEFINE_FIELD_OPTIONAL(KartTeam, kart_team) // KartTeam is uint8_t - // send with PRM_RELIABLE + DEFINE_FIELD_OPTIONAL(KartTeam, kart_team, check(0)) /* KartTeam is uint8_t, I have no idea when */ + RELIABLE() END_DEFINE_CLASS(ChatPacket) DEFINE_CLASS(ChangeTeamPacket) - DEFINE_FIXED_FIELD(uint8_t, type, LE_CHANGE_TEAM) + DEFINE_TYPE(uint8_t, type, LE_CHANGE_TEAM) DEFINE_FIELD(uint8_t, local_id) - // send with PRM_RELIABLE + RELIABLE() END_DEFINE_CLASS(ChangeTeamPacket) DEFINE_CLASS(KickHostPacket) - DEFINE_FIXED_FIELD(uint8_t, type, LE_KICK_HOST) + DEFINE_TYPE(uint8_t, type, LE_KICK_HOST) DEFINE_FIELD(uint32_t, host_id) - // send with PRM_RELIABLE + RELIABLE() END_DEFINE_CLASS(KickHostPacket) DEFINE_CLASS(ReportRequestPacket) - DEFINE_FIXED_FIELD(uint8_t, type, LE_REPORT_PLAYER) + DEFINE_TYPE(uint8_t, type, LE_REPORT_PLAYER) DEFINE_FIELD(uint32_t, host_id) DEFINE_FIELD(widestr16, info) - // send with PRM_RELIABLE + RELIABLE() END_DEFINE_CLASS(ReportRequestPacket) DEFINE_CLASS(ReportSuccessPacket) SYNCHRONOUS(true) - DEFINE_FIXED_FIELD(uint8_t, type, LE_REPORT_PLAYER) + DEFINE_TYPE(uint8_t, type, LE_REPORT_PLAYER) DEFINE_FIELD(bool, success) DEFINE_FIELD(widestr, reported_name) - // send with PRM_RELIABLE + RELIABLE() END_DEFINE_CLASS(ReportSuccessPacket) DEFINE_CLASS(ChangeHandicapPacket) - DEFINE_FIXED_FIELD(uint8_t, type, LE_CHANGE_HANDICAP) + DEFINE_TYPE(uint8_t, type, LE_CHANGE_HANDICAP) DEFINE_FIELD(uint8_t, local_id) DEFINE_FIELD(uint8_t, handicap) - // send with PRM_RELIABLE + RELIABLE() END_DEFINE_CLASS(ChangeHandicapPacket) DEFINE_CLASS(BackLobbyPacket) SYNCHRONOUS(true) - DEFINE_FIXED_FIELD(uint8_t, type, LE_BACK_LOBBY) + DEFINE_TYPE(uint8_t, type, LE_BACK_LOBBY) DEFINE_FIELD(uint8_t, reason) - // send with PRM_RELIABLE + RELIABLE() END_DEFINE_CLASS(BackLobbyPacket) DEFINE_CLASS(ServerInfoPacket) SYNCHRONOUS(true) - DEFINE_FIXED_FIELD(uint8_t, type, LE_SERVER_INFO) + DEFINE_TYPE(uint8_t, type, LE_SERVER_INFO) DEFINE_FIELD(std::string, server_name); DEFINE_FIELD(uint8_t, difficulty) DEFINE_FIELD(uint8_t, max_players) @@ -340,7 +341,7 @@ DEFINE_CLASS(ServerInfoPacket) DEFINE_FIELD(widestr16, motd) DEFINE_FIELD(bool, is_configurable) DEFINE_FIELD(bool, has_live_players) - // send with PRM_RELIABLE + RELIABLE() END_DEFINE_CLASS(ServerInfoPacket) DEFINE_CLASS(AssetsPacket) @@ -358,32 +359,32 @@ DEFINE_CLASS(AssetsPacket2) END_DEFINE_CLASS(AssetsPacket2) DEFINE_CLASS(NewAssetsPacket) - DEFINE_FIXED_FIELD(uint8_t, type, LE_ASSETS_UPDATE) + DEFINE_TYPE(uint8_t, type, LE_ASSETS_UPDATE) DEFINE_FIELD(AssetsPacket, assets) END_DEFINE_CLASS(NewAssetsPacket) DEFINE_CLASS(PlayerKartsPacket) DEFINE_FIELD(uint8_t, players_count) - DEFINE_VECTOR_OBJ(std::string, players_count, karts) + DEFINE_VECTOR(std::string, players_count, karts) // I don't care about compilation for now but don't want extra macroses yet either. - DEFINE_VECTOR_OBJ/*_OPTIONAL*/(KartDataPacket, players_count, kart_data/*, cap(REAL_ADDON_KARTS) && IDONTKNOW*/) // if has "real_addon_karts" in cap AND anything is sent + DEFINE_VECTOR_PACKET/*_OPTIONAL*/(KartDataPacket, players_count, kart_data/*, cap(REAL_ADDON_KARTS) && IDONTKNOW*/) // if has "real_addon_karts" in cap AND anything is sent END_DEFINE_CLASS(PlayerKartsPacket) DEFINE_CLASS(KartSelectionRequestPacket) - DEFINE_FIXED_FIELD(uint8_t, type, LE_KART_SELECTION) + DEFINE_TYPE(uint8_t, type, LE_KART_SELECTION) DEFINE_FIELD(PlayerKartsPacket, karts) END_DEFINE_CLASS(KartSelectionRequestPacket) DEFINE_CLASS(LiveJoinRequestPacket) SYNCHRONOUS(true) - DEFINE_FIXED_FIELD(uint8_t, type, LE_LIVE_JOIN) + DEFINE_TYPE(uint8_t, type, LE_LIVE_JOIN) DEFINE_FIELD(bool, is_spectator) DEFINE_FIELD_OPTIONAL(PlayerKartsPacket, player_karts, check(0)) // check client side for condition! END_DEFINE_CLASS(LiveJoinRequestPacket) DEFINE_CLASS(FinishedLoadingLiveJoinPacket) - DEFINE_FIXED_FIELD(uint8_t, type, LE_CLIENT_LOADED_WORLD) + DEFINE_TYPE(uint8_t, type, LE_CLIENT_LOADED_WORLD) END_DEFINE_CLASS(FinishedLoadingLiveJoinPacket) DEFINE_CLASS(ConnectionRequestedPacket) @@ -400,13 +401,13 @@ END_DEFINE_CLASS(ConnectionRequestedPacket) DEFINE_CLASS(KartInfoRequestPacket) // check if synch - DEFINE_FIXED_FIELD(uint8_t, type, LE_KART_INFO) + DEFINE_TYPE(uint8_t, type, LE_KART_INFO) DEFINE_FIELD(uint8_t, kart_id) END_DEFINE_CLASS(KartInfoRequestPacket) DEFINE_CLASS(KartInfoPacket) SYNCHRONOUS(true) - DEFINE_FIXED_FIELD(uint8_t, type, LE_KART_INFO) + DEFINE_TYPE(uint8_t, type, LE_KART_INFO) DEFINE_FIELD(uint32_t, live_join_util_ticks) DEFINE_FIELD(uint8_t, kart_id) DEFINE_FIELD(widestr, player_name) @@ -418,12 +419,12 @@ DEFINE_CLASS(KartInfoPacket) DEFINE_FIELD(std::string, kart_name) DEFINE_FIELD(std::string, country_code) // The field below is present if "real_addon_karts" is in capabilities - DEFINE_FIELD_OBJ(KartDataPacket, kart_data) - // send with PRM_RELIABLE + DEFINE_FIELD_PACKET(KartDataPacket, kart_data) + RELIABLE() END_DEFINE_CLASS(KartInfoPacket) DEFINE_CLASS(ConfigServerPacket) - DEFINE_FIXED_FIELD(uint8_t, type, LE_CONFIG_SERVER) + DEFINE_TYPE(uint8_t, type, LE_CONFIG_SERVER) DEFINE_FIELD(uint8_t, difficulty) DEFINE_FIELD(uint8_t, game_mode) DEFINE_FIELD(bool, soccer_goal_target) @@ -431,41 +432,42 @@ END_DEFINE_CLASS(ConfigServerPacket) DEFINE_CLASS(ConnectionRefusedPacket) SYNCHRONOUS(true) - DEFINE_FIXED_FIELD(uint8_t, type, LE_CONNECTION_REFUSED) + DEFINE_TYPE(uint8_t, type, LE_CONNECTION_REFUSED) DEFINE_FIELD(uint8_t, reason) - DEFINE_FIELD_OPTIONAL(std::string, message); - // send with PRM_RELIABLE, warning! can be sent unencrypted! + DEFINE_FIELD_OPTIONAL(std::string, message, check(0)) /* I have no idea when */ + RELIABLE() + /* warning! can be sent unencrypted despite reliable! */ END_DEFINE_CLASS(ConnectionRefusedPacket) DEFINE_CLASS(StartGamePacket) SYNCHRONOUS(true) - DEFINE_FIXED_FIELD(uint8_t, type, LE_START_RACE) + DEFINE_TYPE(uint8_t, type, LE_START_RACE) DEFINE_FIELD(uint64_t, start_time) DEFINE_FIELD(uint8_t, check_count) - DEFINE_FIELD(ItemCompleteStatePacket, item_complete_state) /* this had operator += instead */ - // send with PRM_RELIABLE + DEFINE_FIELD(NimCompleteStatePacket, nim_complete_state) /* this had operator += instead */ + RELIABLE() END_DEFINE_CLASS(StartGamePacket) DEFINE_CLASS(VotePacket) /* vote of a player sent to others */ SYNCHRONOUS(true) - DEFINE_FIXED_FIELD(uint8_t, type, LE_VOTE) + DEFINE_TYPE(uint8_t, type, LE_VOTE) DEFINE_FIELD(uint32_t, host_id) DEFINE_FIELD(PeerVotePacket, vote) END_DEFINE_CLASS(VotePacket) DEFINE_CLASS(VoteRequestPacket) - DEFINE_FIXED_FIELD(uint8_t, type, LE_VOTE) + DEFINE_TYPE(uint8_t, type, LE_VOTE) DEFINE_FIELD(PeerVotePacket, vote) END_DEFINE_CLASS(VoteRequestPacket) DEFINE_CLASS(ServerOwnershipPacket) SYNCHRONOUS(true) - DEFINE_FIXED_FIELD(uint8_t, type, LE_SERVER_OWNERSHIP) + DEFINE_TYPE(uint8_t, type, LE_SERVER_OWNERSHIP) END_DEFINE_CLASS(ServerOwnershipPacket) DEFINE_CLASS(ConnectionAcceptedPacket) SYNCHRONOUS(true) - DEFINE_FIXED_FIELD(uint8_t, type, LE_CONNECTION_ACCEPTED) + DEFINE_TYPE(uint8_t, type, LE_CONNECTION_ACCEPTED) DEFINE_FIELD(uint32_t, host_id) DEFINE_FIELD(uint32_t, server_version) DEFINE_FIELD(uint16_t, capabilities_size) @@ -478,7 +480,7 @@ END_DEFINE_CLASS(ConnectionAcceptedPacket) DEFINE_CLASS(PlayerDisconnectedPacket) SYNCHRONOUS(true) - DEFINE_FIXED_FIELD(uint8_t, type, LE_PLAYER_DISCONNECTED) + DEFINE_TYPE(uint8_t, type, LE_PLAYER_DISCONNECTED) DEFINE_FIELD(uint8_t, players_size) DEFINE_FIELD(uint32_t, host_id) DEFINE_VECTOR(std::string, players_size, names) @@ -491,32 +493,21 @@ END_DEFINE_CLASS(PointChangesPacket) DEFINE_CLASS(StartSelectionPacket) SYNCHRONOUS(true) - DEFINE_FIXED_FIELD(uint8_t, type, LE_START_SELECTION) + DEFINE_TYPE(uint8_t, type, LE_START_SELECTION) DEFINE_FIELD(float, voting_timeout) DEFINE_FIELD(bool, no_kart_selection) DEFINE_FIELD(bool, fixed_length) DEFINE_FIELD(bool, track_voting) DEFINE_FIELD(AssetsPacket2, assets) - // send with PRM_RELIABLE + RELIABLE() END_DEFINE_CLASS(StartSelectionPacket) DEFINE_CLASS(BadTeamPacket) SYNCHRONOUS(true) - DEFINE_FIXED_FIELD(uint8_t, type, LE_BAD_TEAM) - // send with PRM_RELIABLE + DEFINE_TYPE(uint8_t, type, LE_BAD_TEAM) + RELIABLE() END_DEFINE_CLASS(BadTeamPacket) -DEFINE_CLASS(RaceFinishedPacket) - SYNCHRONOUS(true) - DEFINE_FIXED_FIELD(uint8_t, type, LE_RACE_FINISHED) - DEFINE_FIELD_OPTIONAL(uint32_t, fastest_lap, check(0)) /* if linear (incl. gp) */ - DEFINE_FIELD_OPTIONAL(widestr, fastest_kart_name, check(0)) /* if linear (incl. gp) */ - DEFINE_FIELD_OPTIONAL(GPScoresPacket, gp_scores, check(1)) /* if gp */ - DEFINE_FIELD(bool, point_changes_indication) - DEFINE_FIELD(PointChangesPacket, point_changes) - // send with PRM_RELIABLE -END_DEFINE_CLASS(RaceFinishedPacket) - DEFINE_CLASS(GPIndividualScorePacket) DEFINE_FIELD(uint32_t, last_score) DEFINE_FIELD(uint32_t, cur_score) @@ -531,23 +522,34 @@ DEFINE_CLASS(GPScoresPacket) DEFINE_VECTOR(GPIndividualScorePacket, num_players, scores) END_DEFINE_CLASS(GPScoresPacket) +DEFINE_CLASS(RaceFinishedPacket) + SYNCHRONOUS(true) + DEFINE_TYPE(uint8_t, type, LE_RACE_FINISHED) + DEFINE_FIELD_OPTIONAL(uint32_t, fastest_lap, check(0)) /* if linear (incl. gp) */ + DEFINE_FIELD_OPTIONAL(widestr, fastest_kart_name, check(0)) /* if linear (incl. gp) */ + DEFINE_FIELD_OPTIONAL(GPScoresPacket, gp_scores, check(1)) /* if gp */ + DEFINE_FIELD(bool, point_changes_indication) + DEFINE_FIELD(PointChangesPacket, point_changes) + RELIABLE() +END_DEFINE_CLASS(RaceFinishedPacket) + DEFINE_CLASS(InsideCtfPacket) SYNCHRONOUS(true) - DEFINE_FIXED_FIELD(uint8_t, type, GameEventsProtocol::GE_CTF_SCORED) + DEFINE_TYPE(uint8_t, type, GE_CTF_SCORED) DEFINE_FIELD(uint8_t, active_holder) DEFINE_FIELD(bool, red_inactive) /* actually, red scored */ DEFINE_FIELD(uint16_t, kart_score) DEFINE_FIELD(uint8_t, red_score) DEFINE_FIELD(uint8_t, blue_score) - // send with PRM_RELIABLE + RELIABLE() END_DEFINE_CLASS(InsideCtfPacket) DEFINE_CLASS(InsideFfaPacket) SYNCHRONOUS(true) - DEFINE_FIXED_FIELD(uint8_t, type, GameEventsProtocol::GE_BATTLE_KART_SCORE) + DEFINE_TYPE(uint8_t, type, GE_BATTLE_KART_SCORE) DEFINE_FIELD(uint8_t, hitter_kart) DEFINE_FIELD(uint16_t, new_score) - // send with PRM_RELIABLE + RELIABLE() END_DEFINE_CLASS(InsideFfaPacket) /* Separation is needed because it's filled in check structure itself */ @@ -557,7 +559,7 @@ END_DEFINE_CLASS(CheckActivePacket) DEFINE_CLASS(InsideChecklinePacket) SYNCHRONOUS(true) - DEFINE_FIXED_FIELD(uint8_t, type, GameEventsProtocol::GE_CHECK_LINE) + DEFINE_TYPE(uint8_t, type, GE_CHECK_LINE) DEFINE_FIELD(uint8_t, check_id) DEFINE_FIELD(uint8_t, kart_id) DEFINE_FIELD(uint8_t, finished_laps) @@ -565,13 +567,13 @@ DEFINE_CLASS(InsideChecklinePacket) DEFINE_FIELD(uint32_t, fastest_lap_ticks) DEFINE_FIELD(widestr, fastest_kart_name) DEFINE_FIELD(uint8_t, check_structure_count) - DEFINE_VECTOR_OBJ(CheckActivePacket, check_structure_count, check_active) + DEFINE_VECTOR_PACKET(CheckActivePacket, check_structure_count, check_active) END_DEFINE_CLASS(InsideChecklinePacket) DEFINE_CLASS(InternalGoalPacket) SYNCHRONOUS(true) - DEFINE_FIXED_FIELD(uint8_t, type, GameEventsProtocol::GE_PLAYER_GOAL) + DEFINE_TYPE(uint8_t, type, GE_PLAYER_GOAL) DEFINE_FIELD(uint8_t, id) DEFINE_FIELD(bool, correct_goal) DEFINE_FIELD(bool, first_goal) @@ -582,40 +584,40 @@ DEFINE_CLASS(InternalGoalPacket) /* what follows is only since 1.1, that is, when capabilities have "soccer_fixes" */ DEFINE_FIELD_OPTIONAL(std::string, country_code, cap(SOCCER_FIXES)) DEFINE_FIELD_OPTIONAL(uint8_t, handicap, cap(SOCCER_FIXES)) - // send with PRM_RELIABLE + RELIABLE() END_DEFINE_CLASS(InternalGoalPacket) DEFINE_CLASS(ResetBallPacket) SYNCHRONOUS(true) - DEFINE_FIXED_FIELD(uint8_t, type, GameEventsProtocol::GE_RESET_BALL) + DEFINE_TYPE(uint8_t, type, GE_RESET_BALL) DEFINE_FIELD(uint32_t, reset_ball_ticks) - // send with PRM_RELIABLE + RELIABLE() END_DEFINE_CLASS(ResetBallPacket) DEFINE_CLASS(BadConnectionPacket) SYNCHRONOUS(true) - DEFINE_FIXED_FIELD(uint8_t, type, LobbyEvent::LE_BAD_CONNECTION) - // send with PRM_RELIABLE + DEFINE_TYPE(uint8_t, type, LobbyEvent::LE_BAD_CONNECTION) + RELIABLE() END_DEFINE_CLASS(BadConnectionPacket) DEFINE_CLASS(RaceFinishedAckPacket) SYNCHRONOUS(true) - DEFINE_FIXED_FIELD(uint8_t, type, LE_RACE_FINISHED_ACK) - // send with PRM_RELIABLE + DEFINE_TYPE(uint8_t, type, LE_RACE_FINISHED_ACK) + RELIABLE() END_DEFINE_CLASS(RaceFinishedAckPacket) DEFINE_CLASS(RequestBeginPacket) - DEFINE_FIXED_FIELD(uint8_t, type, LE_REQUEST_BEGIN) - // send with PRM_RELIABLE + DEFINE_TYPE(uint8_t, type, LE_REQUEST_BEGIN) + RELIABLE() END_DEFINE_CLASS(RequestBeginPacket) DEFINE_CLASS(ClientBackLobbyPacket) - DEFINE_FIXED_FIELD(uint8_t, type, LE_CLIENT_BACK_LOBBY) - // send with PRM_RELIABLE + DEFINE_TYPE(uint8_t, type, LE_CLIENT_BACK_LOBBY) + RELIABLE() END_DEFINE_CLASS(ClientBackLobbyPacket) DEFINE_CLASS(ItemConfirmationPacket) - DEFINE_FIXED_FIELD(uint8_t, type, GP_ITEM_CONFIRMATION) + DEFINE_TYPE(uint8_t, type, GP_ITEM_CONFIRMATION) DEFINE_FIELD(uint32_t, ticks) END_DEFINE_CLASS(ItemConfirmationPacket) diff --git a/src/network/protocols/game_event_types.hpp b/src/network/protocols/game_event_types.hpp new file mode 100644 index 00000000000..19e1ce1f181 --- /dev/null +++ b/src/network/protocols/game_event_types.hpp @@ -0,0 +1,45 @@ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2025 kimden +// +// 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, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#ifndef GAME_EVENT_TYPES_H +#define GAME_EVENT_TYPES_H + +#include "utils/types.hpp" + +enum GameEventType : uint8_t +{ + GE_KART_FINISHED_RACE = 1, + GE_STARTUP_BOOST = 2, + GE_BATTLE_KART_SCORE = 3, + GE_CTF_SCORED = 4, + GE_RESET_BALL = 5, + GE_PLAYER_GOAL = 6, + GE_CHECK_LINE = 7 +}; // GameEventType + +/** The type of game events to be forwarded to the server. */ +enum GameProtocolEventType: uint8_t +{ + GP_CONTROLLER_ACTION, + GP_STATE, + GP_ITEM_UPDATE, + GP_ITEM_CONFIRMATION, + GP_ADJUST_TIME +}; + +#endif // GAME_EVENT_TYPES_H diff --git a/src/network/protocols/game_events_protocol.hpp b/src/network/protocols/game_events_protocol.hpp index 0cc05fcf616..c987147aa26 100644 --- a/src/network/protocols/game_events_protocol.hpp +++ b/src/network/protocols/game_events_protocol.hpp @@ -8,17 +8,6 @@ class AbstractKart; class GameEventsProtocol : public Protocol { -public: - enum GameEventType : uint8_t - { - GE_KART_FINISHED_RACE = 1, - GE_STARTUP_BOOST = 2, - GE_BATTLE_KART_SCORE = 3, - GE_CTF_SCORED = 4, - GE_RESET_BALL = 5, - GE_PLAYER_GOAL = 6, - GE_CHECK_LINE = 7 - }; // GameEventType private: int m_last_finished_position; diff --git a/src/network/protocols/game_protocol.hpp b/src/network/protocols/game_protocol.hpp index fa4c28d9f3e..0287e62adae 100644 --- a/src/network/protocols/game_protocol.hpp +++ b/src/network/protocols/game_protocol.hpp @@ -44,14 +44,6 @@ class GameProtocol : public Protocol * asynchronous event update. */ mutable std::mutex m_world_deleting_mutex; - /** The type of game events to be forwarded to the server. */ - enum { GP_CONTROLLER_ACTION, - GP_STATE, - GP_ITEM_UPDATE, - GP_ITEM_CONFIRMATION, - GP_ADJUST_TIME - }; - /** A network string that collects all information from the server to be sent * next. */ NetworkString *m_data_to_send; diff --git a/src/network/protocols/server_lobby.cpp b/src/network/protocols/server_lobby.cpp index eeaf069d320..d5d847ecbb5 100644 --- a/src/network/protocols/server_lobby.cpp +++ b/src/network/protocols/server_lobby.cpp @@ -215,7 +215,7 @@ ServerLobby::ServerLobby() : LobbyProtocol() m_ranking = std::make_shared(); } m_name_decorator = std::make_shared(); - m_items_complete_state = new BareNetworkString(); + m_nim_complete_state = NimCompleteStatePacket(); m_server_id_online.store(0); m_difficulty.store(ServerConfig::m_server_difficulty); m_game_mode.store(ServerConfig::m_server_mode); @@ -234,7 +234,6 @@ ServerLobby::~ServerLobby() // For child process the request manager will keep on running unregisterServer(m_process_type == PT_MAIN ? true : false/*now*/); } - delete m_items_complete_state; if (getSettings()->isSavingServerConfig()) ServerConfig::writeServerConfigToDisk(); @@ -2114,15 +2113,20 @@ void ServerLobby::checkRaceFinished() */ PointChangesPacket ServerLobby::computeNewRankings() { + unsigned player_count = RaceManager::get()->getNumPlayers(); + + // Empty packet for exceptions - unlikely to have though. + PointChangesPacket empty_packet; + empty_packet.player_count = (uint8_t)player_count; + empty_packet.changes = std::vector(player_count, 0.); + // No ranking for battle mode if (!RaceManager::get()->modeHasLaps()) - return; + return empty_packet; World* w = World::getWorld(); assert(w); - unsigned player_count = RaceManager::get()->getNumPlayers(); - // If all players quitted the race, we assume something went wrong // and skip entirely rating and statistics updates. for (unsigned i = 0; i < player_count; i++) @@ -2130,7 +2134,7 @@ PointChangesPacket ServerLobby::computeNewRankings() if (!w->getKart(i)->isEliminated()) break; if ((i + 1) == player_count) - return; + return empty_packet; } // Fill the results for the rankings to process @@ -2145,7 +2149,11 @@ PointChangesPacket ServerLobby::computeNewRankings() data.push_back(entry); } + // "LOLAND" changes, accidentally merged into supertuxkart/master + // and not noticed for 4 months. + // for (int i = 0; i < 64; ++i) { m_ranking->computeNewRankings(data, RaceManager::get()->isTimeTrialMode()); + // } // Used to display rating change at the end of a race PointChangesPacket packet; @@ -2228,7 +2236,7 @@ void ServerLobby::kickPlayerWithReason(std::shared_ptr peer, const char ConnectionRefusedPacket packet; packet.reason = RR_BANNED; - packet.message = reason; + packet.message = std::make_shared(reason); packet.toNetworkString(ns); peer->sendNetstring(ns, PRM_RELIABLE, PEM_UNENCRYPTED); @@ -2279,7 +2287,7 @@ bool ServerLobby::handleAssetsAndAddonScores(std::shared_ptr peer, NetworkString* ns = getNetworkString(2); ConnectionRefusedPacket packet; packet.reason = RR_INCOMPATIBLE_DATA; - packet.message = getSettings()->getIncompatibleAdvice(); + packet.message = std::make_shared(getSettings()->getIncompatibleAdvice()); packet.toNetworkString(ns); peer->sendNetstring(ns, PRM_RELIABLE, PEM_UNENCRYPTED); @@ -2291,7 +2299,6 @@ bool ServerLobby::handleAssetsAndAddonScores(std::shared_ptr peer, return false; } - std::array addons_scores = getAssetManager()->getAddonScores(client_karts, client_maps); // Save available karts and tracks from clients in STKPeer so if this peer @@ -2317,7 +2324,7 @@ bool ServerLobby::handleAssetsAndAddonScores(std::shared_ptr peer, void ServerLobby::connectionRequested(Event* event) { std::shared_ptr peer = event->getPeerSP(); - auto packet = event->getPacket(); + auto conn_packet = event->getPacket(); if (!checkDataSize(event, 14)) return; peer->cleanPlayerProfiles(); @@ -2341,7 +2348,7 @@ void ServerLobby::connectionRequested(Event* event) } // Check server version - int version = packet.version; + int version = conn_packet.version; auto& stk_config = STKConfig::get(); @@ -2359,36 +2366,34 @@ void ServerLobby::connectionRequested(Event* event) Log::verbose("ServerLobby", "Player refused: wrong server version"); return; } - std::string user_version = packet.user_version; + std::string user_version = conn_packet.user_version; event->getPeer()->setUserVersion(user_version); - unsigned list_caps = packet.capabilities_count; + unsigned list_caps = conn_packet.capabilities_count; std::set caps; for (unsigned i = 0; i < list_caps; i++) { - std::string cap = packet.capabilities[i]; + std::string cap = conn_packet.capabilities[i]; caps.insert(cap); } event->getPeer()->setClientCapabilities(caps); - std::set client_karts, client_maps; - std::set client_karts; - for (const std::string& item: packet.assets.karts) + for (const std::string& item: conn_packet.assets.karts) client_karts.insert(item); std::set client_maps; - for (const std::string& item: packet.assets.maps) + for (const std::string& item: conn_packet.assets.maps) client_maps.insert(item); if (!handleAssetsAndAddonScores(event->getPeerSP(), client_karts, client_maps)) return; - unsigned player_count = packet.players_count; + unsigned player_count = conn_packet.players_count; uint32_t online_id = 0; uint32_t encrypted_size = 0; - online_id = packet.online_id; - encrypted_size = packet.encrypted_size; + online_id = conn_packet.online_id; + encrypted_size = conn_packet.encrypted_size; // Will be disconnected if banned by IP testBannedForIP(peer); @@ -2401,7 +2406,7 @@ void ServerLobby::connectionRequested(Event* event) if (online_id != 0) testBannedForOnlineId(peer, online_id); - // Will be disconnected if banned by online id + if (peer->isDisconnected()) return; @@ -2503,7 +2508,7 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr peer, NetworkString* ns = getNetworkString(2); ConnectionRefusedPacket packet; packet.reason = RR_BANNED; - packet.message = "Please behave well next time."; + packet.message = std::make_shared("Please behave well next time."); packet.toNetworkString(ns); peer->sendNetstring(ns, PRM_RELIABLE, PEM_UNENCRYPTED); delete ns; @@ -3078,10 +3083,10 @@ void ServerLobby::handlePlayerVote(Event* event) // Now inform all clients about the vote NetworkString* ns = getNetworkString(); - VotePacket packet; - packet.host_id = event->getPeer()->getHostId(); - packet.vote = vote.encode(); - packet.toNetworkString(ns); + VotePacket vote_packet; + vote_packet.host_id = event->getPeer()->getHostId(); + vote_packet.vote = vote.encode(); + vote_packet.toNetworkString(ns); Comm::sendMessageToPeers(ns); delete ns; @@ -3342,7 +3347,7 @@ void ServerLobby::configPeersStartTime() StartGamePacket packet; packet.start_time = start_time; packet.check_count = (uint8_t)Track::getCurrentTrack()->getCheckManager()->getCheckStructureCount(); - packet.item_complete_state = m_items_complete_state; // was operator += + packet.nim_complete_state = m_nim_complete_state; // was operator += packet.toNetworkString(ns); Comm::sendMessageToPeers(ns, PRM_RELIABLE); @@ -4173,9 +4178,8 @@ void ServerLobby::clientSelectingAssetsWantsToBackLobby(Event* event) //----------------------------------------------------------------------------- void ServerLobby::saveInitialItems(std::shared_ptr nim) { - m_items_complete_state->getBuffer().clear(); - m_items_complete_state->reset(); - nim->saveCompleteState(m_items_complete_state); + // there was m_nim_complete_state->getBuffer().clear(); here + m_nim_complete_state = nim->saveCompleteState(); } // saveInitialItems //----------------------------------------------------------------------------- diff --git a/src/network/protocols/server_lobby.hpp b/src/network/protocols/server_lobby.hpp index af174205878..d463a64f327 100644 --- a/src/network/protocols/server_lobby.hpp +++ b/src/network/protocols/server_lobby.hpp @@ -151,7 +151,7 @@ class ServerLobby : public LobbyProtocol, public LobbyContextUser RaceFinishedPacket m_result_packet; /* Used to make sure clients are having same item list at start */ - BareNetworkString* m_items_complete_state; + NimCompleteStatePacket m_nim_complete_state; std::atomic m_server_id_online; diff --git a/src/network/stk_peer.cpp b/src/network/stk_peer.cpp index cec69aafdda..68e8d6c3766 100644 --- a/src/network/stk_peer.cpp +++ b/src/network/stk_peer.cpp @@ -139,7 +139,7 @@ void STKPeer::sendNetstring(NetworkString *data, PacketReliabilityMode reliable, //----------------------------------------------------------------------------- -void STKPeer::sendPacket(const Packet& packet, unsigned capacity, PacketReliabilityMode reliable, PacketEncryptionMode encrypted) +void STKPeer::sendPacket(Packet* packet, unsigned capacity, PacketReliabilityMode reliable, PacketEncryptionMode encrypted) { NetworkString* ns = getNetworkString(capacity); packet.toNetworkString(ns); diff --git a/src/network/stk_peer.hpp b/src/network/stk_peer.hpp index 3090162b88d..aa89b585aec 100644 --- a/src/network/stk_peer.hpp +++ b/src/network/stk_peer.hpp @@ -42,6 +42,7 @@ class Crypto; class NetworkPlayerProfile; class NetworkString; +class Packet; class STKHost; class SocketAddress; @@ -148,9 +149,9 @@ class STKPeer : public NoCopy void sendNetstring(NetworkString *data, PacketReliabilityMode reliable = PRM_RELIABLE, PacketEncryptionMode encrypted = PEM_ENCRYPTED); // ------------------------------------------------------------------------ - void sendPacket(const Packet& packet, PacketReliabilityMode reliable = PRM_RELIABLE, + void sendPacket(Packet* packet, PacketReliabilityMode reliable = PRM_RELIABLE, PacketEncryptionMode encrypted = PEM_ENCRYPTED); - ------------------------------------------------------------------------ + // ------------------------------------------------------------------------ void disconnect(); // ------------------------------------------------------------------------ void kick(); From 70a1935c8130d88c4aa4b1b074bcd0d30fcfff8a Mon Sep 17 00:00:00 2001 From: kimden <23140380+kimden@users.noreply.github.com> Date: Thu, 10 Apr 2025 02:46:00 +0400 Subject: [PATCH 11/34] Macro changes, added PROTOCOL_TYPE, more CL packets --- src/network/network_string.hpp | 8 ++ src/network/packet_types.cpp | 48 ++++------ src/network/packet_types.hpp | 23 +++-- src/network/packet_types_base.hpp | 104 ++++++++++++---------- src/network/protocols/client_lobby.cpp | 116 +++++++++++++------------ src/network/protocols/client_lobby.hpp | 2 +- 6 files changed, 161 insertions(+), 140 deletions(-) diff --git a/src/network/network_string.hpp b/src/network/network_string.hpp index fe362af8f82..034c25dd398 100644 --- a/src/network/network_string.hpp +++ b/src/network/network_string.hpp @@ -462,6 +462,14 @@ class NetworkString : public BareNetworkString return (ProtocolType)(m_buffer.at(0) & ~PROTOCOL_SYNCHRONOUS); } // getProtocolType + // ------------------------------------------------------------------------ + /** Sets the protocol type of this message. */ + void setProtocolType(ProtocolType type) + { + m_buffer.at(0) &= PROTOCOL_SYNCHRONOUS; + m_buffer.at(0) |= (type & (~PROTOCOL_SYNCHRONOUS)); + } // getProtocolType + // ------------------------------------------------------------------------ /** Sets if this message is to be sent synchronous or asynchronous. */ void setSynchronous(bool b) diff --git a/src/network/packet_types.cpp b/src/network/packet_types.cpp index 1cfc2f9ae3b..d54b760660c 100644 --- a/src/network/packet_types.cpp +++ b/src/network/packet_types.cpp @@ -27,17 +27,18 @@ inline void Name::toNetworkString(NetworkString* ns) const \ #define DEFINE_DERIVED_CLASS(Name, Parent) DEFINE_CLASS(Name) -#define SYNCHRONOUS(Value) \ - ns->setSynchronous(Value); +#define PROTOCOL_TYPE(Type, Sync) \ + ns->setProtocolType(Type); \ + if (!m_override_synchronous) \ + ns->setSynchronous(Sync); \ + else \ + ns->setSynchronous(*m_override_synchronous); #define AUX_VAR(Type, Var) #define DEFINE_FIELD(Type, Var) \ ns->encode(Var); -#define DEFINE_FIELD_PACKET(Type, Var) \ - Var.toNetworkString(ns); - #define DEFINE_FIELD_PTR(Type, Var) \ if (Var) \ ns->encode(*Var); @@ -55,14 +56,10 @@ inline void Name::toNetworkString(NetworkString* ns) const \ ns->encode(Value[Value##_cnt]); \ } -#define DEFINE_VECTOR_PACKET(Type, Size, Value) \ +#define DEFINE_VECTOR_PTR(Type, Size, Value) \ for (unsigned Value##_cnt = 0; Value##_cnt < Size; ++Value##_cnt) { \ - Value[Value##_cnt].toNetworkString(ns); \ - } - -#define DEFINE_VECTOR_PACKET_PTR(Type, Size, Value) \ - for (unsigned Value##_cnt = 0; Value##_cnt < Size; ++Value##_cnt) { \ - Value[Value##_cnt]->toNetworkString(ns); \ + if (Value[Value##_cnt]) \ + ns->encode(Value[Value##_cnt]); \ } #define RELIABLE() @@ -73,16 +70,14 @@ inline void Name::toNetworkString(NetworkString* ns) const \ #include "network/packet_types_base.hpp" #undef DEFINE_CLASS #undef DEFINE_DERIVED_CLASS -#undef SYNCHRONOUS +#undef PROTOCOL_TYPE #undef AUX_VAR #undef DEFINE_FIELD -#undef DEFINE_FIELD_PACKET #undef DEFINE_FIELD_PTR #undef DEFINE_TYPE #undef DEFINE_FIELD_OPTIONAL #undef DEFINE_VECTOR -#undef DEFINE_VECTOR_PACKET -#undef DEFINE_VECTOR_PACKET_PTR +#undef DEFINE_VECTOR_PTR #undef RELIABLE #undef END_DEFINE_CLASS @@ -97,16 +92,13 @@ inline void Name::fromNetworkString(NetworkString* ns) \ #define DEFINE_DERIVED_CLASS(Name, Parent) DEFINE_CLASS(Name) -#define SYNCHRONOUS(Value) +#define PROTOCOL_TYPE(Type, Sync) #define AUX_VAR(Type, Var) #define DEFINE_FIELD(Type, Var) \ ns->decode(Var); -#define DEFINE_FIELD_PACKET(Type, Var) \ - Var.fromNetworkString(ns); - // Same as optional but unconditional #define DEFINE_FIELD_PTR(Type, Var) \ Type temp_##Var; \ @@ -129,17 +121,11 @@ inline void Name::fromNetworkString(NetworkString* ns) \ ns->decode(Var[Var##_cnt]); \ } -#define DEFINE_VECTOR_PACKET(Type, Size, Var) \ - Var.resize(Size); \ - for (unsigned Var##_cnt = 0; Var##_cnt < Size; ++Var##_cnt) { \ - Var[Var##_cnt].fromNetworkString(ns); \ - } - -#define DEFINE_VECTOR_PACKET_PTR(Type, Size, Var) \ +#define DEFINE_VECTOR_PTR(Type, Size, Var) \ Var.resize(Size); \ for (unsigned Var##_cnt = 0; Var##_cnt < Size; ++Var##_cnt) { \ Type temp_##Var; \ - temp_##Var.fromNetworkString(ns); \ + ns->decode(temp_##Var); \ Var[Var##_cnt] = std::make_shared(temp_##Var); \ } @@ -151,16 +137,14 @@ inline void Name::fromNetworkString(NetworkString* ns) \ #include "network/packet_types_base.hpp" #undef DEFINE_CLASS #undef DEFINE_DERIVED_CLASS -#undef SYNCHRONOUS +#undef PROTOCOL_TYPE #undef AUX_VAR #undef DEFINE_FIELD -#undef DEFINE_FIELD_PACKET #undef DEFINE_FIELD_PTR #undef DEFINE_TYPE #undef DEFINE_FIELD_OPTIONAL #undef DEFINE_VECTOR -#undef DEFINE_VECTOR_PACKET -#undef DEFINE_VECTOR_PACKET_PTR +#undef DEFINE_VECTOR_PTR #undef RELIABLE #undef END_DEFINE_CLASS diff --git a/src/network/packet_types.hpp b/src/network/packet_types.hpp index f9269cb850f..37592b7e1a8 100644 --- a/src/network/packet_types.hpp +++ b/src/network/packet_types.hpp @@ -20,6 +20,7 @@ #define PACKET_TYPES_HPP #include "network/network_string.hpp" +#include "network/protocol.hpp" #include "network/protocols/game_event_types.hpp" #include "utils/cpp2011.hpp" @@ -121,18 +122,26 @@ struct Checkable struct Packet: public Checkable { +public: std::function m_capability_checker; // Needed to dynamic_cast virtual ~Packet() {} virtual void toNetworkString(NetworkString* ns) const {} virtual void fromNetworkString(NetworkString* ns) {} - virtual bool isSynchronous() { return false; } bool cap(const std::string& name) { return m_capability_checker(name); } + + void forceSynchronous(bool value) + { m_override_synchronous = std::make_shared(value); } + void unforceSynchronous() { m_override_synchronous = {}; } + +private: + std::shared_ptr m_override_synchronous; }; // temp constexpr int IDONT_KNOW = 0; +constexpr bool UNUSED = false; //---------------------- Initialization --------------------------------------- @@ -148,32 +157,28 @@ struct Name: public Parent { \ virtual void toNetworkString(NetworkString* ns) const OVERRIDE; \ virtual void fromNetworkString(NetworkString* ns) OVERRIDE; -#define SYNCHRONOUS(Value) bool isSynchronous() OVERRIDE { return Value; } +#define PROTOCOL_TYPE(Type, Sync) #define AUX_VAR(Type, Var) Type Var; #define DEFINE_FIELD(Type, Var) Type Var; -#define DEFINE_FIELD_PACKET(Type, Var) Type Var; #define DEFINE_FIELD_PTR(Type, Var) std::shared_ptr Var; #define DEFINE_FIELD_OPTIONAL(Type, Var, Condition) std::shared_ptr Var; #define DEFINE_TYPE(Type, Var, Value) Type Var; #define DEFINE_VECTOR(Type, Size, Var) std::vector Var; -#define DEFINE_VECTOR_PACKET(Type, Size, Var) std::vector Var; -#define DEFINE_VECTOR_PACKET_PTR(Type, Size, Var) std::vector> Var; +#define DEFINE_VECTOR_PTR(Type, Size, Var) std::vector> Var; #define RELIABLE() #define END_DEFINE_CLASS(Name) }; #include "network/packet_types_base.hpp" #undef DEFINE_CLASS #undef DEFINE_DERIVED_CLASS -#undef SYNCHRONOUS +#undef PROTOCOL_TYPE #undef AUX_VAR #undef DEFINE_FIELD -#undef DEFINE_FIELD_PACKET #undef DEFINE_FIELD_PTR #undef DEFINE_TYPE #undef DEFINE_FIELD_OPTIONAL #undef DEFINE_VECTOR -#undef DEFINE_VECTOR_PACKET -#undef DEFINE_VECTOR_PACKET_PTR +#undef DEFINE_VECTOR_PTR #undef RELIABLE #undef END_DEFINE_CLASS diff --git a/src/network/packet_types_base.hpp b/src/network/packet_types_base.hpp index 194610975d9..93115db880b 100644 --- a/src/network/packet_types_base.hpp +++ b/src/network/packet_types_base.hpp @@ -51,6 +51,8 @@ using widestr16 = irr::core::stringw; // but encodeString16 // Note that bools are encoded using int8_t +// Make sure all level 0 packets have protocol set! + DEFINE_CLASS(PlayerListProfilePacket) DEFINE_FIELD(uint32_t, host_id) DEFINE_FIELD(uint32_t, online_id) @@ -63,11 +65,11 @@ DEFINE_CLASS(PlayerListProfilePacket) END_DEFINE_CLASS(PlayerListProfilePacket) DEFINE_CLASS(PlayerListPacket) - SYNCHRONOUS(true) + PROTOCOL_TYPE(xxx, true) DEFINE_TYPE(uint8_t, type, LE_UPDATE_PLAYER_LIST) DEFINE_FIELD(bool, game_started) DEFINE_FIELD(uint8_t, all_profiles_size) - DEFINE_VECTOR_PACKET(PlayerListProfilePacket, all_profiles_size, all_profiles) + DEFINE_VECTOR(PlayerListProfilePacket, all_profiles_size, all_profiles) END_DEFINE_CLASS(PlayerListPacket) DEFINE_CLASS(EncodedSinglePlayerPacket) @@ -121,16 +123,16 @@ END_DEFINE_CLASS(KartDataPacket) DEFINE_CLASS(MultipleKartDataPacket) AUX_VAR(uint8_t, players_size) - DEFINE_VECTOR_PACKET(KartDataPacket, players_size, players_kart_data) + DEFINE_VECTOR(KartDataPacket, players_size, players_kart_data) END_DEFINE_CLASS(MultipleKartDataPacket) DEFINE_CLASS(LoadWorldPacket) - SYNCHRONOUS(true) + PROTOCOL_TYPE(xxx, true) DEFINE_TYPE(uint8_t, type, LE_LOAD_WORLD) DEFINE_FIELD(DefaultVotePacket, default_vote) DEFINE_FIELD(bool, live_join) DEFINE_FIELD(uint8_t, players_size) - DEFINE_VECTOR_PACKET(EncodedSinglePlayerPacket, players_size, all_players) + DEFINE_VECTOR(EncodedSinglePlayerPacket, players_size, all_players) DEFINE_FIELD(uint32_t, item_seed) DEFINE_FIELD_OPTIONAL(BattleInfoPacket, battle_info, check(0)) // RaceManager::get()->isBattleMode() DEFINE_FIELD_OPTIONAL(MultipleKartDataPacket, karts_data, cap(REAL_ADDON_KARTS)) @@ -161,7 +163,7 @@ DEFINE_CLASS(NimCompleteStatePacket) DEFINE_FIELD(uint32_t, ticks_since_start) DEFINE_FIELD(uint32_t, switch_ticks) DEFINE_FIELD(uint32_t, all_items_size) - DEFINE_VECTOR_PACKET(ItemCompleteStatePacket, all_items_size, all_items) + DEFINE_VECTOR(ItemCompleteStatePacket, all_items_size, all_items) END_DEFINE_CLASS(NimCompleteStatePacket) DEFINE_CLASS(KartInfoInGamePacket) @@ -194,7 +196,7 @@ END_DEFINE_CLASS(CheckStructureSubPacket) DEFINE_DERIVED_CLASS(CheckStructurePacket, CheckPacket) AUX_VAR(uint32_t, karts_count) - DEFINE_VECTOR_PACKET(CheckStructureSubPacket, karts_count, player_check_state) + DEFINE_VECTOR(CheckStructureSubPacket, karts_count, player_check_state) END_DEFINE_CLASS(CheckStructurePacket) DEFINE_CLASS(CheckLineSubPacket) @@ -204,7 +206,7 @@ END_DEFINE_CLASS(CheckLineSubPacket) DEFINE_DERIVED_CLASS(CheckLinePacket, CheckPacket) AUX_VAR(uint32_t, karts_count) DEFINE_FIELD_PTR(CheckStructurePacket, check_structure_packet) - DEFINE_VECTOR_PACKET(CheckLineSubPacket, karts_count, subpackets) + DEFINE_VECTOR(CheckLineSubPacket, karts_count, subpackets) END_DEFINE_CLASS(CheckLinePacket) DEFINE_CLASS(WorldPacket) @@ -215,11 +217,11 @@ DEFINE_DERIVED_CLASS(LinearWorldCompleteStatePacket, WorldPacket) AUX_VAR(uint32_t, track_sectors_count) DEFINE_FIELD(uint32_t, fastest_lap_ticks) DEFINE_FIELD(float, distance_increase) - DEFINE_VECTOR_PACKET(PlacementPacket, karts_count, kart_placements) - DEFINE_VECTOR_PACKET(KartInfoInGamePacket, karts_count, kart_infos) - DEFINE_VECTOR_PACKET(TrackSectorPacket, track_sectors_count, track_sectors) + DEFINE_VECTOR(PlacementPacket, karts_count, kart_placements) + DEFINE_VECTOR(KartInfoInGamePacket, karts_count, kart_infos) + DEFINE_VECTOR(TrackSectorPacket, track_sectors_count, track_sectors) DEFINE_FIELD(uint8_t, check_structure_count) - DEFINE_VECTOR_PACKET_PTR(CheckStructurePacket, check_structure_count, check_structures) + DEFINE_VECTOR_PTR(CheckStructurePacket, check_structure_count, check_structures) END_DEFINE_CLASS(LinearWorldCompleteStatePacket) DEFINE_CLASS(ScorerDataPacket) @@ -234,9 +236,9 @@ END_DEFINE_CLASS(ScorerDataPacket) DEFINE_DERIVED_CLASS(SoccerWorldCompleteStatePacket, WorldPacket) DEFINE_FIELD(uint32_t, red_scorers_count) - DEFINE_VECTOR_PACKET(ScorerDataPacket, red_scorers_count, red_scorers) + DEFINE_VECTOR(ScorerDataPacket, red_scorers_count, red_scorers) DEFINE_FIELD(uint32_t, blue_scorers_count) - DEFINE_VECTOR_PACKET(ScorerDataPacket, blue_scorers_count, blue_scorers) + DEFINE_VECTOR(ScorerDataPacket, blue_scorers_count, blue_scorers) DEFINE_FIELD(uint32_t, reser_ball_ticks) DEFINE_FIELD(uint32_t, ticks_back_to_own_goal) END_DEFINE_CLASS(SoccerWorldCompleteStatePacket) @@ -261,12 +263,12 @@ END_DEFINE_CLASS(WorldCompleteStatePacket) DEFINE_CLASS(InsideGameInfoPacket) DEFINE_FIELD(uint8_t, players_size) - DEFINE_VECTOR_PACKET(EncodedSinglePlayerPacket, players_size, all_players) - DEFINE_VECTOR_PACKET(KartDataPacket, players_size, players_kart_data) + DEFINE_VECTOR(EncodedSinglePlayerPacket, players_size, all_players) + DEFINE_VECTOR(KartDataPacket, players_size, players_kart_data) END_DEFINE_CLASS(InsideGameInfoPacket) DEFINE_CLASS(LiveJoinPacket) - SYNCHRONOUS(true) + PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, true) DEFINE_TYPE(uint8_t, type, LE_LIVE_JOIN_ACK) DEFINE_FIELD(uint64_t, client_starting_time) DEFINE_FIELD(uint8_t, check_count); @@ -278,9 +280,9 @@ DEFINE_CLASS(LiveJoinPacket) END_DEFINE_CLASS(LiveJoinPacket) DEFINE_CLASS(ChatPacket) - SYNCHRONOUS(true) + PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, true) DEFINE_TYPE(uint8_t, type, LE_CHAT) - DEFINE_FIELD(widestr16, message) // use encodeString16 ! max len is 360 + DEFINE_FIELD(widestr16, message) // use encodeString16 ! max len is 360 for server, 1000 for client DEFINE_FIELD_OPTIONAL(KartTeam, kart_team, check(0)) /* KartTeam is uint8_t, I have no idea when */ RELIABLE() END_DEFINE_CLASS(ChatPacket) @@ -305,7 +307,7 @@ DEFINE_CLASS(ReportRequestPacket) END_DEFINE_CLASS(ReportRequestPacket) DEFINE_CLASS(ReportSuccessPacket) - SYNCHRONOUS(true) + PROTOCOL_TYPE(xxx, true) DEFINE_TYPE(uint8_t, type, LE_REPORT_PLAYER) DEFINE_FIELD(bool, success) DEFINE_FIELD(widestr, reported_name) @@ -320,14 +322,14 @@ DEFINE_CLASS(ChangeHandicapPacket) END_DEFINE_CLASS(ChangeHandicapPacket) DEFINE_CLASS(BackLobbyPacket) - SYNCHRONOUS(true) + PROTOCOL_TYPE(xxx, true) DEFINE_TYPE(uint8_t, type, LE_BACK_LOBBY) DEFINE_FIELD(uint8_t, reason) RELIABLE() END_DEFINE_CLASS(BackLobbyPacket) DEFINE_CLASS(ServerInfoPacket) - SYNCHRONOUS(true) + PROTOCOL_TYPE(xxx, true) DEFINE_TYPE(uint8_t, type, LE_SERVER_INFO) DEFINE_FIELD(std::string, server_name); DEFINE_FIELD(uint8_t, difficulty) @@ -359,8 +361,10 @@ DEFINE_CLASS(AssetsPacket2) END_DEFINE_CLASS(AssetsPacket2) DEFINE_CLASS(NewAssetsPacket) + PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, false) DEFINE_TYPE(uint8_t, type, LE_ASSETS_UPDATE) DEFINE_FIELD(AssetsPacket, assets) + RELIABLE() END_DEFINE_CLASS(NewAssetsPacket) DEFINE_CLASS(PlayerKartsPacket) @@ -368,7 +372,7 @@ DEFINE_CLASS(PlayerKartsPacket) DEFINE_VECTOR(std::string, players_count, karts) // I don't care about compilation for now but don't want extra macroses yet either. - DEFINE_VECTOR_PACKET/*_OPTIONAL*/(KartDataPacket, players_count, kart_data/*, cap(REAL_ADDON_KARTS) && IDONTKNOW*/) // if has "real_addon_karts" in cap AND anything is sent + DEFINE_VECTOR/*_OPTIONAL*/(KartDataPacket, players_count, kart_data/*, cap(REAL_ADDON_KARTS) && IDONTKNOW*/) // if has "real_addon_karts" in cap AND anything is sent END_DEFINE_CLASS(PlayerKartsPacket) DEFINE_CLASS(KartSelectionRequestPacket) @@ -377,14 +381,16 @@ DEFINE_CLASS(KartSelectionRequestPacket) END_DEFINE_CLASS(KartSelectionRequestPacket) DEFINE_CLASS(LiveJoinRequestPacket) - SYNCHRONOUS(true) + PROTOCOL_TYPE(xxx, true) DEFINE_TYPE(uint8_t, type, LE_LIVE_JOIN) DEFINE_FIELD(bool, is_spectator) DEFINE_FIELD_OPTIONAL(PlayerKartsPacket, player_karts, check(0)) // check client side for condition! END_DEFINE_CLASS(LiveJoinRequestPacket) DEFINE_CLASS(FinishedLoadingLiveJoinPacket) + PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, UNUSED) DEFINE_TYPE(uint8_t, type, LE_CLIENT_LOADED_WORLD) + RELIABLE(); END_DEFINE_CLASS(FinishedLoadingLiveJoinPacket) DEFINE_CLASS(ConnectionRequestedPacket) @@ -400,13 +406,14 @@ DEFINE_CLASS(ConnectionRequestedPacket) END_DEFINE_CLASS(ConnectionRequestedPacket) DEFINE_CLASS(KartInfoRequestPacket) - // check if synch + PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, true) DEFINE_TYPE(uint8_t, type, LE_KART_INFO) DEFINE_FIELD(uint8_t, kart_id) + RELIABLE() END_DEFINE_CLASS(KartInfoRequestPacket) DEFINE_CLASS(KartInfoPacket) - SYNCHRONOUS(true) + PROTOCOL_TYPE(xxx, true) DEFINE_TYPE(uint8_t, type, LE_KART_INFO) DEFINE_FIELD(uint32_t, live_join_util_ticks) DEFINE_FIELD(uint8_t, kart_id) @@ -419,7 +426,7 @@ DEFINE_CLASS(KartInfoPacket) DEFINE_FIELD(std::string, kart_name) DEFINE_FIELD(std::string, country_code) // The field below is present if "real_addon_karts" is in capabilities - DEFINE_FIELD_PACKET(KartDataPacket, kart_data) + DEFINE_FIELD_OPTIONAL(KartDataPacket, kart_data, cap(REAL_ADDON_KARTS)) RELIABLE() END_DEFINE_CLASS(KartInfoPacket) @@ -431,7 +438,7 @@ DEFINE_CLASS(ConfigServerPacket) END_DEFINE_CLASS(ConfigServerPacket) DEFINE_CLASS(ConnectionRefusedPacket) - SYNCHRONOUS(true) + PROTOCOL_TYPE(xxx, true) DEFINE_TYPE(uint8_t, type, LE_CONNECTION_REFUSED) DEFINE_FIELD(uint8_t, reason) DEFINE_FIELD_OPTIONAL(std::string, message, check(0)) /* I have no idea when */ @@ -440,7 +447,7 @@ DEFINE_CLASS(ConnectionRefusedPacket) END_DEFINE_CLASS(ConnectionRefusedPacket) DEFINE_CLASS(StartGamePacket) - SYNCHRONOUS(true) + PROTOCOL_TYPE(xxx, true) DEFINE_TYPE(uint8_t, type, LE_START_RACE) DEFINE_FIELD(uint64_t, start_time) DEFINE_FIELD(uint8_t, check_count) @@ -449,7 +456,7 @@ DEFINE_CLASS(StartGamePacket) END_DEFINE_CLASS(StartGamePacket) DEFINE_CLASS(VotePacket) /* vote of a player sent to others */ - SYNCHRONOUS(true) + PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, true) DEFINE_TYPE(uint8_t, type, LE_VOTE) DEFINE_FIELD(uint32_t, host_id) DEFINE_FIELD(PeerVotePacket, vote) @@ -461,12 +468,12 @@ DEFINE_CLASS(VoteRequestPacket) END_DEFINE_CLASS(VoteRequestPacket) DEFINE_CLASS(ServerOwnershipPacket) - SYNCHRONOUS(true) + PROTOCOL_TYPE(xxx, true) DEFINE_TYPE(uint8_t, type, LE_SERVER_OWNERSHIP) END_DEFINE_CLASS(ServerOwnershipPacket) DEFINE_CLASS(ConnectionAcceptedPacket) - SYNCHRONOUS(true) + PROTOCOL_TYPE(xxx, true) DEFINE_TYPE(uint8_t, type, LE_CONNECTION_ACCEPTED) DEFINE_FIELD(uint32_t, host_id) DEFINE_FIELD(uint32_t, server_version) @@ -479,7 +486,7 @@ DEFINE_CLASS(ConnectionAcceptedPacket) END_DEFINE_CLASS(ConnectionAcceptedPacket) DEFINE_CLASS(PlayerDisconnectedPacket) - SYNCHRONOUS(true) + PROTOCOL_TYPE(xxx, true) DEFINE_TYPE(uint8_t, type, LE_PLAYER_DISCONNECTED) DEFINE_FIELD(uint8_t, players_size) DEFINE_FIELD(uint32_t, host_id) @@ -492,7 +499,7 @@ DEFINE_CLASS(PointChangesPacket) END_DEFINE_CLASS(PointChangesPacket) DEFINE_CLASS(StartSelectionPacket) - SYNCHRONOUS(true) + PROTOCOL_TYPE(xxx, true) DEFINE_TYPE(uint8_t, type, LE_START_SELECTION) DEFINE_FIELD(float, voting_timeout) DEFINE_FIELD(bool, no_kart_selection) @@ -503,7 +510,7 @@ DEFINE_CLASS(StartSelectionPacket) END_DEFINE_CLASS(StartSelectionPacket) DEFINE_CLASS(BadTeamPacket) - SYNCHRONOUS(true) + PROTOCOL_TYPE(xxx, true) DEFINE_TYPE(uint8_t, type, LE_BAD_TEAM) RELIABLE() END_DEFINE_CLASS(BadTeamPacket) @@ -523,7 +530,7 @@ DEFINE_CLASS(GPScoresPacket) END_DEFINE_CLASS(GPScoresPacket) DEFINE_CLASS(RaceFinishedPacket) - SYNCHRONOUS(true) + PROTOCOL_TYPE(xxx, true) DEFINE_TYPE(uint8_t, type, LE_RACE_FINISHED) DEFINE_FIELD_OPTIONAL(uint32_t, fastest_lap, check(0)) /* if linear (incl. gp) */ DEFINE_FIELD_OPTIONAL(widestr, fastest_kart_name, check(0)) /* if linear (incl. gp) */ @@ -534,7 +541,7 @@ DEFINE_CLASS(RaceFinishedPacket) END_DEFINE_CLASS(RaceFinishedPacket) DEFINE_CLASS(InsideCtfPacket) - SYNCHRONOUS(true) + PROTOCOL_TYPE(PROTOCOL_GAME_EVENTS, true) DEFINE_TYPE(uint8_t, type, GE_CTF_SCORED) DEFINE_FIELD(uint8_t, active_holder) DEFINE_FIELD(bool, red_inactive) /* actually, red scored */ @@ -545,7 +552,7 @@ DEFINE_CLASS(InsideCtfPacket) END_DEFINE_CLASS(InsideCtfPacket) DEFINE_CLASS(InsideFfaPacket) - SYNCHRONOUS(true) + PROTOCOL_TYPE(PROTOCOL_GAME_EVENTS, true) DEFINE_TYPE(uint8_t, type, GE_BATTLE_KART_SCORE) DEFINE_FIELD(uint8_t, hitter_kart) DEFINE_FIELD(uint16_t, new_score) @@ -558,7 +565,7 @@ DEFINE_CLASS(CheckActivePacket) END_DEFINE_CLASS(CheckActivePacket) DEFINE_CLASS(InsideChecklinePacket) - SYNCHRONOUS(true) + PROTOCOL_TYPE(PROTOCOL_GAME_EVENTS, true) DEFINE_TYPE(uint8_t, type, GE_CHECK_LINE) DEFINE_FIELD(uint8_t, check_id) DEFINE_FIELD(uint8_t, kart_id) @@ -567,12 +574,12 @@ DEFINE_CLASS(InsideChecklinePacket) DEFINE_FIELD(uint32_t, fastest_lap_ticks) DEFINE_FIELD(widestr, fastest_kart_name) DEFINE_FIELD(uint8_t, check_structure_count) - DEFINE_VECTOR_PACKET(CheckActivePacket, check_structure_count, check_active) + DEFINE_VECTOR(CheckActivePacket, check_structure_count, check_active) END_DEFINE_CLASS(InsideChecklinePacket) DEFINE_CLASS(InternalGoalPacket) - SYNCHRONOUS(true) + PROTOCOL_TYPE(PROTOCOL_GAME_EVENTS, true) DEFINE_TYPE(uint8_t, type, GE_PLAYER_GOAL) DEFINE_FIELD(uint8_t, id) DEFINE_FIELD(bool, correct_goal) @@ -588,20 +595,20 @@ DEFINE_CLASS(InternalGoalPacket) END_DEFINE_CLASS(InternalGoalPacket) DEFINE_CLASS(ResetBallPacket) - SYNCHRONOUS(true) + PROTOCOL_TYPE(PROTOCOL_GAME_EVENTS, true) DEFINE_TYPE(uint8_t, type, GE_RESET_BALL) DEFINE_FIELD(uint32_t, reset_ball_ticks) RELIABLE() END_DEFINE_CLASS(ResetBallPacket) DEFINE_CLASS(BadConnectionPacket) - SYNCHRONOUS(true) + PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, true) DEFINE_TYPE(uint8_t, type, LobbyEvent::LE_BAD_CONNECTION) RELIABLE() END_DEFINE_CLASS(BadConnectionPacket) DEFINE_CLASS(RaceFinishedAckPacket) - SYNCHRONOUS(true) + PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, true) DEFINE_TYPE(uint8_t, type, LE_RACE_FINISHED_ACK) RELIABLE() END_DEFINE_CLASS(RaceFinishedAckPacket) @@ -621,4 +628,13 @@ DEFINE_CLASS(ItemConfirmationPacket) DEFINE_FIELD(uint32_t, ticks) END_DEFINE_CLASS(ItemConfirmationPacket) +DEFINE_CLASS(CommandPacket) + PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, false) + DEFINE_TYPE(uint8_t, type, LE_COMMAND) + DEFINE_FIELD(std::string, language) + DEFINE_FIELD(std::string, command) + RELIABLE() +END_DEFINE_CLASS(CommandPacket) + + // end \ No newline at end of file diff --git a/src/network/protocols/client_lobby.cpp b/src/network/protocols/client_lobby.cpp index dc1570493fe..3c8bb70f758 100644 --- a/src/network/protocols/client_lobby.cpp +++ b/src/network/protocols/client_lobby.cpp @@ -419,7 +419,7 @@ void ClientLobby::update(int ticks) for (const std::string& cap : stk_config->m_network_capabilities) ns->encodeString(cap); - getKartsTracksNetworkString(ns); + ns (+=) getKartsTracksNetworkString(); assert(!NetworkConfig::get()->isAddingNetworkPlayers()); const uint8_t player_count = (uint8_t)NetworkConfig::get()->getNetworkPlayers().size(); @@ -584,10 +584,10 @@ void ClientLobby::finalizeConnectionRequest(NetworkString* header, void ClientLobby::receivePlayerVote(Event* event) { if (!checkDataSize(event, 4)) return; - // Get the player name who voted - NetworkString& data = event->data(); - uint32_t host_id = data.getUInt32(); - PeerVote vote(data); + + auto packet = event->getPacket(); + uint32_t host_id = packet.host_id; + PeerVote vote(packet.vote); Log::debug("ClientLobby", "Vote from server: host %d, track %s, laps %d, reverse %d.", host_id, vote.m_track_name.c_str(), vote.m_num_laps, vote.m_reverse); @@ -1303,8 +1303,9 @@ void ClientLobby::backToLobby(Event *event) void ClientLobby::finishedLoadingWorld() { NetworkString* ns = getNetworkString(1); - ns->setSynchronous(m_server_send_live_load_world); - ns->addUInt8(LE_CLIENT_LOADED_WORLD); + FinishedLoadingLiveJoinPacket packet; + packet.forceSynchronous(m_server_send_live_load_world); + packet.toNetworkString(ns); Comm::sendToServer(ns, PRM_RELIABLE); delete ns; } // finishedLoadingWorld @@ -1316,17 +1317,17 @@ void ClientLobby::liveJoinAcknowledged(Event* event) if (!w) return; - const NetworkString& data = event->data(); - m_start_live_game_time = data.getUInt64(); + auto packet = event->getPacket(); + m_start_live_game_time = packet.client_starting_time; powerup_manager->setRandomSeed(m_start_live_game_time); - unsigned check_structure_count = event->data().getUInt8(); + unsigned check_structure_count = packet.check_count; LinearWorld* lw = dynamic_cast(World::getWorld()); if (lw) lw->handleServerCheckStructureCount(check_structure_count); - m_start_live_game_time = data.getUInt64(); - m_last_live_join_util_ticks = data.getUInt32(); + m_start_live_game_time = packet.live_join_start_time; + m_last_live_join_util_ticks = packet.last_live_join_util_ticks; for (unsigned i = 0; i < w->getNumKarts(); i++) { AbstractKart* k = w->getKart(i); @@ -1337,18 +1338,19 @@ void ClientLobby::liveJoinAcknowledged(Event* event) NetworkItemManager* nim = dynamic_cast (Track::getCurrentTrack()->getItemManager()); assert(nim); - nim->restoreCompleteState(data); - w->restoreCompleteState(data); + nim->restoreCompleteState(packet.nim_complete_state); + w->restoreCompleteState(packet.world_complete_state); - if (RaceManager::get()->supportsLiveJoining() && data.size() > 0) + if (RaceManager::get()->supportsLiveJoining() && packet.inside_info) { + InsideGameInfoPacket subpacket = *packet.inside_info; // Get and update the players list 1 more time in case the was // player connection or disconnection std::vector > players; - unsigned player_count = data.getUInt8(); + unsigned player_count = subpacket.players_size; for (unsigned i = 0; i < player_count; ++i) - players.push_back(decodePlayer(data)); - getPlayersAddonKartType(data, players); + players.push_back(decodePlayer(subpacket.all_players[i])); + getPlayersAddonKartType(subpacket.players_kart_data, players); w->resetElimination(); for (unsigned i = 0; i < players.size(); i++) { @@ -1404,8 +1406,9 @@ void ClientLobby::finishLiveJoin() void ClientLobby::requestKartInfo(uint8_t kart_id) { NetworkString* ns = getNetworkString(1); - ns->setSynchronous(true); - ns->addUInt8(LE_KART_INFO).addUInt8(kart_id); + KartInfoRequestPacket packet; + packet.kart_id = kart_id; + packet.toNetworkString(ns); Comm::sendToServer(ns, PRM_RELIABLE); delete ns; } // requestKartInfo @@ -1417,26 +1420,24 @@ void ClientLobby::handleKartInfo(Event* event) if (!w) return; - const NetworkString& data = event->data(); - int live_join_util_ticks = data.getUInt32(); - uint8_t kart_id = data.getUInt8(); - core::stringw player_name; - data.decodeStringW(&player_name); - uint32_t host_id = data.getUInt32(); - float kart_color = data.getFloat(); - uint32_t online_id = data.getUInt32(); - HandicapLevel h = (HandicapLevel)data.getUInt8(); - uint8_t local_id = data.getUInt8(); - std::string kart_name; - data.decodeString(&kart_name); - std::string country_code; - data.decodeString(&country_code); + auto packet = event->getPacket(); + int live_join_util_ticks = packet.live_join_util_ticks; + uint8_t kart_id = packet.kart_id; + core::stringw player_name = packet.player_name; + uint32_t host_id = packet.host_id; + float kart_color = packet.default_kart_color; + uint32_t online_id = packet.online_id; + HandicapLevel h = (HandicapLevel)packet.handicap; + uint8_t local_id = packet.local_player_id; + std::string kart_name = packet.kart_name; + std::string country_code = packet.country_code; KartData kart_data; - if (NetworkConfig::get()->getServerCapabilities().find( - "real_addon_karts") != - NetworkConfig::get()->getServerCapabilities().end() && - data.size() > 0) - kart_data = KartData(data); + if (NetworkConfig::get()->getServerCapabilities().find("real_addon_karts") != + NetworkConfig::get()->getServerCapabilities().end() + && packet.kart_data) + { + kart_data = KartData(*packet.kart_data); + } RemoteKartInfo& rki = RaceManager::get()->getKartInfo(kart_id); rki.setPlayerName(player_name); @@ -1500,7 +1501,7 @@ void ClientLobby::sendChat(irr::core::stringw text, KartTeam team) if (text.size() > 0) { NetworkString* chat = getNetworkString(); - chat->addUInt8(LobbyEvent::LE_CHAT); + ChatPacket packet; core::stringw name; PlayerProfile* player = PlayerManager::getCurrentPlayer(); @@ -1545,11 +1546,12 @@ void ClientLobby::sendChat(irr::core::stringw text, KartTeam team) name = core::stringw(L"\u200E") + name; } #endif - chat->encodeString16(name + L": " + text, 1000/*max_len*/); + packet.message = name + L": " + text; if (team != KART_TEAM_NONE) - chat->addUInt8(team); + packet.kart_team = std::make_shared(team); + packet.toNetworkString(chat); Comm::sendToServer(chat, PRM_RELIABLE); delete chat; } @@ -1897,8 +1899,10 @@ void ClientLobby::handleClientCommand(const std::string& cmd) { // Send for server command NetworkString* cmd_ns = getNetworkString(1); - const std::string& language = UserConfigParams::m_language; - cmd_ns->addUInt8(LE_COMMAND).encodeString(language).encodeString(cmd); + CommandPacket packet; + packet.language = UserConfigParams::m_language; + packet.command = cmd; + packet.toNetworkString(cmd_ns); Comm::sendToServer(cmd_ns, PRM_RELIABLE); delete cmd_ns; } @@ -1906,7 +1910,7 @@ void ClientLobby::handleClientCommand(const std::string& cmd) } // handleClientCommand // ---------------------------------------------------------------------------- -void ClientLobby::getKartsTracksNetworkString(BareNetworkString* ns) +AssetsPacket ClientLobby::getKartsTracksNetworkString() { std::vector all_k; for (unsigned i = 0; i < kart_properties_manager->getNumberOfKarts(); i++) @@ -1924,23 +1928,27 @@ void ClientLobby::getKartsTracksNetworkString(BareNetworkString* ns) auto all_t = TrackManager::get()->getAllTrackIdentifiers(); if (all_t.size() >= 65536) all_t.resize(65535); - ns->addUInt16((uint16_t)all_k.size()).addUInt16((uint16_t)all_t.size()); + + AssetsPacket packet; + packet.karts_number = (uint16_t)all_k.size(); + packet.maps_number = (uint16_t)all_t.size(); + for (const std::string& kart : all_k) - { - ns->encodeString(kart); - } + packet.karts.push_back(kart); + for (const std::string& track : all_t) - { - ns->encodeString(track); - } + packet.maps.push_back(track); + + return packet; } // getKartsTracksNetworkString // ---------------------------------------------------------------------------- void ClientLobby::updateAssetsToServer() { NetworkString* ns = getNetworkString(1); - ns->addUInt8(LE_ASSETS_UPDATE); - getKartsTracksNetworkString(ns); + NewAssetsPacket packet; + packet.assets = getKartsTracksNetworkString(); + packet.toNetworkString(ns); Comm::sendToServer(ns, PRM_RELIABLE); delete ns; } // updateAssetsToServer diff --git a/src/network/protocols/client_lobby.hpp b/src/network/protocols/client_lobby.hpp index bef3e50e35c..e0839cd7e47 100644 --- a/src/network/protocols/client_lobby.hpp +++ b/src/network/protocols/client_lobby.hpp @@ -150,7 +150,7 @@ class ClientLobby : public LobbyProtocol bool* is_spectator = NULL) const; void getPlayersAddonKartType(const BareNetworkString& data, std::vector >& players) const; - void getKartsTracksNetworkString(BareNetworkString* ns); + AssetsPacket getKartsTracksNetworkString(); void doInstallAddonsPack(); public: ClientLobby(std::shared_ptr s); From 21e62787265653dfa7c2be9abaad8506170138ae Mon Sep 17 00:00:00 2001 From: kimden <23140380+kimden@users.noreply.github.com> Date: Fri, 11 Apr 2025 01:17:10 +0400 Subject: [PATCH 12/34] Own optional, more refactors, including CL --- src/items/network_item_manager.cpp | 4 +- src/modes/soccer_world.cpp | 25 +++-- src/network/game_setup.cpp | 4 +- src/network/kart_data.cpp | 19 ++-- src/network/network_string.hpp | 13 ++- src/network/packet_types.cpp | 16 +-- src/network/packet_types.hpp | 28 ++++-- src/network/packet_types_base.hpp | 97 +++++++++++-------- src/network/protocols/client_lobby.cpp | 66 ++++++------- .../protocols/game_events_protocol.cpp | 12 ++- src/network/protocols/server_lobby.cpp | 40 ++++---- src/network/stk_peer.cpp | 7 +- src/states_screens/online/tracks_screen.cpp | 4 +- 13 files changed, 187 insertions(+), 148 deletions(-) diff --git a/src/items/network_item_manager.cpp b/src/items/network_item_manager.cpp index 597f8c22e24..d7d7fb56a5e 100644 --- a/src/items/network_item_manager.cpp +++ b/src/items/network_item_manager.cpp @@ -533,7 +533,7 @@ NimCompleteStatePacket NetworkItemManager::saveCompleteState() const if (m_all_items[i]) { packet.all_items.back().has_item = true; - packet.all_items.back().item_state = std::make_shared(m_all_items[i]->saveCompleteState()); + packet.all_items.back().item_state = m_all_items[i]->saveCompleteState(); } else packet.all_items.back().has_item = false; @@ -560,7 +560,7 @@ void NetworkItemManager::restoreCompleteState(const NimCompleteStatePacket& pack const bool has_item = packet.all_items[i].has_item; if (has_item) { - ItemState* is = new ItemState(*(packet.all_items[i].item_state)); + ItemState* is = new ItemState(packet.all_items[i].item_state.get_value()); m_confirmed_state.push_back(is); } else diff --git a/src/modes/soccer_world.cpp b/src/modes/soccer_world.cpp index ed2786e6d38..f8ef417c521 100644 --- a/src/modes/soccer_world.cpp +++ b/src/modes/soccer_world.cpp @@ -246,9 +246,8 @@ ScorerDataPacket SoccerWorld::ScorerData::saveCompleteState(bool has_soccer_fixe packet.player = m_player; if (has_soccer_fixes) { - // kimden: Please get rid of types here. - packet.country_code = std::make_shared(m_country_code); - packet.handicap_level = std::make_shared(m_handicap_level); + packet.country_code = m_country_code; + packet.handicap_level = m_handicap_level; } return packet; } // saveCompleteState @@ -264,10 +263,10 @@ void SoccerWorld::ScorerData::restoreCompleteState(const ScorerDataPacket& packe if (NetworkConfig::get()->getServerCapabilities().find("soccer_fixes") != NetworkConfig::get()->getServerCapabilities().end()) { - if (auto ptr = packet.country_code) - m_country_code = *ptr; - if (auto ptr = packet.handicap_level) - m_handicap_level = (HandicapLevel)*ptr; + if (packet.country_code.has_value()) + m_country_code = packet.country_code.get_value(); + if (packet.handicap_level.has_value()) + m_handicap_level = (HandicapLevel)packet.handicap_level.get_value(); } } // restoreCompleteState //============================================================================= @@ -698,8 +697,8 @@ void SoccerWorld::onCheckGoalTriggered(bool first_goal) // Added in 1.1, add missing handicap info and country code InternalGoalPacket packet_1_1 = packet; - packet_1_1.country_code = std::make_shared(sd.m_country_code); - packet_1_1.handicap = std::make_shared(sd.m_handicap_level); + packet_1_1.country_code = sd.m_country_code; + packet_1_1.handicap = sd.m_handicap_level; NetworkString p(PROTOCOL_GAME_EVENTS); NetworkString p_1_1(PROTOCOL_GAME_EVENTS); @@ -773,11 +772,11 @@ void SoccerWorld::handlePlayerGoalFromServer(const InternalGoalPacket& packet) if (NetworkConfig::get()->getServerCapabilities().find("soccer_fixes") != NetworkConfig::get()->getServerCapabilities().end()) { - if (packet.country_code) - sd.m_country_code = *packet.country_code; + if (packet.country_code.has_value()) + sd.m_country_code = packet.country_code.get_value(); - if (packet.handicap) - sd.m_handicap_level = (HandicapLevel)(*packet.handicap); + if (packet.handicap.has_value()) + sd.m_handicap_level = (HandicapLevel)(packet.handicap.get_value()); } if (first_goal) diff --git a/src/network/game_setup.cpp b/src/network/game_setup.cpp index 57ecd00c663..9a14742b099 100644 --- a/src/network/game_setup.cpp +++ b/src/network/game_setup.cpp @@ -133,13 +133,13 @@ ServerInfoPacket GameSetup::addServerInfo() cur_track = 0; packet.has_extra_server_info = cur_track; - packet.extra_server_info = std::make_shared(m_extra_server_info); + packet.extra_server_info = m_extra_server_info; } else { // Soccer mode packet.has_extra_server_info = 1; - packet.extra_server_info = std::make_shared(m_extra_server_info); + packet.extra_server_info = m_extra_server_info; } } else diff --git a/src/network/kart_data.cpp b/src/network/kart_data.cpp index c90a9fd34a2..8b3048140f6 100644 --- a/src/network/kart_data.cpp +++ b/src/network/kart_data.cpp @@ -27,15 +27,16 @@ KartData::KartData(const KartProperties* kp) KartData::KartData(const KartDataPacket& packet) { m_kart_type = ""; - if (packet.kart_type) - m_kart_type = *packet.kart_type; + if (packet.kart_type.has_value()) + m_kart_type = packet.kart_type.get_value(); if (!m_kart_type.empty()) { - m_width = packet.parameters->width; - m_height = packet.parameters->height; - m_length = packet.parameters->length; - m_gravity_shift = packet.parameters->gravity_shift; + auto value = packet.parameters.get_value(); + m_width = value.width; + m_height = value.height; + m_length = value.length; + m_gravity_shift = value.gravity_shift; } else { @@ -49,8 +50,7 @@ KartData::KartData(const KartDataPacket& packet) KartDataPacket KartData::encode() const { KartDataPacket packet; - packet.kart_type = std::make_shared(m_kart_type); - packet.parameters = {}; + packet.kart_type = m_kart_type; if (!m_kart_type.empty()) { @@ -59,7 +59,8 @@ KartDataPacket KartData::encode() const params.height = m_height; params.length = m_length; params.gravity_shift = m_gravity_shift; - packet.parameters = std::make_shared(params); + + packet.parameters = params; } return packet; diff --git a/src/network/network_string.hpp b/src/network/network_string.hpp index 034c25dd398..91c31971469 100644 --- a/src/network/network_string.hpp +++ b/src/network/network_string.hpp @@ -134,6 +134,11 @@ friend class Crypto; encodeString(s); } // BareNetworkString // ------------------------------------------------------------------------ + void reserve(int capacity) + { + m_buffer.reserve(capacity); + } // reserve + // ------------------------------------------------------------------------ /** Initialises the string with a sequence of characters. */ BareNetworkString(const char *data, int len) { @@ -428,12 +433,14 @@ class NetworkString : public BareNetworkString { public: static void unitTesting(); - + + NetworkString(): BareNetworkString() {} + /** Constructor for a message to be sent. It sets the * protocol type of this message. It adds 1 byte to the capacity: * 1 byte for the protocol type. */ - NetworkString(ProtocolType type, int capacity=16) - : BareNetworkString(capacity+1) + NetworkString(ProtocolType type, int capacity=16) + : BareNetworkString(capacity + 1) { m_buffer.push_back(type); } // NetworkString diff --git a/src/network/packet_types.cpp b/src/network/packet_types.cpp index d54b760660c..ff5759efba9 100644 --- a/src/network/packet_types.cpp +++ b/src/network/packet_types.cpp @@ -29,10 +29,10 @@ inline void Name::toNetworkString(NetworkString* ns) const \ #define PROTOCOL_TYPE(Type, Sync) \ ns->setProtocolType(Type); \ - if (!m_override_synchronous) \ + if (!m_override_synchronous.has_value()) \ ns->setSynchronous(Sync); \ else \ - ns->setSynchronous(*m_override_synchronous); + ns->setSynchronous(m_override_synchronous.get_value()); #define AUX_VAR(Type, Var) @@ -45,8 +45,8 @@ inline void Name::toNetworkString(NetworkString* ns) const \ // We send it if it exists, and receive only if the condition is true #define DEFINE_FIELD_OPTIONAL(Type, Var, Condition) \ - if (Var) \ - ns->encode(*Var); + if (Var.has_value()) \ + ns->encode(Var.get_value()); #define DEFINE_TYPE(Type, Var, Value) \ ns->encode(Value); @@ -59,10 +59,10 @@ inline void Name::toNetworkString(NetworkString* ns) const \ #define DEFINE_VECTOR_PTR(Type, Size, Value) \ for (unsigned Value##_cnt = 0; Value##_cnt < Size; ++Value##_cnt) { \ if (Value[Value##_cnt]) \ - ns->encode(Value[Value##_cnt]); \ + ns->encode(*(Value[Value##_cnt])); \ } -#define RELIABLE() +#define RELIABLE(Value) #define END_DEFINE_CLASS(Name) \ } @@ -110,7 +110,7 @@ inline void Name::fromNetworkString(NetworkString* ns) \ if (Condition) { \ Type temp_##Var; \ ns->decode(temp_##Var); \ - Var = std::make_shared(temp_##Var); \ + Var = temp_##Var; \ } #define DEFINE_TYPE(Type, Var, Value) @@ -129,7 +129,7 @@ inline void Name::fromNetworkString(NetworkString* ns) \ Var[Var##_cnt] = std::make_shared(temp_##Var); \ } -#define RELIABLE() +#define RELIABLE(Value) #define END_DEFINE_CLASS(Name) \ } diff --git a/src/network/packet_types.hpp b/src/network/packet_types.hpp index 37592b7e1a8..a8a94d01966 100644 --- a/src/network/packet_types.hpp +++ b/src/network/packet_types.hpp @@ -120,6 +120,20 @@ struct Checkable } }; +template +class Optional +{ +private: + std::shared_ptr m_pointer; + +public: + bool has_value() const { return m_pointer != nullptr; } + const T& get_value() const { return *m_pointer; } + void unset() const { m_pointer.reset(); } + const T& operator = (const T& value) + { m_pointer = std::make_shared(value); return value; } +}; + struct Packet: public Checkable { public: @@ -131,12 +145,8 @@ struct Packet: public Checkable virtual void fromNetworkString(NetworkString* ns) {} bool cap(const std::string& name) { return m_capability_checker(name); } - void forceSynchronous(bool value) - { m_override_synchronous = std::make_shared(value); } - void unforceSynchronous() { m_override_synchronous = {}; } - -private: - std::shared_ptr m_override_synchronous; + Optional m_override_synchronous; + Optional m_override_reliable; }; // temp @@ -161,11 +171,11 @@ struct Name: public Parent { \ #define AUX_VAR(Type, Var) Type Var; #define DEFINE_FIELD(Type, Var) Type Var; #define DEFINE_FIELD_PTR(Type, Var) std::shared_ptr Var; -#define DEFINE_FIELD_OPTIONAL(Type, Var, Condition) std::shared_ptr Var; +#define DEFINE_FIELD_OPTIONAL(Type, Var, Condition) Optional Var; #define DEFINE_TYPE(Type, Var, Value) Type Var; #define DEFINE_VECTOR(Type, Size, Var) std::vector Var; #define DEFINE_VECTOR_PTR(Type, Size, Var) std::vector> Var; -#define RELIABLE() +#define RELIABLE(Value) #define END_DEFINE_CLASS(Name) }; #include "network/packet_types_base.hpp" @@ -182,6 +192,6 @@ struct Name: public Parent { \ #undef RELIABLE #undef END_DEFINE_CLASS -/* Don't forget to send RELIABLE() packets with PRM_RELIABLE */ +/* Don't forget to send RELIABLE(Value) packets with PRM_RELIABLE or PRM_UNRELIABLE if false */ #endif // PACKET_TYPES_HPP diff --git a/src/network/packet_types_base.hpp b/src/network/packet_types_base.hpp index 93115db880b..b09fa2943d1 100644 --- a/src/network/packet_types_base.hpp +++ b/src/network/packet_types_base.hpp @@ -65,7 +65,7 @@ DEFINE_CLASS(PlayerListProfilePacket) END_DEFINE_CLASS(PlayerListProfilePacket) DEFINE_CLASS(PlayerListPacket) - PROTOCOL_TYPE(xxx, true) + PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, true) DEFINE_TYPE(uint8_t, type, LE_UPDATE_PLAYER_LIST) DEFINE_FIELD(bool, game_started) DEFINE_FIELD(uint8_t, all_profiles_size) @@ -127,7 +127,7 @@ DEFINE_CLASS(MultipleKartDataPacket) END_DEFINE_CLASS(MultipleKartDataPacket) DEFINE_CLASS(LoadWorldPacket) - PROTOCOL_TYPE(xxx, true) + PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, true) DEFINE_TYPE(uint8_t, type, LE_LOAD_WORLD) DEFINE_FIELD(DefaultVotePacket, default_vote) DEFINE_FIELD(bool, live_join) @@ -275,7 +275,7 @@ DEFINE_CLASS(LiveJoinPacket) DEFINE_FIELD(uint64_t, live_join_start_time) DEFINE_FIELD(uint32_t, last_live_join_util_ticks) DEFINE_FIELD(NimCompleteStatePacket, nim_complete_state) - DEFINE_FIELD(WorldCompleteStatePacket, world_complete_state) + DEFINE_FIELD_PTR(WorldCompleteStatePacket, world_complete_state) DEFINE_FIELD_OPTIONAL(InsideGameInfoPacket, inside_info, check(0)) // RaceManager::get()->supportsLiveJoining() END_DEFINE_CLASS(LiveJoinPacket) @@ -284,52 +284,56 @@ DEFINE_CLASS(ChatPacket) DEFINE_TYPE(uint8_t, type, LE_CHAT) DEFINE_FIELD(widestr16, message) // use encodeString16 ! max len is 360 for server, 1000 for client DEFINE_FIELD_OPTIONAL(KartTeam, kart_team, check(0)) /* KartTeam is uint8_t, I have no idea when */ - RELIABLE() + RELIABLE(true) END_DEFINE_CLASS(ChatPacket) DEFINE_CLASS(ChangeTeamPacket) + PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, false) DEFINE_TYPE(uint8_t, type, LE_CHANGE_TEAM) DEFINE_FIELD(uint8_t, local_id) - RELIABLE() + RELIABLE(true) END_DEFINE_CLASS(ChangeTeamPacket) DEFINE_CLASS(KickHostPacket) + PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, false) DEFINE_TYPE(uint8_t, type, LE_KICK_HOST) DEFINE_FIELD(uint32_t, host_id) - RELIABLE() + RELIABLE(true) END_DEFINE_CLASS(KickHostPacket) DEFINE_CLASS(ReportRequestPacket) + PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, false) DEFINE_TYPE(uint8_t, type, LE_REPORT_PLAYER) DEFINE_FIELD(uint32_t, host_id) DEFINE_FIELD(widestr16, info) - RELIABLE() + RELIABLE(true) END_DEFINE_CLASS(ReportRequestPacket) DEFINE_CLASS(ReportSuccessPacket) - PROTOCOL_TYPE(xxx, true) + PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, true) DEFINE_TYPE(uint8_t, type, LE_REPORT_PLAYER) DEFINE_FIELD(bool, success) DEFINE_FIELD(widestr, reported_name) - RELIABLE() + RELIABLE(true) END_DEFINE_CLASS(ReportSuccessPacket) DEFINE_CLASS(ChangeHandicapPacket) + PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, false) DEFINE_TYPE(uint8_t, type, LE_CHANGE_HANDICAP) DEFINE_FIELD(uint8_t, local_id) DEFINE_FIELD(uint8_t, handicap) - RELIABLE() + RELIABLE(true) END_DEFINE_CLASS(ChangeHandicapPacket) DEFINE_CLASS(BackLobbyPacket) - PROTOCOL_TYPE(xxx, true) + PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, true) DEFINE_TYPE(uint8_t, type, LE_BACK_LOBBY) DEFINE_FIELD(uint8_t, reason) - RELIABLE() + RELIABLE(true) END_DEFINE_CLASS(BackLobbyPacket) DEFINE_CLASS(ServerInfoPacket) - PROTOCOL_TYPE(xxx, true) + PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, true) DEFINE_TYPE(uint8_t, type, LE_SERVER_INFO) DEFINE_FIELD(std::string, server_name); DEFINE_FIELD(uint8_t, difficulty) @@ -343,7 +347,7 @@ DEFINE_CLASS(ServerInfoPacket) DEFINE_FIELD(widestr16, motd) DEFINE_FIELD(bool, is_configurable) DEFINE_FIELD(bool, has_live_players) - RELIABLE() + RELIABLE(true) END_DEFINE_CLASS(ServerInfoPacket) DEFINE_CLASS(AssetsPacket) @@ -364,7 +368,7 @@ DEFINE_CLASS(NewAssetsPacket) PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, false) DEFINE_TYPE(uint8_t, type, LE_ASSETS_UPDATE) DEFINE_FIELD(AssetsPacket, assets) - RELIABLE() + RELIABLE(true) END_DEFINE_CLASS(NewAssetsPacket) DEFINE_CLASS(PlayerKartsPacket) @@ -376,12 +380,13 @@ DEFINE_CLASS(PlayerKartsPacket) END_DEFINE_CLASS(PlayerKartsPacket) DEFINE_CLASS(KartSelectionRequestPacket) + PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, true) DEFINE_TYPE(uint8_t, type, LE_KART_SELECTION) DEFINE_FIELD(PlayerKartsPacket, karts) END_DEFINE_CLASS(KartSelectionRequestPacket) DEFINE_CLASS(LiveJoinRequestPacket) - PROTOCOL_TYPE(xxx, true) + PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, true) DEFINE_TYPE(uint8_t, type, LE_LIVE_JOIN) DEFINE_FIELD(bool, is_spectator) DEFINE_FIELD_OPTIONAL(PlayerKartsPacket, player_karts, check(0)) // check client side for condition! @@ -390,7 +395,7 @@ END_DEFINE_CLASS(LiveJoinRequestPacket) DEFINE_CLASS(FinishedLoadingLiveJoinPacket) PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, UNUSED) DEFINE_TYPE(uint8_t, type, LE_CLIENT_LOADED_WORLD) - RELIABLE(); + RELIABLE(true); END_DEFINE_CLASS(FinishedLoadingLiveJoinPacket) DEFINE_CLASS(ConnectionRequestedPacket) @@ -409,11 +414,11 @@ DEFINE_CLASS(KartInfoRequestPacket) PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, true) DEFINE_TYPE(uint8_t, type, LE_KART_INFO) DEFINE_FIELD(uint8_t, kart_id) - RELIABLE() + RELIABLE(true) END_DEFINE_CLASS(KartInfoRequestPacket) DEFINE_CLASS(KartInfoPacket) - PROTOCOL_TYPE(xxx, true) + PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, true) DEFINE_TYPE(uint8_t, type, LE_KART_INFO) DEFINE_FIELD(uint32_t, live_join_util_ticks) DEFINE_FIELD(uint8_t, kart_id) @@ -427,10 +432,11 @@ DEFINE_CLASS(KartInfoPacket) DEFINE_FIELD(std::string, country_code) // The field below is present if "real_addon_karts" is in capabilities DEFINE_FIELD_OPTIONAL(KartDataPacket, kart_data, cap(REAL_ADDON_KARTS)) - RELIABLE() + RELIABLE(true) END_DEFINE_CLASS(KartInfoPacket) DEFINE_CLASS(ConfigServerPacket) + PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, false) DEFINE_TYPE(uint8_t, type, LE_CONFIG_SERVER) DEFINE_FIELD(uint8_t, difficulty) DEFINE_FIELD(uint8_t, game_mode) @@ -438,21 +444,21 @@ DEFINE_CLASS(ConfigServerPacket) END_DEFINE_CLASS(ConfigServerPacket) DEFINE_CLASS(ConnectionRefusedPacket) - PROTOCOL_TYPE(xxx, true) + PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, true) DEFINE_TYPE(uint8_t, type, LE_CONNECTION_REFUSED) DEFINE_FIELD(uint8_t, reason) DEFINE_FIELD_OPTIONAL(std::string, message, check(0)) /* I have no idea when */ - RELIABLE() + RELIABLE(true) /* warning! can be sent unencrypted despite reliable! */ END_DEFINE_CLASS(ConnectionRefusedPacket) DEFINE_CLASS(StartGamePacket) - PROTOCOL_TYPE(xxx, true) + PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, true) DEFINE_TYPE(uint8_t, type, LE_START_RACE) DEFINE_FIELD(uint64_t, start_time) DEFINE_FIELD(uint8_t, check_count) DEFINE_FIELD(NimCompleteStatePacket, nim_complete_state) /* this had operator += instead */ - RELIABLE() + RELIABLE(true) END_DEFINE_CLASS(StartGamePacket) DEFINE_CLASS(VotePacket) /* vote of a player sent to others */ @@ -463,17 +469,18 @@ DEFINE_CLASS(VotePacket) /* vote of a player sent to others */ END_DEFINE_CLASS(VotePacket) DEFINE_CLASS(VoteRequestPacket) + PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, false) DEFINE_TYPE(uint8_t, type, LE_VOTE) DEFINE_FIELD(PeerVotePacket, vote) END_DEFINE_CLASS(VoteRequestPacket) DEFINE_CLASS(ServerOwnershipPacket) - PROTOCOL_TYPE(xxx, true) + PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, true) DEFINE_TYPE(uint8_t, type, LE_SERVER_OWNERSHIP) END_DEFINE_CLASS(ServerOwnershipPacket) DEFINE_CLASS(ConnectionAcceptedPacket) - PROTOCOL_TYPE(xxx, true) + PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, true) DEFINE_TYPE(uint8_t, type, LE_CONNECTION_ACCEPTED) DEFINE_FIELD(uint32_t, host_id) DEFINE_FIELD(uint32_t, server_version) @@ -486,7 +493,7 @@ DEFINE_CLASS(ConnectionAcceptedPacket) END_DEFINE_CLASS(ConnectionAcceptedPacket) DEFINE_CLASS(PlayerDisconnectedPacket) - PROTOCOL_TYPE(xxx, true) + PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, true) DEFINE_TYPE(uint8_t, type, LE_PLAYER_DISCONNECTED) DEFINE_FIELD(uint8_t, players_size) DEFINE_FIELD(uint32_t, host_id) @@ -499,20 +506,20 @@ DEFINE_CLASS(PointChangesPacket) END_DEFINE_CLASS(PointChangesPacket) DEFINE_CLASS(StartSelectionPacket) - PROTOCOL_TYPE(xxx, true) + PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, true) DEFINE_TYPE(uint8_t, type, LE_START_SELECTION) DEFINE_FIELD(float, voting_timeout) DEFINE_FIELD(bool, no_kart_selection) DEFINE_FIELD(bool, fixed_length) DEFINE_FIELD(bool, track_voting) DEFINE_FIELD(AssetsPacket2, assets) - RELIABLE() + RELIABLE(true) END_DEFINE_CLASS(StartSelectionPacket) DEFINE_CLASS(BadTeamPacket) - PROTOCOL_TYPE(xxx, true) + PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, true) DEFINE_TYPE(uint8_t, type, LE_BAD_TEAM) - RELIABLE() + RELIABLE(true) END_DEFINE_CLASS(BadTeamPacket) DEFINE_CLASS(GPIndividualScorePacket) @@ -530,14 +537,14 @@ DEFINE_CLASS(GPScoresPacket) END_DEFINE_CLASS(GPScoresPacket) DEFINE_CLASS(RaceFinishedPacket) - PROTOCOL_TYPE(xxx, true) + PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, true) DEFINE_TYPE(uint8_t, type, LE_RACE_FINISHED) DEFINE_FIELD_OPTIONAL(uint32_t, fastest_lap, check(0)) /* if linear (incl. gp) */ DEFINE_FIELD_OPTIONAL(widestr, fastest_kart_name, check(0)) /* if linear (incl. gp) */ DEFINE_FIELD_OPTIONAL(GPScoresPacket, gp_scores, check(1)) /* if gp */ DEFINE_FIELD(bool, point_changes_indication) - DEFINE_FIELD(PointChangesPacket, point_changes) - RELIABLE() + DEFINE_FIELD_OPTIONAL(PointChangesPacket, point_changes, point_changes_indication) + RELIABLE(true) END_DEFINE_CLASS(RaceFinishedPacket) DEFINE_CLASS(InsideCtfPacket) @@ -548,7 +555,7 @@ DEFINE_CLASS(InsideCtfPacket) DEFINE_FIELD(uint16_t, kart_score) DEFINE_FIELD(uint8_t, red_score) DEFINE_FIELD(uint8_t, blue_score) - RELIABLE() + RELIABLE(true) END_DEFINE_CLASS(InsideCtfPacket) DEFINE_CLASS(InsideFfaPacket) @@ -556,7 +563,7 @@ DEFINE_CLASS(InsideFfaPacket) DEFINE_TYPE(uint8_t, type, GE_BATTLE_KART_SCORE) DEFINE_FIELD(uint8_t, hitter_kart) DEFINE_FIELD(uint16_t, new_score) - RELIABLE() + RELIABLE(true) END_DEFINE_CLASS(InsideFfaPacket) /* Separation is needed because it's filled in check structure itself */ @@ -591,41 +598,45 @@ DEFINE_CLASS(InternalGoalPacket) /* what follows is only since 1.1, that is, when capabilities have "soccer_fixes" */ DEFINE_FIELD_OPTIONAL(std::string, country_code, cap(SOCCER_FIXES)) DEFINE_FIELD_OPTIONAL(uint8_t, handicap, cap(SOCCER_FIXES)) - RELIABLE() + RELIABLE(true) END_DEFINE_CLASS(InternalGoalPacket) DEFINE_CLASS(ResetBallPacket) PROTOCOL_TYPE(PROTOCOL_GAME_EVENTS, true) DEFINE_TYPE(uint8_t, type, GE_RESET_BALL) DEFINE_FIELD(uint32_t, reset_ball_ticks) - RELIABLE() + RELIABLE(true) END_DEFINE_CLASS(ResetBallPacket) DEFINE_CLASS(BadConnectionPacket) PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, true) DEFINE_TYPE(uint8_t, type, LobbyEvent::LE_BAD_CONNECTION) - RELIABLE() + RELIABLE(true) END_DEFINE_CLASS(BadConnectionPacket) DEFINE_CLASS(RaceFinishedAckPacket) PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, true) DEFINE_TYPE(uint8_t, type, LE_RACE_FINISHED_ACK) - RELIABLE() + RELIABLE(true) END_DEFINE_CLASS(RaceFinishedAckPacket) DEFINE_CLASS(RequestBeginPacket) + PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, false) DEFINE_TYPE(uint8_t, type, LE_REQUEST_BEGIN) - RELIABLE() + RELIABLE(true) END_DEFINE_CLASS(RequestBeginPacket) DEFINE_CLASS(ClientBackLobbyPacket) + PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, false) DEFINE_TYPE(uint8_t, type, LE_CLIENT_BACK_LOBBY) - RELIABLE() + RELIABLE(true) END_DEFINE_CLASS(ClientBackLobbyPacket) DEFINE_CLASS(ItemConfirmationPacket) + PROTOCOL_TYPE(PROTOCOL_CONTROLLER_EVENTS, false) DEFINE_TYPE(uint8_t, type, GP_ITEM_CONFIRMATION) DEFINE_FIELD(uint32_t, ticks) + RELIABLE(false) END_DEFINE_CLASS(ItemConfirmationPacket) DEFINE_CLASS(CommandPacket) @@ -633,7 +644,7 @@ DEFINE_CLASS(CommandPacket) DEFINE_TYPE(uint8_t, type, LE_COMMAND) DEFINE_FIELD(std::string, language) DEFINE_FIELD(std::string, command) - RELIABLE() + RELIABLE(true) END_DEFINE_CLASS(CommandPacket) diff --git a/src/network/protocols/client_lobby.cpp b/src/network/protocols/client_lobby.cpp index 3c8bb70f758..289f18a4666 100644 --- a/src/network/protocols/client_lobby.cpp +++ b/src/network/protocols/client_lobby.cpp @@ -329,9 +329,9 @@ void ClientLobby::addAllPlayers(Event* event) if (RaceManager::get()->isBattleMode()) { // kimden: double checking when it's not needed? - if (packet.battle_info) + if (packet.battle_info.has_value()) { - BattleInfoPacket subpacket = *packet.battle_info; + BattleInfoPacket subpacket = packet.battle_info.get_value(); m_game_setup->setHitCaptureTime(subpacket.battle_hit_capture_limit, subpacket.battle_time_limit); @@ -380,23 +380,21 @@ std::shared_ptr std::shared_ptr peer, bool* is_spectator) const { - core::stringw player_name; - data.decodeStringW(&player_name); - uint32_t host_id = data.getUInt32(); - float kart_color = data.getFloat(); - uint32_t online_id = data.getUInt32(); - HandicapLevel handicap = (HandicapLevel)data.getUInt8(); - uint8_t local_id = data.getUInt8(); - KartTeam team = (KartTeam)data.getUInt8(); - std::string country_code; - data.decodeString(&country_code); + core::stringw player_name = packet.name; + uint32_t host_id = packet.host_id; + float kart_color = packet.kart_color; + uint32_t online_id = packet.online_id; + HandicapLevel handicap = (HandicapLevel)packet.handicap; + uint8_t local_id = packet.local_player_id; + KartTeam team = (KartTeam)packet.kart_team; + std::string country_code = packet.country_code; if (is_spectator && host_id == STKHost::get()->getMyHostId()) *is_spectator = false; + auto player = std::make_shared(peer, player_name, host_id, kart_color, online_id, handicap, local_id, team, country_code); - std::string kart_name; - data.decodeString(&kart_name); - player->setKartName(kart_name); + + player->setKartName(packet.kart_name); return player; } // decodePlayers @@ -1159,23 +1157,21 @@ void ClientLobby::startSelection(Event* event) */ void ClientLobby::raceFinished(Event* event) { - NetworkString &data = event->data(); + auto packet = event->getPacket(); Log::info("ClientLobby", "Server notified that the race is finished."); LinearWorld* lw = dynamic_cast(World::getWorld()); if (m_game_setup->isGrandPrix()) { - int t = data.getUInt32(); - core::stringw kart_name; - data.decodeStringW(&kart_name); + int t = packet.fastest_lap.get_value(); + core::stringw kart_name = packet.fastest_kart_name.get_value(); lw->setFastestLapTicks(t); lw->setFastestKartName(kart_name); - RaceManager::get()->configGrandPrixResultFromNetwork(data); + RaceManager::get()->configGrandPrixResultFromNetwork(packet.gp_scores.get_value()); } else if (RaceManager::get()->modeHasLaps()) { - int t = data.getUInt32(); - core::stringw kart_name; - data.decodeStringW(&kart_name); + int t = packet.fastest_lap.get_value(); + core::stringw kart_name = packet.fastest_kart_name.get_value(); lw->setFastestLapTicks(t); lw->setFastestKartName(kart_name); } @@ -1207,12 +1203,12 @@ void ClientLobby::raceFinished(Event* event) if (NetworkConfig::get()->getServerCapabilities().find("ranking_changes") != NetworkConfig::get()->getServerCapabilities().end()) { - bool has_ranking_changes = (data.getUInt8() & 1) != 0; - if (has_ranking_changes) + bool has_ranking_changes = packet.point_changes_indication; + if (has_ranking_changes && packet.point_changes.has_value()) { - unsigned count = data.getUInt8(); - for (unsigned i = 0; i < count; i++) - m_ranking_changes.push_back(data.getFloat()); + PointChangesPacket subpacket = packet.point_changes.get_value(); + unsigned count = subpacket.player_count; + m_ranking_changes = subpacket.changes; } } @@ -1304,7 +1300,7 @@ void ClientLobby::finishedLoadingWorld() { NetworkString* ns = getNetworkString(1); FinishedLoadingLiveJoinPacket packet; - packet.forceSynchronous(m_server_send_live_load_world); + packet.m_override_synchronous = m_server_send_live_load_world; packet.toNetworkString(ns); Comm::sendToServer(ns, PRM_RELIABLE); delete ns; @@ -1339,11 +1335,11 @@ void ClientLobby::liveJoinAcknowledged(Event* event) (Track::getCurrentTrack()->getItemManager()); assert(nim); nim->restoreCompleteState(packet.nim_complete_state); - w->restoreCompleteState(packet.world_complete_state); + w->restoreCompleteState(std::dynamic_pointer_cast(packet.world_complete_state)); - if (RaceManager::get()->supportsLiveJoining() && packet.inside_info) + if (RaceManager::get()->supportsLiveJoining() && packet.inside_info.has_value()) { - InsideGameInfoPacket subpacket = *packet.inside_info; + InsideGameInfoPacket subpacket = packet.inside_info.get_value(); // Get and update the players list 1 more time in case the was // player connection or disconnection std::vector > players; @@ -1434,9 +1430,9 @@ void ClientLobby::handleKartInfo(Event* event) KartData kart_data; if (NetworkConfig::get()->getServerCapabilities().find("real_addon_karts") != NetworkConfig::get()->getServerCapabilities().end() - && packet.kart_data) + && packet.kart_data.has_value()) { - kart_data = KartData(*packet.kart_data); + kart_data = packet.kart_data.get_value(); } RemoteKartInfo& rki = RaceManager::get()->getKartInfo(kart_id); @@ -1549,7 +1545,7 @@ void ClientLobby::sendChat(irr::core::stringw text, KartTeam team) packet.message = name + L": " + text; if (team != KART_TEAM_NONE) - packet.kart_team = std::make_shared(team); + packet.kart_team = team; packet.toNetworkString(chat); Comm::sendToServer(chat, PRM_RELIABLE); diff --git a/src/network/protocols/game_events_protocol.cpp b/src/network/protocols/game_events_protocol.cpp index cd57f22075d..4441bbecdb7 100644 --- a/src/network/protocols/game_events_protocol.cpp +++ b/src/network/protocols/game_events_protocol.cpp @@ -72,14 +72,18 @@ bool GameEventsProtocol::notifyEvent(Event* event) { if (!sw) throw std::invalid_argument("No soccer world"); - sw->handleResetBallFromServer(data); + + auto packet = event->getPacket(); + sw->handleResetBallFromServer(packet); break; } case GE_PLAYER_GOAL: { if (!sw) throw std::invalid_argument("No soccer world"); - sw->handlePlayerGoalFromServer(data); + + auto packet = event->getPacket(); + sw->handlePlayerGoalFromServer(packet); break; } case GE_BATTLE_KART_SCORE: @@ -141,8 +145,10 @@ bool GameEventsProtocol::notifyEvent(Event* event) { if (!lw) throw std::invalid_argument("No linear world"); + + auto packet = event->getPacket(); if (NetworkConfig::get()->isClient()) - lw->updateCheckLinesClient(data); + lw->updateCheckLinesClient(packet); break; } default: diff --git a/src/network/protocols/server_lobby.cpp b/src/network/protocols/server_lobby.cpp index d5d847ecbb5..ee374fa973a 100644 --- a/src/network/protocols/server_lobby.cpp +++ b/src/network/protocols/server_lobby.cpp @@ -343,8 +343,8 @@ void ServerLobby::handleChat(Event* event) core::stringw message = packet.message; KartTeam target_team = KART_TEAM_NONE; - if (packet.kart_team) - target_team = *(packet.kart_team); + if (packet.kart_team.has_value()) + target_team = packet.kart_team.get_value(); getChatManager()->handleNormalChatMessage(peer, StringUtils::wideToUtf8(message), target_team, m_name_decorator); @@ -916,7 +916,7 @@ void ServerLobby::asynchronousUpdate() resetPeersReady(); m_state = LOAD_WORLD; - NetworkString* ns; + NetworkString* ns = getNetworkString(); LoadWorldPacket packet = getLoadWorldMessage(players, false/*live_join*/); packet.toNetworkString(ns); Comm::sendMessageToPeers(ns); @@ -966,7 +966,8 @@ LoadWorldPacket ServerLobby::getLoadWorldMessage( for (auto& player: players) packet.all_players.push_back(encodePlayer(player, m_name_decorator)); packet.item_seed = m_item_seed; - packet.battle_info = {}; + + auto& stk_config = STKConfig::get(); if (RaceManager::get()->isBattleMode()) { @@ -979,8 +980,11 @@ LoadWorldPacket ServerLobby::getLoadWorldMessage( getSettings()->getFlagDeactivatedTime()); packet.battle_info = battle_packet; } + MultipleKartDataPacket multi_packet; for (unsigned i = 0; i < players.size(); i++) - packet.players_kart_data.push_back(players[i]->getKartData().encode()); + multi_packet.players_kart_data.push_back(players[i]->getKartData().encode()); + + packet.karts_data = multi_packet; return packet; } // getLoadWorldMessage @@ -1039,9 +1043,7 @@ void ServerLobby::rejectLiveJoin(std::shared_ptr peer, BackLobbyReason updatePlayerList(); NetworkString* ns2 = getNetworkString(); - ServerInfoPacket packet2; - //packet2.server_info = ...; - m_game_setup->addServerInfo(ns2); + ServerInfoPacket packet2 = m_game_setup->addServerInfo(); packet2.toNetworkString(ns2); peer->sendNetstring(ns2, PRM_RELIABLE); delete ns2; @@ -1078,7 +1080,7 @@ void ServerLobby::liveJoinRequest(Event* event) if (!spectator) { auto& spectators_by_limit = getCrownManager()->getSpectatorsByLimit(); - setPlayerKarts(packet.player_karts, peer); + setPlayerKarts(packet.player_karts.get_value(), peer); std::vector used_id; for (unsigned i = 0; i < peer->getPlayerProfiles().size(); i++) @@ -1284,8 +1286,9 @@ void ServerLobby::finishedLoadingLiveJoinClient(Event* event) packet.nim_complete_state = nim->saveCompleteState(); nim->addLiveJoinPeer(peer); - packet.world_complete_state = w->saveCompleteState(peer); - packet.inside_info = {}; + packet.world_complete_state = std::dynamic_pointer_cast + (w->saveCompleteState(peer)); + if (RaceManager::get()->supportsLiveJoining()) { InsideGameInfoPacket inside_packet; @@ -1514,6 +1517,8 @@ void ServerLobby::update(int ticks) handlePlayerDisconnection(); + NetworkString* ns; + switch (m_state.load()) { case SET_PUBLIC_ADDRESS: @@ -1558,7 +1563,7 @@ void ServerLobby::update(int ticks) setTimeoutFromNow(15); m_state = RESULT_DISPLAY; - NetworkString* ns = getNetworkString(); + ns = getNetworkString(); m_result_packet.toNetworkString(ns); Comm::sendMessageToPeers(ns, PRM_RELIABLE); delete ns; @@ -2053,6 +2058,8 @@ void ServerLobby::checkRaceFinished() { int fastest_lap = static_cast(World::getWorld())->getFastestLapTicks(); + + // kimden: you shouldn't expose packet field type like that m_result_packet.fastest_lap = fastest_lap; m_result_packet.fastest_kart_name = static_cast(World::getWorld()) ->getFastestLapKartName(); @@ -2060,8 +2067,7 @@ void ServerLobby::checkRaceFinished() if (m_game_setup->isGrandPrix()) { - m_result_packet.gp_scores = std::make_shared( - getGPManager()->updateGPScores(gp_changes)); + m_result_packet.gp_scores = getGPManager()->updateGPScores(gp_changes); } m_result_packet.point_changes_indication = @@ -2236,7 +2242,7 @@ void ServerLobby::kickPlayerWithReason(std::shared_ptr peer, const char ConnectionRefusedPacket packet; packet.reason = RR_BANNED; - packet.message = std::make_shared(reason); + packet.message = reason; packet.toNetworkString(ns); peer->sendNetstring(ns, PRM_RELIABLE, PEM_UNENCRYPTED); @@ -2287,7 +2293,7 @@ bool ServerLobby::handleAssetsAndAddonScores(std::shared_ptr peer, NetworkString* ns = getNetworkString(2); ConnectionRefusedPacket packet; packet.reason = RR_INCOMPATIBLE_DATA; - packet.message = std::make_shared(getSettings()->getIncompatibleAdvice()); + packet.message = getSettings()->getIncompatibleAdvice(); packet.toNetworkString(ns); peer->sendNetstring(ns, PRM_RELIABLE, PEM_UNENCRYPTED); @@ -2508,7 +2514,7 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr peer, NetworkString* ns = getNetworkString(2); ConnectionRefusedPacket packet; packet.reason = RR_BANNED; - packet.message = std::make_shared("Please behave well next time."); + packet.message = std::string("Please behave well next time."); packet.toNetworkString(ns); peer->sendNetstring(ns, PRM_RELIABLE, PEM_UNENCRYPTED); delete ns; diff --git a/src/network/stk_peer.cpp b/src/network/stk_peer.cpp index 68e8d6c3766..93b7c086a59 100644 --- a/src/network/stk_peer.cpp +++ b/src/network/stk_peer.cpp @@ -139,10 +139,11 @@ void STKPeer::sendNetstring(NetworkString *data, PacketReliabilityMode reliable, //----------------------------------------------------------------------------- -void STKPeer::sendPacket(Packet* packet, unsigned capacity, PacketReliabilityMode reliable, PacketEncryptionMode encrypted) +void STKPeer::sendPacket(Packet* packet, PacketReliabilityMode reliable, PacketEncryptionMode encrypted) { - NetworkString* ns = getNetworkString(capacity); - packet.toNetworkString(ns); + /* kimden: get capacity from the packet itself !!! */ + NetworkString* ns = new NetworkString(); + packet->toNetworkString(ns); sendNetstring(ns, reliable, encrypted); delete ns; } // sendPacket diff --git a/src/states_screens/online/tracks_screen.cpp b/src/states_screens/online/tracks_screen.cpp index fde29a5a1ec..bf0b136a4f1 100644 --- a/src/states_screens/online/tracks_screen.cpp +++ b/src/states_screens/online/tracks_screen.cpp @@ -770,7 +770,9 @@ void TracksScreen::voteForPlayer() { // kimden: I'm not sure if this is the right thing, but seems fine. // Not encoding packet to netstring before if just in case, too. - packet.toNetworkString(&vote); + VoteRequestPacket vr_packet; + vr_packet.vote = packet; + vr_packet.toNetworkString(&vote); Comm::sendToServer(&vote, PRM_RELIABLE); } } // voteForPlayer From 2ead0b7d5db836710429160a92dddbd1974e27f9 Mon Sep 17 00:00:00 2001 From: kimden <23140380+kimden@users.noreply.github.com> Date: Sun, 13 Apr 2025 02:37:49 +0400 Subject: [PATCH 13/34] Compilable but not linkable state without some packets Had also to move some things in packets and network string, they also accidentally included each other --- src/network/event.cpp | 9 - src/network/event.hpp | 7 +- src/network/network_string.cpp | 38 ++-- src/network/network_string.hpp | 51 ++++- src/network/packet_types.cpp | 1 + src/network/packet_types.hpp | 9 +- src/network/packet_types_base.hpp | 47 +++- src/network/protocols/client_lobby.cpp | 205 ++++++++++-------- src/network/protocols/client_lobby.hpp | 7 +- src/network/protocols/server_lobby.cpp | 82 ++++--- src/network/protocols/server_lobby.hpp | 2 +- .../online/network_kart_selection.cpp | 2 +- src/tracks/check_structure.hpp | 2 + src/utils/lobby_gp_manager.cpp | 2 - src/utils/lobby_gp_manager.hpp | 1 + 15 files changed, 282 insertions(+), 183 deletions(-) diff --git a/src/network/event.cpp b/src/network/event.cpp index d6f71528d45..c7b96d51ede 100644 --- a/src/network/event.cpp +++ b/src/network/event.cpp @@ -104,13 +104,4 @@ Event::~Event() { delete m_data; } // ~Event -//----------------------------------------------------------------------------- - -template -T Event::getPacket() -{ - T packet; - packet.fromNetworkString(m_data); - return packet; -} // getPacket //----------------------------------------------------------------------------- \ No newline at end of file diff --git a/src/network/event.hpp b/src/network/event.hpp index f30bb4eb3ad..0afd089402a 100644 --- a/src/network/event.hpp +++ b/src/network/event.hpp @@ -128,7 +128,12 @@ class Event PeerDisconnectInfo getPeerDisconnectInfo() const { return m_pdi; } // ------------------------------------------------------------------------ template - T getPacket(); + T getPacket() + { + T packet; + packet.fromNetworkString(m_data); + return packet; + } // getPacket // ------------------------------------------------------------------------ }; // class Event diff --git a/src/network/network_string.cpp b/src/network/network_string.cpp index 8d2a396b994..b144040d523 100644 --- a/src/network/network_string.cpp +++ b/src/network/network_string.cpp @@ -248,74 +248,74 @@ std::string BareNetworkString::getLogMessage(const std::string &indent) const template<> -void BareNetworkString::encode(const uint32_t& value) +void NetworkString::encodeSpecific(const uint32_t& value) { addUInt32(value); } // encode(uint32_t) //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - template<> -void BareNetworkString::decode(uint32_t& value) +void NetworkString::decodeSpecific(uint32_t& value) { value = getUInt32(); -} // decode(uint32_t) +} // decodeSpecific(uint32_t) //----------------------------------------------------------------------------- template<> -void BareNetworkString::encode(const uint8_t& value) +void NetworkString::encodeSpecific(const uint8_t& value) { addUInt8(value); } // encode(uint8_t) //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - template<> -void BareNetworkString::decode(uint8_t& value) +void NetworkString::decodeSpecific(uint8_t& value) { value = getUInt8(); -} // decode(uint8_t) +} // decodeSpecific(uint8_t) //----------------------------------------------------------------------------- template<> -void BareNetworkString::encode(const irr::core::stringw& value) +void NetworkString::encodeSpecific(const irr::core::stringw& value) { encodeString(value); } // encode(irr::core::stringw) //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - template<> -void BareNetworkString::decode(irr::core::stringw& value) +void NetworkString::decodeSpecific(irr::core::stringw& value) { decodeStringW(&value); -} // decode(irr::core::stringw) +} // decodeSpecific(irr::core::stringw) //----------------------------------------------------------------------------- template<> -void BareNetworkString::encode(const std::string& value) +void NetworkString::encodeSpecific(const std::string& value) { encodeString(value); } // encode(std::string) //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - template<> -void BareNetworkString::decode(std::string& value) +void NetworkString::decodeSpecific(std::string& value) { decodeString(&value); -} // decode(std::string) +} // decodeSpecific(std::string) //----------------------------------------------------------------------------- template<> -void BareNetworkString::encode(const bool& value) +void NetworkString::encodeSpecific(const bool& value) { addUInt8(value ? 1 : 0); } // encode(bool) //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - template<> -void BareNetworkString::decode(bool& value) +void NetworkString::decodeSpecific(bool& value) { value = getUInt8() == 1; -} // decode(bool) +} // decodeSpecific(bool) //----------------------------------------------------------------------------- // template<> -// void BareNetworkString::encode(const T& value) +// void NetworkString::encodeSpecific(const T& value) // { -// } // encode(T) +// } // encodeSpecific(T) // //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // template<> -// void BareNetworkString::decode(T& value) +// void NetworkString::decodeSpecific(T& value) // { -// } // decode(T) +// } // decodeSpecific(T) // //----------------------------------------------------------------------------- diff --git a/src/network/network_string.hpp b/src/network/network_string.hpp index 91c31971469..7c8fcb92a2a 100644 --- a/src/network/network_string.hpp +++ b/src/network/network_string.hpp @@ -24,6 +24,7 @@ #define NETWORK_STRING_HPP #include "network/protocol.hpp" +#include "network/packet_types.hpp" #include "utils/leak_check.hpp" #include "utils/types.hpp" #include "utils/vec3.hpp" @@ -38,6 +39,7 @@ #include #include #include +#include typedef unsigned char uchar; @@ -403,12 +405,6 @@ friend class Crypto; return q; } // getQuat // ------------------------------------------------------------------------ - template - void encode(const T& value); - // ------------------------------------------------------------------------ - template - void decode(T& value); - // ------------------------------------------------------------------------ }; // class BareNetworkString @@ -492,6 +488,49 @@ class NetworkString : public BareNetworkString { return (m_buffer[0] & PROTOCOL_SYNCHRONOUS) == PROTOCOL_SYNCHRONOUS; } // isSynchronous + // ------------------------------------------------------------------------ + template + void encodeSpecific(const T& value); + // ------------------------------------------------------------------------ + template + void decodeSpecific(T& value); + // ------------------------------------------------------------------------ + template + void encodeMaybePacket(const T& value, std::false_type) + { + encodeSpecific(value); + } + // ------------------------------------------------------------------------ + template + void decodeMaybePacket(T& value, std::false_type) + { + decodeSpecific(value); + } + // ------------------------------------------------------------------------ + template + void encodeMaybePacket(const T& value, std::true_type) + { + value.toNetworkString(this); + } + // ------------------------------------------------------------------------ + template + void decodeMaybePacket(T& value, std::true_type) + { + value.fromNetworkString(this); + } + // ------------------------------------------------------------------------ + template + void encode(const T& value) + { + encodeMaybePacket(value, std::is_base_of()); + } // encode + // ------------------------------------------------------------------------ + template + void decode(T& value) + { + decodeMaybePacket(value, std::is_base_of()); + } // decode + // ------------------------------------------------------------------------ }; // class NetworkString diff --git a/src/network/packet_types.cpp b/src/network/packet_types.cpp index ff5759efba9..02475c6a817 100644 --- a/src/network/packet_types.cpp +++ b/src/network/packet_types.cpp @@ -18,6 +18,7 @@ #include "network/packet_types.hpp" #include "network/remote_kart_info.hpp" +#include "network/network_string.hpp" //---------------------- To NetworkString ------------------------------------- diff --git a/src/network/packet_types.hpp b/src/network/packet_types.hpp index a8a94d01966..7593d3ed7cd 100644 --- a/src/network/packet_types.hpp +++ b/src/network/packet_types.hpp @@ -19,15 +19,20 @@ #ifndef PACKET_TYPES_HPP #define PACKET_TYPES_HPP -#include "network/network_string.hpp" +// #include "network/network_string.hpp" #include "network/protocol.hpp" #include "network/protocols/game_event_types.hpp" #include "utils/cpp2011.hpp" +#include "utils/types.hpp" +#include "utils/vec3.hpp" enum KartTeam: int8_t; +class NetworkString; +class BareNetworkString; #include #include +#include /** * IMPORTANT! @@ -134,7 +139,7 @@ class Optional { m_pointer = std::make_shared(value); return value; } }; -struct Packet: public Checkable +class Packet: public Checkable { public: std::function m_capability_checker; diff --git a/src/network/packet_types_base.hpp b/src/network/packet_types_base.hpp index b09fa2943d1..ee0cc9e9b04 100644 --- a/src/network/packet_types_base.hpp +++ b/src/network/packet_types_base.hpp @@ -53,6 +53,11 @@ using widestr16 = irr::core::stringw; // but encodeString16 // Make sure all level 0 packets have protocol set! +DEFINE_CLASS(EncryptedBuffer) + AUX_VAR(uint32_t, size) + DEFINE_VECTOR(uint8_t, size, buffer) +END_DEFINE_CLASS(EncryptedBuffer) + DEFINE_CLASS(PlayerListProfilePacket) DEFINE_FIELD(uint32_t, host_id) DEFINE_FIELD(uint32_t, online_id) @@ -398,18 +403,6 @@ DEFINE_CLASS(FinishedLoadingLiveJoinPacket) RELIABLE(true); END_DEFINE_CLASS(FinishedLoadingLiveJoinPacket) -DEFINE_CLASS(ConnectionRequestedPacket) - DEFINE_FIELD(uint32_t, version) - DEFINE_FIELD(std::string, user_version) - DEFINE_FIELD(uint16_t, capabilities_count) - DEFINE_VECTOR(std::string, capabilities_count, capabilities) - DEFINE_FIELD(AssetsPacket, assets) - DEFINE_FIELD(uint8_t, players_count) - DEFINE_FIELD(uint32_t, online_id) - DEFINE_FIELD(uint32_t, encrypted_size) - // to be continued -END_DEFINE_CLASS(ConnectionRequestedPacket) - DEFINE_CLASS(KartInfoRequestPacket) PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, true) DEFINE_TYPE(uint8_t, type, LE_KART_INFO) @@ -647,5 +640,35 @@ DEFINE_CLASS(CommandPacket) RELIABLE(true) END_DEFINE_CLASS(CommandPacket) +DEFINE_CLASS(ConnectingPlayerPacket) + DEFINE_FIELD(widestr, name) + DEFINE_FIELD(float, default_kart_color) + DEFINE_FIELD(uint8_t, handicap) +END_DEFINE_CLASS(ConnectingPlayerPacket) + +DEFINE_CLASS(RestConnectionRequestPacket) + DEFINE_FIELD(std::string, private_server_password) + DEFINE_FIELD(uint8_t, player_count) + DEFINE_VECTOR(ConnectingPlayerPacket, player_count, players) +END_DEFINE_CLASS(RestConnectionRequestPacket) + +DEFINE_CLASS(ConnectionRequestedPacket) + PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, false) + DEFINE_TYPE(uint8_t, type, LE_CONNECTION_REQUESTED) + DEFINE_FIELD(uint32_t, server_version) + DEFINE_FIELD(std::string, user_agent) + DEFINE_FIELD(uint16_t, capabilities_size) + DEFINE_VECTOR(std::string, capabilities_size, capabilities) + DEFINE_FIELD(AssetsPacket, assets) + DEFINE_FIELD(uint8_t, player_count) + + DEFINE_FIELD(uint32_t, id) + DEFINE_FIELD(uint32_t, encrypted_size) // 0 if not encrypted + DEFINE_FIELD_OPTIONAL(widestr, player_name, id != 0 && encrypted_size == 0) + DEFINE_FIELD_OPTIONAL(EncryptedBuffer, player_info_encrypted, encrypted_size != 0) + DEFINE_FIELD_OPTIONAL(RestConnectionRequestPacket, player_info_unencrypted, encrypted_size == 0 && check(4)) /* I really don't know, it can be sent if encryption failed, very bad */ + +END_DEFINE_CLASS(ConnectionRequestedPacket) + // end \ No newline at end of file diff --git a/src/network/protocols/client_lobby.cpp b/src/network/protocols/client_lobby.cpp index 289f18a4666..0a33402e83a 100644 --- a/src/network/protocols/client_lobby.cpp +++ b/src/network/protocols/client_lobby.cpp @@ -255,22 +255,6 @@ bool ClientLobby::notifyEventAsynchronous(Event* event) return true; } // notifyEventAsynchronous -//----------------------------------------------------------------------------- -void ClientLobby::getPlayersAddonKartType(const BareNetworkString& data, - std::vector >& players) const -{ - if (NetworkConfig::get()->getServerCapabilities().find( - "real_addon_karts") == - NetworkConfig::get()->getServerCapabilities().end() || - data.size() == 0) - return; - for (unsigned i = 0; i < players.size(); i++) - { - KartData kart_data(data); - players[i]->setKartData(kart_data); - } -} // getPlayersAddonKartType - //----------------------------------------------------------------------------- void ClientLobby::addAllPlayers(Event* event) { @@ -340,7 +324,14 @@ void ClientLobby::addAllPlayers(Event* event) RaceManager::get()->setFlagDeactivatedTicks(subpacket.flag_deactivated_time); } } - getPlayersAddonKartType(data, players); + if (NetworkConfig::get()->getServerCapabilities().find("real_addon_karts") != + NetworkConfig::get()->getServerCapabilities().end() && packet.karts_data.has_value()) + { + for (unsigned i = 0; i < players.size(); i++) + { + players[i]->setKartData(KartData(packet.karts_data.get_value().players_kart_data[i])); + } + } configRemoteKart(players, isSpectator() ? 1 : (int)NetworkConfig::get()->getNetworkPlayers().size()); loadWorld(); @@ -407,21 +398,25 @@ void ClientLobby::update(int ticks) case LINKED: { NetworkConfig::get()->clearServerCapabilities(); - std::string ua = StringUtils::getUserAgentString(); + std::string user_agent = StringUtils::getUserAgentString(); if (NetworkConfig::get()->isNetworkAIInstance()) - ua = "AI"; + user_agent = "AI"; NetworkString* ns = getNetworkString(); - ns->addUInt8(LE_CONNECTION_REQUESTED) - .addUInt32(ServerConfig::m_server_version).encodeString(ua) - .addUInt16((uint16_t)stk_config->m_network_capabilities.size()); + + ConnectionRequestedPacket packet; + packet.server_version = (uint32_t)ServerConfig::m_server_version; + packet.user_agent = user_agent; + packet.capabilities_size = (uint16_t)stk_config->m_network_capabilities.size(); for (const std::string& cap : stk_config->m_network_capabilities) - ns->encodeString(cap); + packet.capabilities.push_back(cap); - ns (+=) getKartsTracksNetworkString(); + packet.assets = getKartsTracksPacket(); assert(!NetworkConfig::get()->isAddingNetworkPlayers()); - const uint8_t player_count = - (uint8_t)NetworkConfig::get()->getNetworkPlayers().size(); - ns->addUInt8(player_count); + + auto& all_players = NetworkConfig::get()->getNetworkPlayers(); + + const uint8_t player_count = (uint8_t)all_players.size(); + packet.player_count = player_count; bool encryption = false; // Make sure there is a player before calling getCurrentOnlineId @@ -431,28 +426,28 @@ void ClientLobby::update(int ticks) NetworkConfig::get()->isNetworkAIInstance(); if (lan_ai) id = 0; - BareNetworkString* rest = new BareNetworkString(); if (m_server->supportsEncryption() && id != 0) { - ns->addUInt32(id); + packet.id = id; encryption = true; } else { - ns->addUInt32(id).addUInt32(0); + packet.id = id; + packet.encrypted_size = 0; + if (id != 0) - { - ns->encodeString( - PlayerManager::getCurrentOnlineProfile()->getUserName()); - } + packet.player_name = PlayerManager::getCurrentOnlineProfile()->getUserName(); } - rest->encodeString(ServerConfig::m_private_server_password) - .addUInt8(player_count); - for (unsigned i = 0; - i < NetworkConfig::get()->getNetworkPlayers().size(); i++) + BareNetworkString* rest = new BareNetworkString(); + RestConnectionRequestPacket subpacket; + + subpacket.private_server_password = ServerConfig::m_private_server_password; + subpacket.player_count = player_count; + for (unsigned i = 0; i < player_count; i++) { - auto& p = NetworkConfig::get()->getNetworkPlayers()[i]; + auto& p = all_players[i]; PlayerProfile* player = std::get<1>(p); core::stringw name = player->getName(); if (NetworkConfig::get()->isNetworkAIInstance()) @@ -465,13 +460,66 @@ void ClientLobby::update(int ticks) #endif name += core::stringw(" ") + StringUtils::toWString(i + 1); } - rest->encodeString(name). - addFloat(player->getDefaultKartColor()); - // Per-player handicap - rest->addUInt8(std::get<2>(p)); + + ConnectingPlayerPacket player_packet; + player_packet.name = name; + player_packet.default_kart_color = player->getDefaultKartColor(); + player_packet.handicap = std::get<2>(p); + subpacket.players.push_back(player_packet); } - finalizeConnectionRequest(ns, rest, encryption); + if (encryption) + { + auto crypto = Crypto::getClientCrypto(); + Crypto::resetClientAES(); + + NetworkString* rest = new NetworkString(); + subpacket.toNetworkString(rest); + if (!crypto->encryptConnectionRequest(*rest)) + { + // Failed + packet.encrypted_size = 0; + // packet.player_info_unencrypted = subpacket; + encryption = false; + + if (id != 0) + packet.player_name = PlayerManager::getCurrentOnlineProfile()->getUserName(); + } + else + { + packet.encrypted_size = rest->getTotalSize(); + Log::info("ClientLobby", "Server will validate this online player."); + + EncryptedBuffer eb; + eb.buffer = rest->getBuffer(); + packet.player_info_encrypted = eb; + } + delete rest; + + packet.toNetworkString(ns); + Comm::sendToServer(ns); + delete ns; + + if (encryption) + { + STKHost::get()->getServerPeerForClient() + ->setCrypto(std::move(crypto)); + } + } + else + { + *ns += *rest; + delete rest; + Comm::sendToServer(ns); + delete ns; + } + + + + + + + m_state.store(REQUESTING_CONNECTION); } break; @@ -535,49 +583,6 @@ void ClientLobby::update(int ticks) } } // update -//----------------------------------------------------------------------------- -void ClientLobby::finalizeConnectionRequest(NetworkString* header, - BareNetworkString* rest, - bool encrypt) -{ - if (encrypt) - { - auto crypto = Crypto::getClientCrypto(); - Crypto::resetClientAES(); - BareNetworkString* result = new BareNetworkString(); - if (!crypto->encryptConnectionRequest(*rest)) - { - // Failed - result->addUInt32(0); - *result += BareNetworkString(rest->getData(), rest->getTotalSize()); - encrypt = false; - } - else - { - Log::info("ClientLobby", "Server will validate this online player."); - result->addUInt32(rest->getTotalSize()); - *result += BareNetworkString(rest->getData(), rest->getTotalSize()); - } - delete rest; - *header += *result; - delete result; - Comm::sendToServer(header); - delete header; - if (encrypt) - { - STKHost::get()->getServerPeerForClient() - ->setCrypto(std::move(crypto)); - } - } - else - { - *header += *rest; - delete rest; - Comm::sendToServer(header); - delete header; - } -} // finalizeConnectionRequest - //----------------------------------------------------------------------------- void ClientLobby::receivePlayerVote(Event* event) { @@ -1031,10 +1036,12 @@ void ClientLobby::connectionRefused(Event* event) void ClientLobby::startGame(Event* event) { World::getWorld()->setPhase(WorldStatus::SERVER_READY_PHASE); - uint64_t start_time = event->data().getUInt64(); + + auto packet = event->getPacket(); + uint64_t start_time = packet.start_time; powerup_manager->setRandomSeed(start_time); - unsigned check_structure_count = event->data().getUInt8(); + unsigned check_structure_count = packet.check_count; LinearWorld* lw = dynamic_cast(World::getWorld()); if (lw) lw->handleServerCheckStructureCount(check_structure_count); @@ -1042,7 +1049,7 @@ void ClientLobby::startGame(Event* event) NetworkItemManager* nim = dynamic_cast (Track::getCurrentTrack()->getItemManager()); assert(nim); - nim->restoreCompleteState(event->data()); + nim->restoreCompleteState(packet.nim_complete_state); core::stringw err_msg = _("Failed to start the network game."); // Different stk process thread may have different stk host @@ -1207,7 +1214,7 @@ void ClientLobby::raceFinished(Event* event) if (has_ranking_changes && packet.point_changes.has_value()) { PointChangesPacket subpacket = packet.point_changes.get_value(); - unsigned count = subpacket.player_count; + // unsigned count = subpacket.player_count; m_ranking_changes = subpacket.changes; } } @@ -1346,7 +1353,15 @@ void ClientLobby::liveJoinAcknowledged(Event* event) unsigned player_count = subpacket.players_size; for (unsigned i = 0; i < player_count; ++i) players.push_back(decodePlayer(subpacket.all_players[i])); - getPlayersAddonKartType(subpacket.players_kart_data, players); + + if (NetworkConfig::get()->getServerCapabilities().find("real_addon_karts") != + NetworkConfig::get()->getServerCapabilities().end()) + { + for (unsigned i = 0; i < players.size(); i++) + { + players[i]->setKartData(KartData(subpacket.players_kart_data[i])); + } + } w->resetElimination(); for (unsigned i = 0; i < players.size(); i++) { @@ -1906,7 +1921,7 @@ void ClientLobby::handleClientCommand(const std::string& cmd) } // handleClientCommand // ---------------------------------------------------------------------------- -AssetsPacket ClientLobby::getKartsTracksNetworkString() +AssetsPacket ClientLobby::getKartsTracksPacket() { std::vector all_k; for (unsigned i = 0; i < kart_properties_manager->getNumberOfKarts(); i++) @@ -1936,14 +1951,14 @@ AssetsPacket ClientLobby::getKartsTracksNetworkString() packet.maps.push_back(track); return packet; -} // getKartsTracksNetworkString +} // getKartsTracksPacket // ---------------------------------------------------------------------------- void ClientLobby::updateAssetsToServer() { NetworkString* ns = getNetworkString(1); NewAssetsPacket packet; - packet.assets = getKartsTracksNetworkString(); + packet.assets = getKartsTracksPacket(); packet.toNetworkString(ns); Comm::sendToServer(ns, PRM_RELIABLE); delete ns; diff --git a/src/network/protocols/client_lobby.hpp b/src/network/protocols/client_lobby.hpp index e0839cd7e47..2b630feaf8e 100644 --- a/src/network/protocols/client_lobby.hpp +++ b/src/network/protocols/client_lobby.hpp @@ -126,8 +126,6 @@ class ClientLobby : public LobbyProtocol std::set m_available_tracks; void addAllPlayers(Event* event); - void finalizeConnectionRequest(NetworkString* header, - BareNetworkString* rest, bool encrypt); std::map m_disconnected_msg; @@ -148,9 +146,8 @@ class ClientLobby : public LobbyProtocol decodePlayer(const EncodedSinglePlayerPacket& packet, std::shared_ptr peer = nullptr, bool* is_spectator = NULL) const; - void getPlayersAddonKartType(const BareNetworkString& data, - std::vector >& players) const; - AssetsPacket getKartsTracksNetworkString(); + + AssetsPacket getKartsTracksPacket(); void doInstallAddonsPack(); public: ClientLobby(std::shared_ptr s); diff --git a/src/network/protocols/server_lobby.cpp b/src/network/protocols/server_lobby.cpp index ee374fa973a..b1040adc17e 100644 --- a/src/network/protocols/server_lobby.cpp +++ b/src/network/protocols/server_lobby.cpp @@ -2354,7 +2354,7 @@ void ServerLobby::connectionRequested(Event* event) } // Check server version - int version = conn_packet.version; + int version = conn_packet.server_version; auto& stk_config = STKConfig::get(); @@ -2372,10 +2372,10 @@ void ServerLobby::connectionRequested(Event* event) Log::verbose("ServerLobby", "Player refused: wrong server version"); return; } - std::string user_version = conn_packet.user_version; + std::string user_version = conn_packet.user_agent; event->getPeer()->setUserVersion(user_version); - unsigned list_caps = conn_packet.capabilities_count; + unsigned list_caps = conn_packet.capabilities_size; std::set caps; for (unsigned i = 0; i < list_caps; i++) { @@ -2395,10 +2395,10 @@ void ServerLobby::connectionRequested(Event* event) if (!handleAssetsAndAddonScores(event->getPeerSP(), client_karts, client_maps)) return; - unsigned player_count = conn_packet.players_count; + unsigned player_count = conn_packet.player_count; uint32_t online_id = 0; uint32_t encrypted_size = 0; - online_id = conn_packet.online_id; + online_id = conn_packet.id; encrypted_size = conn_packet.encrypted_size; // Will be disconnected if banned by IP @@ -2479,32 +2479,38 @@ void ServerLobby::connectionRequested(Event* event) if (getSettings()->hasAiHandling() && peer->isAIPeer()) m_ai_peer = peer; - if (encrypted_size != 0) + // Second condition was not present before + if (encrypted_size != 0 && conn_packet.player_info_encrypted.has_value()) { - m_pending_connection[peer] = std::make_pair(online_id, - BareNetworkString(data.getCurrentData(), encrypted_size)); + NetworkString* ns = new NetworkString(); + auto encrypted = conn_packet.player_info_encrypted.get_value(); + encrypted.toNetworkString(ns); + m_pending_connection[peer] = std::make_pair(online_id, *(BareNetworkString*)ns); } else { core::stringw online_name; - if (online_id > 0) - data.decodeStringW(&online_name); - handleUnencryptedConnection(peer, data, online_id, online_name, + if (online_id > 0 && /* ??? */ conn_packet.player_name.has_value()) + online_name = conn_packet.player_name.get_value(); + handleUnencryptedConnection(peer, conn_packet.player_info_unencrypted, online_id, online_name, false/*is_pending_connection*/); } } // connectionRequested //----------------------------------------------------------------------------- void ServerLobby::handleUnencryptedConnection(std::shared_ptr peer, - BareNetworkString& data, uint32_t online_id, + const Optional& opt, uint32_t online_id, const core::stringw& online_name, bool is_pending_connection, std::string country_code) { - if (data.size() < 2) return; + if (!opt.has_value()) + return; + + RestConnectionRequestPacket packet = opt.get_value(); // Check for password std::string password; - data.decodeString(&password); + password = packet.private_server_password; const std::string& server_pw = getSettings()->getPrivateServerPassword(); if (online_id > 0) { @@ -2543,7 +2549,7 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr peer, // Check again max players and duplicated player in ranked server, // if this is a pending connection unsigned total_players = 0; - unsigned player_count = data.getUInt8(); + unsigned player_count = packet.player_count; if (is_pending_connection) { @@ -2593,8 +2599,9 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr peer, std::string utf8_online_name = StringUtils::wideToUtf8(online_name); for (unsigned i = 0; i < player_count; i++) { - core::stringw name; - data.decodeStringW(&name); + ConnectingPlayerPacket player_packet = packet.players[i]; + + core::stringw name = player_packet.name; // 30 to make it consistent with stk-addons max user name length if (name.empty()) name = L"unnamed"; @@ -2602,8 +2609,8 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr peer, name = name.subString(0, 30); std::string utf8_name = StringUtils::wideToUtf8(name); - float default_kart_color = data.getFloat(); - HandicapLevel handicap = (HandicapLevel)data.getUInt8(); + float default_kart_color = player_packet.default_kart_color; + HandicapLevel handicap = (HandicapLevel)player_packet.handicap; auto player = std::make_shared (peer, i == 0 && !online_name.empty() && !peer->isAIPeer() ? online_name : name, @@ -2677,22 +2684,22 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr peer, auto& stk_config = STKConfig::get(); NetworkString* ns = getNetworkString(4); - ConnectionAcceptedPacket packet; + ConnectionAcceptedPacket ack_packet; // connection success -- return the host id of peer float auto_start_timer = getTimeUntilExpiration(); - packet.host_id = peer->getHostId(); - packet.server_version = ServerConfig::m_server_version; - packet.capabilities_size = (uint16_t)stk_config->m_network_capabilities.size(); + ack_packet.host_id = peer->getHostId(); + ack_packet.server_version = ServerConfig::m_server_version; + ack_packet.capabilities_size = (uint16_t)stk_config->m_network_capabilities.size(); for (const std::string& cap : stk_config->m_network_capabilities) - packet.capabilities.push_back(cap); + ack_packet.capabilities.push_back(cap); - packet.auto_start_timer = auto_start_timer; - packet.state_frequency = getSettings()->getStateFrequency(); - packet.chat_allowed = getChatManager()->getChat(); - packet.reports_allowed = playerReportsTableExists(); + ack_packet.auto_start_timer = auto_start_timer; + ack_packet.state_frequency = getSettings()->getStateFrequency(); + ack_packet.chat_allowed = getChatManager()->getChat(); + ack_packet.reports_allowed = playerReportsTableExists(); - packet.toNetworkString(ns); + ack_packet.toNetworkString(ns); peer->setSpectator(false); @@ -3244,9 +3251,24 @@ bool ServerLobby::decryptConnectionRequest(std::shared_ptr peer, if (crypto->decryptConnectionRequest(data)) { peer->setCrypto(std::move(crypto)); + + RestConnectionRequestPacket packet; + NetworkString* ns = new NetworkString(); + ns->operator+=(data); + try + { + packet.fromNetworkString(ns); + delete ns; + } + catch (...) + { + return false; + } + Optional opt; + opt = packet; Log::info("ServerLobby", "%s validated", StringUtils::wideToUtf8(online_name).c_str()); - handleUnencryptedConnection(peer, data, online_id, + handleUnencryptedConnection(peer, opt, online_id, online_name, true/*is_pending_connection*/, country_code); return true; } diff --git a/src/network/protocols/server_lobby.hpp b/src/network/protocols/server_lobby.hpp index d463a64f327..b5ae03994c8 100644 --- a/src/network/protocols/server_lobby.hpp +++ b/src/network/protocols/server_lobby.hpp @@ -235,7 +235,7 @@ class ServerLobby : public LobbyProtocol, public LobbyContextUser } void handlePendingConnection(); void handleUnencryptedConnection(std::shared_ptr peer, - BareNetworkString& data, + const Optional& opt, uint32_t online_id, const irr::core::stringw& online_name, bool is_pending_connection, diff --git a/src/states_screens/online/network_kart_selection.cpp b/src/states_screens/online/network_kart_selection.cpp index 532dc99c831..10e962aa53a 100644 --- a/src/states_screens/online/network_kart_selection.cpp +++ b/src/states_screens/online/network_kart_selection.cpp @@ -157,7 +157,7 @@ void NetworkKartSelectionScreen::allPlayersDone() { LiveJoinRequestPacket packet; packet.is_spectator = false; - packet.player_karts = std::make_shared(karts_packet); + packet.player_karts = karts_packet; packet.toNetworkString(&kart); } else diff --git a/src/tracks/check_structure.hpp b/src/tracks/check_structure.hpp index 27c79c71876..30021e427ad 100644 --- a/src/tracks/check_structure.hpp +++ b/src/tracks/check_structure.hpp @@ -20,7 +20,9 @@ #define HEADER_CHECK_STRUCTURE_HPP #include +#include +#include "network/packet_types.hpp" #include "utils/aligned_array.hpp" #include "utils/vec3.hpp" diff --git a/src/utils/lobby_gp_manager.cpp b/src/utils/lobby_gp_manager.cpp index 7d4644b1a82..cf2636e37a1 100644 --- a/src/utils/lobby_gp_manager.cpp +++ b/src/utils/lobby_gp_manager.cpp @@ -235,8 +235,6 @@ GPScoresPacket LobbyGPManager::updateGPScores(std::vector& gp_changes) } GPScoresPacket packet; - packet.fastest_lap = fastest_lap; - packet.fastest_kart = fastest_kart_wide; packet.total_gp_tracks = (uint8_t)game_setup->getTotalGrandPrixTracks(); packet.all_tracks_size = (uint8_t)game_setup->getAllTracks().size(); diff --git a/src/utils/lobby_gp_manager.hpp b/src/utils/lobby_gp_manager.hpp index 9127eeba82e..276ac6c08c3 100644 --- a/src/utils/lobby_gp_manager.hpp +++ b/src/utils/lobby_gp_manager.hpp @@ -20,6 +20,7 @@ #define LOBBY_GP_MANAGER_HPP #include "irrString.h" +#include "network/packet_types.hpp" #include "utils/track_filter.hpp" #include "utils/lobby_context.hpp" From f7210c6455a7a1f45ea8272a4a346ea77cf4c7bd Mon Sep 17 00:00:00 2001 From: kimden <23140380+kimden@users.noreply.github.com> Date: Sun, 13 Apr 2025 14:47:20 +0400 Subject: [PATCH 14/34] Linkable version (won't work tho) --- src/network/network_string.cpp | 74 ++++++++++++++++++++++++++ src/network/protocols/server_lobby.cpp | 2 +- 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/src/network/network_string.cpp b/src/network/network_string.cpp index b144040d523..363288f1fce 100644 --- a/src/network/network_string.cpp +++ b/src/network/network_string.cpp @@ -247,6 +247,18 @@ std::string BareNetworkString::getLogMessage(const std::string &indent) const // Generic encoders/decoders +template<> +void NetworkString::encodeSpecific(const uint64_t& value) +{ + addUInt64(value); +} // encode(uint64_t) +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +template<> +void NetworkString::decodeSpecific(uint64_t& value) +{ + value = getUInt64(); +} // decodeSpecific(uint64_t) +//----------------------------------------------------------------------------- template<> void NetworkString::encodeSpecific(const uint32_t& value) { @@ -260,6 +272,18 @@ void NetworkString::decodeSpecific(uint32_t& value) } // decodeSpecific(uint32_t) //----------------------------------------------------------------------------- template<> +void NetworkString::encodeSpecific(const uint16_t& value) +{ + addUInt16(value); +} // encode(uint16_t) +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +template<> +void NetworkString::decodeSpecific(uint16_t& value) +{ + value = getUInt16(); +} // decodeSpecific(uint16_t) +//----------------------------------------------------------------------------- +template<> void NetworkString::encodeSpecific(const uint8_t& value) { addUInt8(value); @@ -307,6 +331,56 @@ void NetworkString::decodeSpecific(bool& value) value = getUInt8() == 1; } // decodeSpecific(bool) //----------------------------------------------------------------------------- +template<> +void NetworkString::encodeSpecific(const Vec3& value) +{ + add(value); +} // encode(Vec3) +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +template<> +void NetworkString::decodeSpecific(Vec3& value) +{ + value = getVec3(); +} // decodeSpecific(Vec3) +//----------------------------------------------------------------------------- +template<> +void NetworkString::encodeSpecific(const btQuaternion& value) +{ + add(value); +} // encode(btQuaternion) +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +template<> +void NetworkString::decodeSpecific(btQuaternion& value) +{ + value = getQuat(); +} // decodeSpecific(btQuaternion) +//----------------------------------------------------------------------------- +template<> +void NetworkString::encodeSpecific(const float& value) +{ + addFloat(value); +} // encodeSpecific(float) +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +template<> +void NetworkString::decodeSpecific(float& value) +{ + value = getFloat(); +} // decodeSpecific(float) +// //----------------------------------------------------------------------------- +template<> +void NetworkString::encodeSpecific(const KartTeam& value) +{ + encodeSpecific((uint8_t)value); +} // encodeSpecific(KartTeam) +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +template<> +void NetworkString::decodeSpecific(KartTeam& value) +{ + uint8_t u8; + decodeSpecific(u8); + value = (KartTeam)u8; +} // decodeSpecific(KartTeam) +// //----------------------------------------------------------------------------- // template<> // void NetworkString::encodeSpecific(const T& value) // { diff --git a/src/network/protocols/server_lobby.cpp b/src/network/protocols/server_lobby.cpp index b1040adc17e..de2a2a4c842 100644 --- a/src/network/protocols/server_lobby.cpp +++ b/src/network/protocols/server_lobby.cpp @@ -1122,7 +1122,7 @@ void ServerLobby::liveJoinRequest(Event* event) std::vector > players = getLivePlayers(); - NetworkString* ns; + NetworkString* ns = new NetworkString(); LoadWorldPacket load_world_packet = getLoadWorldMessage(players, true/*live_join*/); load_world_packet.toNetworkString(ns); peer->sendNetstring(ns, PRM_RELIABLE); From ed7dd0d0089601c9b90d960a8aaa8fd33b9786aa Mon Sep 17 00:00:00 2001 From: kimden <23140380+kimden@users.noreply.github.com> Date: Sun, 13 Apr 2025 17:15:03 +0400 Subject: [PATCH 15/34] Try to fix some compilation errors (2) --- src/modes/free_for_all.cpp | 2 ++ src/network/packet_types.cpp | 4 ++-- src/network/packet_types.hpp | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/modes/free_for_all.cpp b/src/modes/free_for_all.cpp index 9a510f24437..9e51f628cb7 100644 --- a/src/modes/free_for_all.cpp +++ b/src/modes/free_for_all.cpp @@ -308,6 +308,8 @@ std::shared_ptr FreeForAll::saveCompleteState(std::shared_ptr(); for (unsigned i = 0; i < m_scores.size(); i++) packet->scores.push_back(m_scores[i]); + + return packet; } // saveCompleteState // ---------------------------------------------------------------------------- diff --git a/src/network/packet_types.cpp b/src/network/packet_types.cpp index 02475c6a817..9c76f211f2a 100644 --- a/src/network/packet_types.cpp +++ b/src/network/packet_types.cpp @@ -23,7 +23,7 @@ //---------------------- To NetworkString ------------------------------------- #define DEFINE_CLASS(Name) \ -inline void Name::toNetworkString(NetworkString* ns) const \ +void Name::toNetworkString(NetworkString* ns) const \ { #define DEFINE_DERIVED_CLASS(Name, Parent) DEFINE_CLASS(Name) @@ -88,7 +88,7 @@ inline void Name::toNetworkString(NetworkString* ns) const \ //---------------------- From NetworkString ----------------------------------- #define DEFINE_CLASS(Name) \ -inline void Name::fromNetworkString(NetworkString* ns) \ +void Name::fromNetworkString(NetworkString* ns) \ { #define DEFINE_DERIVED_CLASS(Name, Parent) DEFINE_CLASS(Name) diff --git a/src/network/packet_types.hpp b/src/network/packet_types.hpp index 7593d3ed7cd..234f5fe5d04 100644 --- a/src/network/packet_types.hpp +++ b/src/network/packet_types.hpp @@ -163,12 +163,14 @@ constexpr bool UNUSED = false; #define DEFINE_CLASS(Name) \ struct Name: public Packet { \ public: \ + virtual ~Name() {} \ virtual void toNetworkString(NetworkString* ns) const OVERRIDE; \ virtual void fromNetworkString(NetworkString* ns) OVERRIDE; #define DEFINE_DERIVED_CLASS(Name, Parent) \ struct Name: public Parent { \ public: \ + virtual ~Name() {} \ virtual void toNetworkString(NetworkString* ns) const OVERRIDE; \ virtual void fromNetworkString(NetworkString* ns) OVERRIDE; From 86e0431f38bced1bd836dbfec4bf0accdcae8a20 Mon Sep 17 00:00:00 2001 From: kimden <23140380+kimden@users.noreply.github.com> Date: Sun, 13 Apr 2025 18:34:59 +0400 Subject: [PATCH 16/34] Fix more warnings and errors (hopefully) --- src/items/item.hpp | 2 +- src/network/network_player_profile.hpp | 2 +- src/network/packet_types.hpp | 8 ++++---- src/utils/lobby_settings.hpp | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/items/item.hpp b/src/items/item.hpp index b72009dc18e..d535f3d1333 100644 --- a/src/items/item.hpp +++ b/src/items/item.hpp @@ -35,7 +35,7 @@ class BareNetworkString; class AbstractKart; class LODNode; -struct ItemStatePacket; +class ItemStatePacket; namespace irr { diff --git a/src/network/network_player_profile.hpp b/src/network/network_player_profile.hpp index 6c8383670fb..51ef182fb0a 100644 --- a/src/network/network_player_profile.hpp +++ b/src/network/network_player_profile.hpp @@ -36,7 +36,7 @@ class STKPeer; class GenericDecorator; enum KartTeam : int8_t; enum HandicapLevel : uint8_t; -struct EncodedSinglePlayerPacket; +class EncodedSinglePlayerPacket; /*! \class NetworkPlayerProfile * \brief Contains the profile of a player. diff --git a/src/network/packet_types.hpp b/src/network/packet_types.hpp index 234f5fe5d04..c8fe011cbf5 100644 --- a/src/network/packet_types.hpp +++ b/src/network/packet_types.hpp @@ -20,7 +20,7 @@ #define PACKET_TYPES_HPP // #include "network/network_string.hpp" -#include "network/protocol.hpp" +// #include "network/protocol.hpp" #include "network/protocols/game_event_types.hpp" #include "utils/cpp2011.hpp" #include "utils/types.hpp" @@ -110,7 +110,7 @@ namespace const std::string REAL_ADDON_KARTS = "real_addon_karts"; } -struct Checkable +class Checkable { private: uint32_t m_state = 0; @@ -161,14 +161,14 @@ constexpr bool UNUSED = false; //---------------------- Initialization --------------------------------------- #define DEFINE_CLASS(Name) \ -struct Name: public Packet { \ +class Name: public Packet { \ public: \ virtual ~Name() {} \ virtual void toNetworkString(NetworkString* ns) const OVERRIDE; \ virtual void fromNetworkString(NetworkString* ns) OVERRIDE; #define DEFINE_DERIVED_CLASS(Name, Parent) \ -struct Name: public Parent { \ +class Name: public Parent { \ public: \ virtual ~Name() {} \ virtual void toNetworkString(NetworkString* ns) const OVERRIDE; \ diff --git a/src/utils/lobby_settings.hpp b/src/utils/lobby_settings.hpp index c0d6db2d59a..ed3a2826cc4 100644 --- a/src/utils/lobby_settings.hpp +++ b/src/utils/lobby_settings.hpp @@ -34,7 +34,7 @@ class STKPeer; class Tournament; class Track; struct GameInfo; -struct DefaultVotePacket; +class DefaultVotePacket; /** @brief A class that manipulates server settings, such as resetting, * scoring, goal policies, etc. Might be split into a few parts later, From f0d625cebac700f6b819eb62e635f2c92ace328c Mon Sep 17 00:00:00 2001 From: kimden <23140380+kimden@users.noreply.github.com> Date: Mon, 14 Apr 2025 00:22:59 +0400 Subject: [PATCH 17/34] Read optionals if possible, remove unnecessary assets packet The next step is making sure types in packets are differentiated by their encoding/decoding method --- src/network/network_string.hpp | 2 ++ src/network/packet_types.cpp | 7 ++++++- src/network/packet_types_base.hpp | 18 +++++++++--------- src/network/protocols/client_lobby.cpp | 6 +++--- src/network/protocols/client_lobby.hpp | 2 +- src/network/protocols/server_lobby.cpp | 2 +- 6 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/network/network_string.hpp b/src/network/network_string.hpp index 7c8fcb92a2a..4295463b7b8 100644 --- a/src/network/network_string.hpp +++ b/src/network/network_string.hpp @@ -194,6 +194,8 @@ friend class Crypto; // ------------------------------------------------------------------------ int getCurrentOffset() const { return m_current_offset; } // ------------------------------------------------------------------------ + void setCurrentOffset(int value) const { m_current_offset = value; } + // ------------------------------------------------------------------------ /** Returns the remaining length of the network string. */ unsigned int size() const { return (int)m_buffer.size()-m_current_offset; } diff --git a/src/network/packet_types.cpp b/src/network/packet_types.cpp index 9c76f211f2a..44f164463d7 100644 --- a/src/network/packet_types.cpp +++ b/src/network/packet_types.cpp @@ -109,8 +109,13 @@ void Name::fromNetworkString(NetworkString* ns) \ // We send it if it exists, and receive only if the condition is true #define DEFINE_FIELD_OPTIONAL(Type, Var, Condition) \ if (Condition) { \ + int temp_prev_offset = ns->getCurrentOffset(); \ Type temp_##Var; \ - ns->decode(temp_##Var); \ + try { \ + ns->decode(temp_##Var); \ + } catch (...) { \ + ns->setCurrentOffset(temp_prev_offset); \ + } \ Var = temp_##Var; \ } diff --git a/src/network/packet_types_base.hpp b/src/network/packet_types_base.hpp index ee0cc9e9b04..348409f90ad 100644 --- a/src/network/packet_types_base.hpp +++ b/src/network/packet_types_base.hpp @@ -355,12 +355,12 @@ DEFINE_CLASS(ServerInfoPacket) RELIABLE(true) END_DEFINE_CLASS(ServerInfoPacket) -DEFINE_CLASS(AssetsPacket) - DEFINE_FIELD(uint16_t, karts_number) - DEFINE_VECTOR(std::string, karts_number, karts) - DEFINE_FIELD(uint16_t, maps_number) - DEFINE_VECTOR(std::string, maps_number, maps) -END_DEFINE_CLASS(AssetsPacket) +// DEFINE_CLASS(AssetsPacket) +// DEFINE_FIELD(uint16_t, karts_number) +// DEFINE_VECTOR(std::string, karts_number, karts) +// DEFINE_FIELD(uint16_t, maps_number) +// DEFINE_VECTOR(std::string, maps_number, maps) +// END_DEFINE_CLASS(AssetsPacket) DEFINE_CLASS(AssetsPacket2) DEFINE_FIELD(uint16_t, karts_number) @@ -372,7 +372,7 @@ END_DEFINE_CLASS(AssetsPacket2) DEFINE_CLASS(NewAssetsPacket) PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, false) DEFINE_TYPE(uint8_t, type, LE_ASSETS_UPDATE) - DEFINE_FIELD(AssetsPacket, assets) + DEFINE_FIELD(AssetsPacket2, assets) RELIABLE(true) END_DEFINE_CLASS(NewAssetsPacket) @@ -659,14 +659,14 @@ DEFINE_CLASS(ConnectionRequestedPacket) DEFINE_FIELD(std::string, user_agent) DEFINE_FIELD(uint16_t, capabilities_size) DEFINE_VECTOR(std::string, capabilities_size, capabilities) - DEFINE_FIELD(AssetsPacket, assets) + DEFINE_FIELD(AssetsPacket2, assets) DEFINE_FIELD(uint8_t, player_count) DEFINE_FIELD(uint32_t, id) DEFINE_FIELD(uint32_t, encrypted_size) // 0 if not encrypted DEFINE_FIELD_OPTIONAL(widestr, player_name, id != 0 && encrypted_size == 0) DEFINE_FIELD_OPTIONAL(EncryptedBuffer, player_info_encrypted, encrypted_size != 0) - DEFINE_FIELD_OPTIONAL(RestConnectionRequestPacket, player_info_unencrypted, encrypted_size == 0 && check(4)) /* I really don't know, it can be sent if encryption failed, very bad */ + DEFINE_FIELD_OPTIONAL(RestConnectionRequestPacket, player_info_unencrypted, encrypted_size == 0) END_DEFINE_CLASS(ConnectionRequestedPacket) diff --git a/src/network/protocols/client_lobby.cpp b/src/network/protocols/client_lobby.cpp index 0a33402e83a..cca8669c7c8 100644 --- a/src/network/protocols/client_lobby.cpp +++ b/src/network/protocols/client_lobby.cpp @@ -479,7 +479,7 @@ void ClientLobby::update(int ticks) { // Failed packet.encrypted_size = 0; - // packet.player_info_unencrypted = subpacket; + packet.player_info_unencrypted = subpacket; encryption = false; if (id != 0) @@ -1921,7 +1921,7 @@ void ClientLobby::handleClientCommand(const std::string& cmd) } // handleClientCommand // ---------------------------------------------------------------------------- -AssetsPacket ClientLobby::getKartsTracksPacket() +AssetsPacket2 ClientLobby::getKartsTracksPacket() { std::vector all_k; for (unsigned i = 0; i < kart_properties_manager->getNumberOfKarts(); i++) @@ -1940,7 +1940,7 @@ AssetsPacket ClientLobby::getKartsTracksPacket() if (all_t.size() >= 65536) all_t.resize(65535); - AssetsPacket packet; + AssetsPacket2 packet; packet.karts_number = (uint16_t)all_k.size(); packet.maps_number = (uint16_t)all_t.size(); diff --git a/src/network/protocols/client_lobby.hpp b/src/network/protocols/client_lobby.hpp index 2b630feaf8e..9d0d049c277 100644 --- a/src/network/protocols/client_lobby.hpp +++ b/src/network/protocols/client_lobby.hpp @@ -147,7 +147,7 @@ class ClientLobby : public LobbyProtocol std::shared_ptr peer = nullptr, bool* is_spectator = NULL) const; - AssetsPacket getKartsTracksPacket(); + AssetsPacket2 getKartsTracksPacket(); void doInstallAddonsPack(); public: ClientLobby(std::shared_ptr s); diff --git a/src/network/protocols/server_lobby.cpp b/src/network/protocols/server_lobby.cpp index de2a2a4c842..84c08d4d3a0 100644 --- a/src/network/protocols/server_lobby.cpp +++ b/src/network/protocols/server_lobby.cpp @@ -2331,7 +2331,7 @@ void ServerLobby::connectionRequested(Event* event) { std::shared_ptr peer = event->getPeerSP(); auto conn_packet = event->getPacket(); - if (!checkDataSize(event, 14)) return; + // if (!checkDataSize(event, 14)) return; peer->cleanPlayerProfiles(); From 98e8b6eb7e79269478c76626deda7a6a84bba3be Mon Sep 17 00:00:00 2001 From: kimden <23140380+kimden@users.noreply.github.com> Date: Tue, 15 Apr 2025 23:59:18 +0400 Subject: [PATCH 18/34] Fixes allowing joining and playing Not everything of course is implemented, bugs exist too, in particular, ownerless start button doesn't work after racing --- src/modes/soccer_world.cpp | 2 +- src/network/packet_types.cpp | 8 ++++++++ src/network/packet_types.hpp | 2 ++ src/network/packet_types_base.hpp | 7 +++---- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/modes/soccer_world.cpp b/src/modes/soccer_world.cpp index f8ef417c521..28208c56501 100644 --- a/src/modes/soccer_world.cpp +++ b/src/modes/soccer_world.cpp @@ -703,7 +703,7 @@ void SoccerWorld::onCheckGoalTriggered(bool first_goal) NetworkString p(PROTOCOL_GAME_EVENTS); NetworkString p_1_1(PROTOCOL_GAME_EVENTS); packet.toNetworkString(&p); - packet.toNetworkString(&p_1_1); + packet_1_1.toNetworkString(&p_1_1); auto peers = STKHost::get()->getPeers(); for (auto& peer : peers) diff --git a/src/network/packet_types.cpp b/src/network/packet_types.cpp index 44f164463d7..73f36407e4f 100644 --- a/src/network/packet_types.cpp +++ b/src/network/packet_types.cpp @@ -40,6 +40,9 @@ void Name::toNetworkString(NetworkString* ns) const \ #define DEFINE_FIELD(Type, Var) \ ns->encode(Var); +#define DEFINE_FIELD16(Type, Var) \ + ns->encodeString16(Var); + #define DEFINE_FIELD_PTR(Type, Var) \ if (Var) \ ns->encode(*Var); @@ -74,6 +77,7 @@ void Name::toNetworkString(NetworkString* ns) const \ #undef PROTOCOL_TYPE #undef AUX_VAR #undef DEFINE_FIELD +#undef DEFINE_FIELD16 #undef DEFINE_FIELD_PTR #undef DEFINE_TYPE #undef DEFINE_FIELD_OPTIONAL @@ -100,6 +104,9 @@ void Name::fromNetworkString(NetworkString* ns) \ #define DEFINE_FIELD(Type, Var) \ ns->decode(Var); +#define DEFINE_FIELD16(Type, Var) \ + ns->decodeString16(&Var); + // Same as optional but unconditional #define DEFINE_FIELD_PTR(Type, Var) \ Type temp_##Var; \ @@ -146,6 +153,7 @@ void Name::fromNetworkString(NetworkString* ns) \ #undef PROTOCOL_TYPE #undef AUX_VAR #undef DEFINE_FIELD +#undef DEFINE_FIELD16 #undef DEFINE_FIELD_PTR #undef DEFINE_TYPE #undef DEFINE_FIELD_OPTIONAL diff --git a/src/network/packet_types.hpp b/src/network/packet_types.hpp index c8fe011cbf5..c45eeb66021 100644 --- a/src/network/packet_types.hpp +++ b/src/network/packet_types.hpp @@ -177,6 +177,7 @@ class Name: public Parent { \ #define PROTOCOL_TYPE(Type, Sync) #define AUX_VAR(Type, Var) Type Var; #define DEFINE_FIELD(Type, Var) Type Var; +#define DEFINE_FIELD16(Type, Var) Type Var; #define DEFINE_FIELD_PTR(Type, Var) std::shared_ptr Var; #define DEFINE_FIELD_OPTIONAL(Type, Var, Condition) Optional Var; #define DEFINE_TYPE(Type, Var, Value) Type Var; @@ -191,6 +192,7 @@ class Name: public Parent { \ #undef PROTOCOL_TYPE #undef AUX_VAR #undef DEFINE_FIELD +#undef DEFINE_FIELD16 #undef DEFINE_FIELD_PTR #undef DEFINE_TYPE #undef DEFINE_FIELD_OPTIONAL diff --git a/src/network/packet_types_base.hpp b/src/network/packet_types_base.hpp index 348409f90ad..92909402357 100644 --- a/src/network/packet_types_base.hpp +++ b/src/network/packet_types_base.hpp @@ -47,7 +47,6 @@ #include using widestr = irr::core::stringw; -using widestr16 = irr::core::stringw; // but encodeString16 // Note that bools are encoded using int8_t @@ -287,7 +286,7 @@ END_DEFINE_CLASS(LiveJoinPacket) DEFINE_CLASS(ChatPacket) PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, true) DEFINE_TYPE(uint8_t, type, LE_CHAT) - DEFINE_FIELD(widestr16, message) // use encodeString16 ! max len is 360 for server, 1000 for client + DEFINE_FIELD16(widestr, message) // use encodeString16 ! max len is 360 for server, 1000 for client DEFINE_FIELD_OPTIONAL(KartTeam, kart_team, check(0)) /* KartTeam is uint8_t, I have no idea when */ RELIABLE(true) END_DEFINE_CLASS(ChatPacket) @@ -310,7 +309,7 @@ DEFINE_CLASS(ReportRequestPacket) PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, false) DEFINE_TYPE(uint8_t, type, LE_REPORT_PLAYER) DEFINE_FIELD(uint32_t, host_id) - DEFINE_FIELD(widestr16, info) + DEFINE_FIELD16(widestr, info) RELIABLE(true) END_DEFINE_CLASS(ReportRequestPacket) @@ -349,7 +348,7 @@ DEFINE_CLASS(ServerInfoPacket) DEFINE_FIELD_OPTIONAL(uint8_t, extra_server_info, has_extra_server_info) DEFINE_FIELD(uint8_t, min_start_game_players) DEFINE_FIELD(float, start_game_counter) - DEFINE_FIELD(widestr16, motd) + DEFINE_FIELD16(widestr, motd) DEFINE_FIELD(bool, is_configurable) DEFINE_FIELD(bool, has_live_players) RELIABLE(true) From c4432f00b7416d1c5675f5723de26ae0694f5643 Mon Sep 17 00:00:00 2001 From: kimden <23140380+kimden@users.noreply.github.com> Date: Fri, 18 Apr 2025 02:51:09 +0400 Subject: [PATCH 19/34] Processed some packets in client lobby --- src/network/game_setup.cpp | 7 +- src/network/packet_types_base.hpp | 2 +- src/network/protocols/client_lobby.cpp | 115 +++++++++++----------- src/network/protocols/command_manager.cpp | 7 +- 4 files changed, 64 insertions(+), 67 deletions(-) diff --git a/src/network/game_setup.cpp b/src/network/game_setup.cpp index 9a14742b099..f4860db1b95 100644 --- a/src/network/game_setup.cpp +++ b/src/network/game_setup.cpp @@ -132,14 +132,15 @@ ServerInfoPacket GameSetup::addServerInfo() if (!isGrandPrixStarted()) cur_track = 0; - packet.has_extra_server_info = cur_track; - packet.extra_server_info = m_extra_server_info; + packet.has_extra_server_info = 2; + packet.extra_server_info.push_back(cur_track); + packet.extra_server_info.push_back(m_extra_server_info); } else { // Soccer mode packet.has_extra_server_info = 1; - packet.extra_server_info = m_extra_server_info; + packet.extra_server_info.push_back(m_extra_server_info); } } else diff --git a/src/network/packet_types_base.hpp b/src/network/packet_types_base.hpp index 92909402357..9930caf4e99 100644 --- a/src/network/packet_types_base.hpp +++ b/src/network/packet_types_base.hpp @@ -345,7 +345,7 @@ DEFINE_CLASS(ServerInfoPacket) DEFINE_FIELD(uint8_t, extra_spectators_zero) DEFINE_FIELD(uint8_t, game_mode) DEFINE_FIELD(uint8_t, has_extra_server_info) /* can be more than 1 - in gp it's current track number, so not bool */ - DEFINE_FIELD_OPTIONAL(uint8_t, extra_server_info, has_extra_server_info) + DEFINE_VECTOR(uint8_t, has_extra_server_info, extra_server_info) DEFINE_FIELD(uint8_t, min_start_game_players) DEFINE_FIELD(float, start_game_counter) DEFINE_FIELD16(widestr, motd) diff --git a/src/network/protocols/client_lobby.cpp b/src/network/protocols/client_lobby.cpp index cca8669c7c8..ae7b341caba 100644 --- a/src/network/protocols/client_lobby.cpp +++ b/src/network/protocols/client_lobby.cpp @@ -622,11 +622,9 @@ void ClientLobby::receivePlayerVote(Event* event) */ void ClientLobby::disconnectedPlayer(Event* event) { - if (!checkDataSize(event, 1)) return; - - NetworkString &data = event->data(); - unsigned disconnected_player_count = data.getUInt8(); - uint32_t host_id = data.getUInt32(); + auto packet = event->getPacket(); + unsigned disconnected_player_count = packet.players_size; + uint32_t host_id = packet.host_id; m_peers_votes.erase(host_id); // If in-game world exists the kart rewinder will know which player // disconnects @@ -639,8 +637,7 @@ void ClientLobby::disconnectedPlayer(Event* event) SFXManager::get()->quickSound("appear"); for (unsigned i = 0; i < disconnected_player_count; i++) { - std::string name; - data.decodeString(&name); + std::string name = packet.names[i]; if (in_game_world) continue; core::stringw player_name = StringUtils::utf8ToWide(name); @@ -661,10 +658,7 @@ void ClientLobby::disconnectedPlayer(Event* event) */ void ClientLobby::connectionAccepted(Event* event) { - // At least 8 bytes should remain now - if (!checkDataSize(event, 8)) return; - - NetworkString &data = event->data(); + auto packet = event->getPacket(); // Accepted // ======== Log::info("ClientLobby", "The server accepted the connection."); @@ -680,38 +674,36 @@ void ClientLobby::connectionAccepted(Event* event) MessageQueue::add(MessageQueue::MT_GENERIC, msg); } - uint32_t host_id = data.getUInt32(); + uint32_t host_id = packet.host_id; STKHost::get()->setMyHostId(host_id); if (auto sl = LobbyProtocol::getByType(PT_CHILD)) sl->setClientServerHostId(host_id); assert(!NetworkConfig::get()->isAddingNetworkPlayers()); - uint32_t server_version = data.getUInt32(); + uint32_t server_version = packet.server_version; NetworkConfig::get()->setJoinedServerVersion(server_version); assert(server_version != 0); m_auto_started = false; m_state.store(CONNECTED); - unsigned list_caps = data.getUInt16(); + unsigned list_caps = packet.capabilities_size; std::set caps; for (unsigned i = 0; i < list_caps; i++) { - std::string cap; - data.decodeString(&cap); - caps.insert(cap); + caps.insert(packet.capabilities[i]); } NetworkConfig::get()->setServerCapabilities(caps); - float auto_start_timer = data.getFloat(); - int state_frequency_in_server = data.getUInt32(); + float auto_start_timer = packet.auto_start_timer; + int state_frequency_in_server = packet.state_frequency; NetworkConfig::get()->setStateFrequency(state_frequency_in_server); if (!GUIEngine::isNoGraphics() && auto_start_timer != std::numeric_limits::max()) NetworkingLobby::getInstance()->setStartingTimerTo(auto_start_timer); - m_server_enabled_chat = data.getUInt8() == 1; + m_server_enabled_chat = packet.chat_allowed; if (NetworkConfig::get()->getServerCapabilities().find("report_player") != NetworkConfig::get()->getServerCapabilities().end()) - m_server_enabled_report_player = data.getUInt8() == 1; + m_server_enabled_report_player = packet.reports_allowed; } // connectionAccepted //----------------------------------------------------------------------------- @@ -728,15 +720,15 @@ void ClientLobby::handleServerInfo(Event* event) } m_first_connect = false; - NetworkString &data = event->data(); + auto packet = event->getPacket(); // Add server info uint8_t u_data; - data.decodeStringW(&str); + str = StringUtils::utf8ToWide(packet.server_name); str.removeChars(L"\n\r\t"); NetworkingLobby::getInstance()->setHeader(str); - u_data = data.getUInt8(); + u_data = packet.difficulty; const core::stringw& difficulty_name = RaceManager::get()->getDifficultyName((RaceManager::Difficulty)u_data); RaceManager::get()->setDifficulty((RaceManager::Difficulty)u_data); @@ -744,14 +736,14 @@ void ClientLobby::handleServerInfo(Event* event) total_lines += _("Difficulty: %s", difficulty_name); total_lines += L"\n"; - unsigned max_player = data.getUInt8(); + unsigned max_player = packet.max_players; //I18N: In the networking lobby total_lines += _("Max players: %d", (int)max_player); total_lines += L"\n"; // Reserved for extra spectators - u_data = data.getUInt8(); - u_data = data.getUInt8(); + u_data = packet.extra_spectators_zero; + u_data = packet.game_mode; auto game_mode = ServerConfig::getLocalGameMode(u_data); RaceManager::get()->setMinorMode(game_mode.first); // We use single mode in network even it's grand prix @@ -762,16 +754,16 @@ void ClientLobby::handleServerInfo(Event* event) total_lines += _("Game mode: %s", mode_name); total_lines += L"\n"; - uint8_t extra_server_info = data.getUInt8(); + uint8_t extra_server_info = packet.has_extra_server_info; bool grand_prix_started = false; m_game_setup->resetExtraServerInfo(); switch (extra_server_info) { case 0: break; - case 1: + case 1: // soccer { - u_data = data.getUInt8(); + u_data = packet.extra_server_info[0]; core::stringw tl = _("Time limit"); core::stringw gl = _("Goals limit"); core::stringw sgt = u_data == 0 ? tl : gl; @@ -781,11 +773,11 @@ void ClientLobby::handleServerInfo(Event* event) total_lines += L"\n"; break; } - case 2: + case 2: // GP { - unsigned cur_gp_track = data.getUInt8(); + unsigned cur_gp_track = packet.extra_server_info[0]; grand_prix_started = cur_gp_track != 0; - unsigned total_gp_track = data.getUInt8(); + unsigned total_gp_track = packet.extra_server_info[1]; m_game_setup->setGrandPrixTrack(total_gp_track); total_lines += _("Grand prix progress: %d / %d", cur_gp_track, total_gp_track); @@ -794,8 +786,8 @@ void ClientLobby::handleServerInfo(Event* event) } } // Auto start info - unsigned min_players = data.getUInt8(); - float start_timeout = data.getFloat(); + unsigned min_players = packet.min_start_game_players; + float start_timeout = packet.start_game_counter; if (!GUIEngine::isNoGraphics()) { NetworkingLobby::getInstance()->initAutoStartTimer(grand_prix_started, @@ -803,8 +795,7 @@ void ClientLobby::handleServerInfo(Event* event) } // MOTD - core::stringw motd; - data.decodeString16(&motd); + core::stringw motd = packet.motd; if (!motd.empty()) total_lines += motd; @@ -816,10 +807,10 @@ void ClientLobby::handleServerInfo(Event* event) if (!GUIEngine::isNoGraphics()) NetworkingLobby::getInstance()->addMoreServerInfo(total_lines); - bool server_config = data.getUInt8() == 1; + bool server_config = packet.is_configurable; if (!GUIEngine::isNoGraphics()) NetworkingLobby::getInstance()->toggleServerConfigButton(server_config); - m_server_live_joinable = data.getUInt8() == 1; + m_server_live_joinable = packet.has_live_players; NetworkConfig::get()->setTuxHitboxAddon(m_server_live_joinable); } // handleServerInfo @@ -906,6 +897,7 @@ void ClientLobby::updatePlayerList(Event* event) //----------------------------------------------------------------------------- void ClientLobby::handleBadTeam() { + // BadTeamPacket has no more data SFXManager::get()->quickSound("anvil"); //I18N: Display when all players are in red or blue team, which the race //will not be allowed to start @@ -924,6 +916,7 @@ void ClientLobby::handleBadConnection() //----------------------------------------------------------------------------- void ClientLobby::becomingServerOwner() { + // ServerOwnershipPacket is empty otherwise, do nothing if (STKHost::get()->isClientServer()) return; @@ -984,8 +977,8 @@ void ClientLobby::handleChat(Event* event) void ClientLobby::connectionRefused(Event* event) { if (!checkDataSize(event, 1)) return; - const NetworkString &data = event->data(); - switch ((RejectReason)data.getUInt8()) // the second byte + auto packet = event->getPacket(); + switch ((RejectReason)packet.reason) // the second byte { case RR_BUSY: STKHost::get()->setErrorMessage( @@ -995,12 +988,15 @@ void ClientLobby::connectionRefused(Event* event) { core::stringw msg = _("Connection refused: You are banned from the server."); - core::stringw reason; - data.decodeStringW(&reason); - if (!reason.empty()) + + if (packet.message.has_value()) { - msg += L"\n"; - msg += reason; + core::stringw reason = StringUtils::utf8ToWide(packet.message.get_value()); + if (!reason.empty()) + { + msg += L"\n"; + msg += reason; + } } STKHost::get()->setErrorMessage(msg); break; @@ -1082,25 +1078,26 @@ void ClientLobby::startGame(Event* event) void ClientLobby::startSelection(Event* event) { SFXManager::get()->quickSound("wee"); - const NetworkString& data = event->data(); - startVotingPeriod(data.getFloat()); - bool skip_kart_screen = data.getUInt8() == 1; - m_server_auto_game_time = data.getUInt8() == 1; - m_server_enabled_track_voting = data.getUInt8() == 1; - const unsigned kart_num = data.getUInt16(); - const unsigned track_num = data.getUInt16(); + auto packet = event->getPacket(); + startVotingPeriod(packet.voting_timeout); + bool skip_kart_screen = packet.no_kart_selection; + m_server_auto_game_time = packet.fixed_length; + m_server_enabled_track_voting = packet.track_voting; + + // kimden: I think this is already decoded somewhere? + // Worth moving to another function anyway. + const unsigned kart_num = packet.assets.karts_number; + const unsigned track_num = packet.assets.maps_number; m_available_karts.clear(); m_available_tracks.clear(); for (unsigned i = 0; i < kart_num; i++) { - std::string kart; - data.decodeString(&kart); + std::string kart = packet.assets.karts[i]; m_available_karts.insert(kart); } for (unsigned i = 0; i < track_num; i++) { - std::string track; - data.decodeString(&track); + std::string track = packet.assets.maps[i]; m_available_tracks.insert(track); } @@ -1256,11 +1253,11 @@ void ClientLobby::backToLobby(Event *event) else exitGameState(); - NetworkString &data = event->data(); + auto packet = event->getPacket(); core::stringw msg; MessageQueue::MessageType mt = MessageQueue::MT_ERROR; - switch ((BackLobbyReason)data.getUInt8()) // the second byte + switch ((BackLobbyReason)packet.reason) // the second byte { case BLR_NO_GAME_FOR_LIVE_JOIN: // I18N: Error message shown if live join or spectate failed in network diff --git a/src/network/protocols/command_manager.cpp b/src/network/protocols/command_manager.cpp index 1052eac9602..5955b78c880 100644 --- a/src/network/protocols/command_manager.cpp +++ b/src/network/protocols/command_manager.cpp @@ -691,9 +691,8 @@ void CommandManager::setupContextUser() void CommandManager::handleCommand(Event* event, std::shared_ptr peer) { - NetworkString& data = event->data(); - std::string language; - data.decodeString(&language); + auto packet = event->getPacket(); + std::string language = packet.language; Context context(getLobby(), event, peer); auto& argv = context.m_argv; @@ -704,7 +703,7 @@ void CommandManager::handleCommand(Event* event, std::shared_ptr peer) auto& target_peer = context.m_target_peer; std::shared_ptr target_peer_strong = context.m_target_peer.lock(); - data.decodeString(&cmd); + cmd = packet.command; argv = StringUtils::splitQuoted(cmd, ' ', '"', '"', '\\'); if (argv.empty()) return; From 9e4ec7207f23cff6819f1ca2a360b74eaed213af Mon Sep 17 00:00:00 2001 From: kimden <23140380+kimden@users.noreply.github.com> Date: Sat, 19 Apr 2025 01:16:31 +0400 Subject: [PATCH 20/34] Hide NetworkString inside packet while sending to peer --- src/modes/soccer_world.cpp | 24 ++-- src/network/packet_types.hpp | 4 + src/network/packet_types_base.hpp | 2 + src/network/protocols/server_lobby.cpp | 153 +++++-------------------- src/network/stk_host.cpp | 4 +- src/network/stk_peer.cpp | 10 -- src/network/stk_peer.hpp | 28 ++++- 7 files changed, 72 insertions(+), 153 deletions(-) diff --git a/src/modes/soccer_world.cpp b/src/modes/soccer_world.cpp index 28208c56501..172a939ad5b 100644 --- a/src/modes/soccer_world.cpp +++ b/src/modes/soccer_world.cpp @@ -700,10 +700,10 @@ void SoccerWorld::onCheckGoalTriggered(bool first_goal) packet_1_1.country_code = sd.m_country_code; packet_1_1.handicap = sd.m_handicap_level; - NetworkString p(PROTOCOL_GAME_EVENTS); - NetworkString p_1_1(PROTOCOL_GAME_EVENTS); - packet.toNetworkString(&p); - packet_1_1.toNetworkString(&p_1_1); + // NetworkString p(PROTOCOL_GAME_EVENTS); + // NetworkString p_1_1(PROTOCOL_GAME_EVENTS); + // packet.toNetworkString(&p); + // packet_1_1.toNetworkString(&p_1_1); auto peers = STKHost::get()->getPeers(); for (auto& peer : peers) @@ -713,11 +713,11 @@ void SoccerWorld::onCheckGoalTriggered(bool first_goal) if (peer->getClientCapabilities().find("soccer_fixes") != peer->getClientCapabilities().end()) { - peer->sendNetstring(&p_1_1, PRM_RELIABLE); + peer->sendPacket(packet_1_1); } else { - peer->sendNetstring(&p, PRM_RELIABLE); + peer->sendPacket(packet); } } } @@ -1380,16 +1380,12 @@ void SoccerWorld::tellCountToEveryoneInGame() const + " : " + std::to_string(real_blue); // This should be done using sendStringTo... - NetworkString* chat = new NetworkString(PROTOCOL_LOBBY_ROOM); ChatPacket packet; packet.message = StringUtils::utf8ToWide(real_count); - packet.toNetworkString(chat); for (auto& peer : peers) if (peer->isValidated() && !peer->isWaitingForGame()) - peer->sendNetstring(chat, PRM_RELIABLE); - - delete chat; + peer->sendPacket(packet); } // tellCountToEveryoneInGame // ---------------------------------------------------------------------------- void SoccerWorld::tellCount(std::shared_ptr peer) const @@ -1404,13 +1400,9 @@ void SoccerWorld::tellCount(std::shared_ptr peer) const std::to_string(real_red) + " : " + std::to_string(real_blue); // This should be done using sendStringTo... - NetworkString* chat = new NetworkString(PROTOCOL_LOBBY_ROOM); ChatPacket packet; packet.message = StringUtils::utf8ToWide(real_count); - packet.toNetworkString(chat); - - peer->sendNetstring(chat, PRM_RELIABLE); - delete chat; + peer->sendPacket(packet); } // tellCount // ---------------------------------------------------------------------------- diff --git a/src/network/packet_types.hpp b/src/network/packet_types.hpp index c45eeb66021..72232b984ce 100644 --- a/src/network/packet_types.hpp +++ b/src/network/packet_types.hpp @@ -137,6 +137,9 @@ class Optional void unset() const { m_pointer.reset(); } const T& operator = (const T& value) { m_pointer = std::make_shared(value); return value; } + + T get_or(const T& rhs) const + { return m_pointer != nullptr ? *m_pointer : rhs; } }; class Packet: public Checkable @@ -148,6 +151,7 @@ class Packet: public Checkable virtual ~Packet() {} virtual void toNetworkString(NetworkString* ns) const {} virtual void fromNetworkString(NetworkString* ns) {} + virtual unsigned expectedCapacity() const { return 0; } bool cap(const std::string& name) { return m_capability_checker(name); } Optional m_override_synchronous; diff --git a/src/network/packet_types_base.hpp b/src/network/packet_types_base.hpp index 9930caf4e99..ac1e171fa00 100644 --- a/src/network/packet_types_base.hpp +++ b/src/network/packet_types_base.hpp @@ -140,6 +140,7 @@ DEFINE_CLASS(LoadWorldPacket) DEFINE_FIELD(uint32_t, item_seed) DEFINE_FIELD_OPTIONAL(BattleInfoPacket, battle_info, check(0)) // RaceManager::get()->isBattleMode() DEFINE_FIELD_OPTIONAL(MultipleKartDataPacket, karts_data, cap(REAL_ADDON_KARTS)) + RELIABLE(true) END_DEFINE_CLASS(LoadWorldPacket) DEFINE_CLASS(PlacementPacket) @@ -281,6 +282,7 @@ DEFINE_CLASS(LiveJoinPacket) DEFINE_FIELD(NimCompleteStatePacket, nim_complete_state) DEFINE_FIELD_PTR(WorldCompleteStatePacket, world_complete_state) DEFINE_FIELD_OPTIONAL(InsideGameInfoPacket, inside_info, check(0)) // RaceManager::get()->supportsLiveJoining() + RELIABLE(true) END_DEFINE_CLASS(LiveJoinPacket) DEFINE_CLASS(ChatPacket) diff --git a/src/network/protocols/server_lobby.cpp b/src/network/protocols/server_lobby.cpp index 84c08d4d3a0..acf21d36058 100644 --- a/src/network/protocols/server_lobby.cpp +++ b/src/network/protocols/server_lobby.cpp @@ -549,13 +549,10 @@ void ServerLobby::writePlayerReport(Event* event) reporting_peer, reporting_npp, info); if (written) { - NetworkString* ns = getNetworkString(); ReportSuccessPacket packet2; packet2.success = 1; packet2.reported_name = reporting_npp->getName(); - packet2.toNetworkString(ns); - event->getPeer()->sendNetstring(ns, PRM_RELIABLE); - delete ns; + event->getPeer()->sendPacket(packet2); } #endif } // writePlayerReport @@ -1033,20 +1030,14 @@ bool ServerLobby::canLiveJoinNow() const */ void ServerLobby::rejectLiveJoin(std::shared_ptr peer, BackLobbyReason blr) { - NetworkString* ns = getNetworkString(2); BackLobbyPacket packet1; packet1.reason = blr; - packet1.toNetworkString(ns); - peer->sendNetstring(ns, PRM_RELIABLE); - delete ns; + peer->sendPacket(packet1); updatePlayerList(); - NetworkString* ns2 = getNetworkString(); ServerInfoPacket packet2 = m_game_setup->addServerInfo(); - packet2.toNetworkString(ns2); - peer->sendNetstring(ns2, PRM_RELIABLE); - delete ns2; + peer->sendPacket(packet2); peer->updateLastActivity(); } // rejectLiveJoin @@ -1122,11 +1113,8 @@ void ServerLobby::liveJoinRequest(Event* event) std::vector > players = getLivePlayers(); - NetworkString* ns = new NetworkString(); LoadWorldPacket load_world_packet = getLoadWorldMessage(players, true/*live_join*/); - load_world_packet.toNetworkString(ns); - peer->sendNetstring(ns, PRM_RELIABLE); - delete ns; + peer->sendPacket(load_world_packet); peer->updateLastActivity(); } // liveJoinRequest @@ -1271,7 +1259,6 @@ void ServerLobby::finishedLoadingLiveJoinClient(Event* event) } const uint8_t cc = (uint8_t)Track::getCurrentTrack()->getCheckManager()->getCheckStructureCount(); - NetworkString* ns = getNetworkString(10); LiveJoinPacket packet; @@ -1311,9 +1298,7 @@ void ServerLobby::finishedLoadingLiveJoinClient(Event* event) peer->setWaitingForGame(false); peer->setSpectator(spectator); - packet.toNetworkString(ns); - peer->sendNetstring(ns, PRM_RELIABLE); - delete ns; + peer->sendPacket(packet); updatePlayerList(); peer->updateLastActivity(); } // finishedLoadingLiveJoinClient @@ -1478,12 +1463,9 @@ void ServerLobby::update(int ticks) else if (auto ai = m_ai_peer.lock()) { // Reset AI peer for empty server, which will delete world - NetworkString* ns = getNetworkString(2); BackLobbyPacket packet; packet.reason = BLR_NONE; - packet.toNetworkString(ns); - ai->sendNetstring(ns, PRM_RELIABLE); - delete ns; + ai->sendPacket(packet); } if (all_players_in_world_disconnected) m_game_setup->cancelOneRace(); @@ -1759,11 +1741,8 @@ void ServerLobby::startSelection(const Event *event) Log::warn("ServerLobby", "Bad team choosing."); if (event) { - NetworkString* ns = getNetworkString(); BadTeamPacket packet; - packet.toNetworkString(ns); - event->getPeer()->sendNetstring(ns, PRM_RELIABLE); - delete ns; + event->getPeer()->sendPacket(packet); } return; } @@ -1902,7 +1881,6 @@ void ServerLobby::startSelection(const Event *event) // Start selection - must be synchronous since the receiver pushes // a new screen, which must be done from the main thread. - NetworkString *ns = getNetworkString(1); StartSelectionPacket packet; packet.voting_timeout = getSettings()->getVotingTimeout(); @@ -1924,10 +1902,7 @@ void ServerLobby::startSelection(const Event *event) } packet.assets = getAssetManager()->encodePlayerKartsAndCommonMaps(all_k); - packet.toNetworkString(ns); - - peer->sendNetstring(ns, PRM_RELIABLE); - delete ns; + peer->sendPacket(packet); if (getQueues()->areKartFiltersIgnoringKarts()) Comm::sendStringToPeer(peer, "The server will ignore your kart choice"); @@ -2238,20 +2213,16 @@ void ServerLobby::clientDisconnected(Event* event) void ServerLobby::kickPlayerWithReason(std::shared_ptr peer, const char* reason) const { - NetworkString *ns = getNetworkString(2); - ConnectionRefusedPacket packet; packet.reason = RR_BANNED; packet.message = reason; - packet.toNetworkString(ns); - peer->sendNetstring(ns, PRM_RELIABLE, PEM_UNENCRYPTED); + peer->sendPacket(packet, PRM_RELIABLE, PEM_UNENCRYPTED); peer->cleanPlayerProfiles(); peer->reset(); - delete ns; } // kickPlayerWithReason - //----------------------------------------------------------------------------- + void ServerLobby::saveIPBanTable(const SocketAddress& addr) { #ifdef ENABLE_SQLITE3 @@ -2290,16 +2261,13 @@ bool ServerLobby::handleAssetsAndAddonScores(std::shared_ptr peer, } else { - NetworkString* ns = getNetworkString(2); ConnectionRefusedPacket packet; packet.reason = RR_INCOMPATIBLE_DATA; packet.message = getSettings()->getIncompatibleAdvice(); - packet.toNetworkString(ns); - peer->sendNetstring(ns, PRM_RELIABLE, PEM_UNENCRYPTED); + peer->sendPacket(packet, PRM_RELIABLE, PEM_UNENCRYPTED); peer->cleanPlayerProfiles(); peer->reset(); - delete ns; } Log::verbose("ServerLobby", "Player has incompatible karts / tracks."); return false; @@ -2340,13 +2308,10 @@ void ServerLobby::connectionRequested(Event* event) (m_state.load() != WAITING_FOR_START_GAME /*|| m_game_setup->isGrandPrixStarted()*/)) { - NetworkString *ns = getNetworkString(2); ConnectionRefusedPacket packet; packet.reason = RR_BUSY; - packet.toNetworkString(ns); // send only to the peer that made the request and disconnect it now - peer->sendNetstring(ns, PRM_RELIABLE, PEM_UNENCRYPTED); - delete ns; + peer->sendPacket(packet, PRM_RELIABLE, PEM_UNENCRYPTED); peer->reset(); Log::verbose("ServerLobby", "Player refused: selection started"); @@ -2361,12 +2326,9 @@ void ServerLobby::connectionRequested(Event* event) if (version < stk_config->m_min_server_version || version > stk_config->m_max_server_version) { - NetworkString* ns = getNetworkString(2); ConnectionRefusedPacket packet; packet.reason = RR_INCOMPATIBLE_DATA; - packet.toNetworkString(ns); - peer->sendNetstring(ns, PRM_RELIABLE, PEM_UNENCRYPTED); - delete ns; + peer->sendPacket(packet, PRM_RELIABLE, PEM_UNENCRYPTED); peer->reset(); Log::verbose("ServerLobby", "Player refused: wrong server version"); @@ -2421,12 +2383,9 @@ void ServerLobby::connectionRequested(Event* event) if (total_players + player_count + m_ai_profiles.size() > (unsigned)getSettings()->getServerMaxPlayers()) { - NetworkString* ns = getNetworkString(2); ConnectionRefusedPacket packet; packet.reason = RR_TOO_MANY_PLAYERS; - packet.toNetworkString(ns); - peer->sendNetstring(ns, PRM_RELIABLE, PEM_UNENCRYPTED); - delete ns; + peer->sendPacket(packet, PRM_RELIABLE, PEM_UNENCRYPTED); peer->reset(); Log::verbose("ServerLobby", "Player refused: too many players"); @@ -2464,12 +2423,9 @@ void ServerLobby::connectionRequested(Event* event) if (failed_validation || failed_strictness || failed_anywhere_ai || failed_unhandled_ai) { - NetworkString* ns = getNetworkString(2); ConnectionRefusedPacket packet; packet.reason = RR_INVALID_PLAYER; - packet.toNetworkString(ns); - peer->sendNetstring(ns, PRM_RELIABLE, PEM_UNENCRYPTED); - delete ns; + peer->sendPacket(packet, PRM_RELIABLE, PEM_UNENCRYPTED); peer->reset(); Log::verbose("ServerLobby", "Player refused: invalid player"); @@ -2517,13 +2473,10 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr peer, std::string username = StringUtils::wideToUtf8(online_name); if (getSettings()->isTempBanned(username)) { - NetworkString* ns = getNetworkString(2); ConnectionRefusedPacket packet; packet.reason = RR_BANNED; packet.message = std::string("Please behave well next time."); - packet.toNetworkString(ns); - peer->sendNetstring(ns, PRM_RELIABLE, PEM_UNENCRYPTED); - delete ns; + peer->sendPacket(packet, PRM_RELIABLE, PEM_UNENCRYPTED); peer->reset(); Log::verbose("ServerLobby", "Player refused: invalid player"); @@ -2534,12 +2487,9 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr peer, } if (password != server_pw) { - NetworkString* ns = getNetworkString(2); ConnectionRefusedPacket packet; packet.reason = RR_INCORRECT_PASSWORD; - packet.toNetworkString(ns); - peer->sendNetstring(ns, PRM_RELIABLE, PEM_UNENCRYPTED); - delete ns; + peer->sendPacket(packet, PRM_RELIABLE, PEM_UNENCRYPTED); peer->reset(); Log::verbose("ServerLobby", "Player refused: incorrect password"); @@ -2557,12 +2507,9 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr peer, if (total_players + player_count > (unsigned)getSettings()->getServerMaxPlayers()) { - NetworkString* ns = getNetworkString(2); ConnectionRefusedPacket packet; packet.reason = RR_TOO_MANY_PLAYERS; - packet.toNetworkString(ns); - peer->sendNetstring(ns, PRM_RELIABLE, PEM_UNENCRYPTED); - delete ns; + peer->sendPacket(packet, PRM_RELIABLE, PEM_UNENCRYPTED); peer->reset(); Log::verbose("ServerLobby", "Player refused: too many players"); @@ -2575,12 +2522,9 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr peer, all_online_ids.find(online_id) != all_online_ids.end(); if (getSettings()->isRanked() && duplicated_ranked_player) { - NetworkString* ns = getNetworkString(2); ConnectionRefusedPacket packet; packet.reason = RR_INVALID_PLAYER; - packet.toNetworkString(ns); - peer->sendNetstring(ns, PRM_RELIABLE, PEM_UNENCRYPTED); - delete ns; + peer->sendPacket(packet, PRM_RELIABLE, PEM_UNENCRYPTED); peer->reset(); Log::verbose("ServerLobby", "Player refused: invalid player"); @@ -2673,17 +2617,13 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr peer, peer->setValidated(true); // send a message to the one that asked to connect - NetworkString* si = getNetworkString(); - m_game_setup->addServerInfo().toNetworkString(si); - peer->sendNetstring(si); - delete si; + peer->sendPacket(m_game_setup->addServerInfo()); peer->updateLastActivity(); const bool game_started = m_state.load() != WAITING_FOR_START_GAME; auto& stk_config = STKConfig::get(); - NetworkString* ns = getNetworkString(4); ConnectionAcceptedPacket ack_packet; // connection success -- return the host id of peer @@ -2699,8 +2639,6 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr peer, ack_packet.chat_allowed = getChatManager()->getChat(); ack_packet.reports_allowed = playerReportsTableExists(); - ack_packet.toNetworkString(ns); - peer->setSpectator(false); // The 127.* or ::1/128 will be in charged for controlling AI @@ -2735,8 +2673,7 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr peer, { peer->setWaitingForGame(true); updatePlayerList(); - peer->sendNetstring(ns); - delete ns; + peer->sendPacket(ack_packet); } else { @@ -2755,8 +2692,7 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr peer, } } updatePlayerList(); - peer->sendNetstring(ns); - delete ns; + peer->sendPacket(ack_packet); if (getSettings()->isRanked()) { @@ -3006,11 +2942,8 @@ void ServerLobby::updateServerOwner(bool force) std::shared_ptr owner = getCrownManager()->getFirstInCrownOrder(peers); if (m_server_owner.expired() || m_server_owner.lock() != owner) { - NetworkString* ns = getNetworkString(); ServerOwnershipPacket packet; - packet.toNetworkString(ns); - owner->sendNetstring(ns); - delete ns; + owner->sendPacket(packet); } m_server_owner = owner; m_server_owner_id.store(owner->getHostId()); @@ -3712,12 +3645,9 @@ void ServerLobby::handleServerConfiguration(std::shared_ptr peer, if (getAssetManager()->checkIfNoCommonMaps(assets)) { - NetworkString *ns = getNetworkString(2); ConnectionRefusedPacket packet; packet.reason = RR_INCOMPATIBLE_DATA; - packet.toNetworkString(ns); - peer->sendNetstring(ns, PRM_RELIABLE); - delete ns; + peer->sendPacket(packet, PRM_RELIABLE); peer->cleanPlayerProfiles(); peer->reset(); @@ -4029,7 +3959,6 @@ void ServerLobby::handleKartInfo(Event* event) const RemoteKartInfo& rki = RaceManager::get()->getKartInfo(kart_id); - NetworkString* ns = getNetworkString(1); KartInfoPacket packet; packet.live_join_util_ticks = live_join_util_ticks; packet.kart_id = kart_id; @@ -4046,9 +3975,7 @@ void ServerLobby::handleKartInfo(Event* event) peer->getClientCapabilities().end()) packet.kart_data = rki.getKartData().encode(); - packet.toNetworkString(ns); - peer->sendNetstring(ns, PRM_RELIABLE); - delete ns; + peer->sendPacket(packet); FreeForAll* ffa_world = dynamic_cast(World::getWorld()); @@ -4134,19 +4061,13 @@ void ServerLobby::clientInGameWantsToBackLobby(Event* event) peer->setWaitingForGame(true); peer->setSpectator(false); - NetworkString* ns = getNetworkString(2); BackLobbyPacket packet; packet.reason = BLR_NONE; - packet.toNetworkString(ns); - peer->sendNetstring(ns, PRM_RELIABLE); - delete ns; + peer->sendPacket(packet, PRM_RELIABLE); updatePlayerList(); - NetworkString* si = getNetworkString(); - m_game_setup->addServerInfo().toNetworkString(si); - peer->sendNetstring(si, PRM_RELIABLE); - delete si; + peer->sendPacket(m_game_setup->addServerInfo()); peer->updateLastActivity(); } // clientInGameWantsToBackLobby @@ -4186,19 +4107,13 @@ void ServerLobby::clientSelectingAssetsWantsToBackLobby(Event* event) peer->setWaitingForGame(true); peer->setSpectator(false); - NetworkString* ns = getNetworkString(2); BackLobbyPacket packet; packet.reason = BLR_NONE; - packet.toNetworkString(ns); - peer->sendNetstring(ns, PRM_RELIABLE); - delete ns; + peer->sendPacket(packet); updatePlayerList(); - NetworkString* si = getNetworkString(); - m_game_setup->addServerInfo().toNetworkString(si); - peer->sendNetstring(si, PRM_RELIABLE); - delete si; + peer->sendPacket(m_game_setup->addServerInfo()); peer->updateLastActivity(); } // clientSelectingAssetsWantsToBackLobby @@ -4292,7 +4207,6 @@ void ServerLobby::writeOwnReport(std::shared_ptr reporter, std::shared_ reporting, reporting_npp, info_w); if (written) { - NetworkString* ns = getNetworkString(); ReportSuccessPacket packet; packet.success = 1; if (reporter == reporting) @@ -4300,9 +4214,7 @@ void ServerLobby::writeOwnReport(std::shared_ptr reporter, std::shared_ else packet.reported_name = reporting_npp->getName(); - packet.toNetworkString(ns); - reporter->sendNetstring(ns, PRM_RELIABLE); - delete ns; + reporter->sendPacket(packet); } #endif } // writeOwnReport @@ -4315,12 +4227,9 @@ void ServerLobby::sendStringToPeer(std::shared_ptr peer, const std::str sendStringToAllPeers(s); return; } - NetworkString* ns = getNetworkString(); ChatPacket packet; packet.message = StringUtils::utf8ToWide(s); - packet.toNetworkString(ns); - peer->sendNetstring(ns, PRM_RELIABLE); - delete ns; + peer->sendPacket(packet); } // sendStringToPeer //----------------------------------------------------------------------------- diff --git a/src/network/stk_host.cpp b/src/network/stk_host.cpp index 49ee24e1f43..2f5d6354609 100644 --- a/src/network/stk_host.cpp +++ b/src/network/stk_host.cpp @@ -923,10 +923,8 @@ void STKHost::mainLoop(ProcessType pt) player_name.c_str(), ap, max_ping); p.second->setWarnedForHighPing(true); - NetworkString msg(PROTOCOL_LOBBY_ROOM); BadConnectionPacket packet; - packet.toNetworkString(&msg); - p.second->sendNetstring(&msg, PRM_RELIABLE); + p.second->sendPacket(packet); } } } diff --git a/src/network/stk_peer.cpp b/src/network/stk_peer.cpp index 93b7c086a59..eafbea14d72 100644 --- a/src/network/stk_peer.cpp +++ b/src/network/stk_peer.cpp @@ -137,16 +137,6 @@ void STKPeer::sendNetstring(NetworkString *data, PacketReliabilityMode reliable, } } // sendNetstring -//----------------------------------------------------------------------------- - -void STKPeer::sendPacket(Packet* packet, PacketReliabilityMode reliable, PacketEncryptionMode encrypted) -{ - /* kimden: get capacity from the packet itself !!! */ - NetworkString* ns = new NetworkString(); - packet->toNetworkString(ns); - sendNetstring(ns, reliable, encrypted); - delete ns; -} // sendPacket //----------------------------------------------------------------------------- /** Returns if the peer is connected or not. */ diff --git a/src/network/stk_peer.hpp b/src/network/stk_peer.hpp index aa89b585aec..ca31a25f57a 100644 --- a/src/network/stk_peer.hpp +++ b/src/network/stk_peer.hpp @@ -28,6 +28,8 @@ #include "utils/types.hpp" #include "utils/constants.hpp" +#include "network/network_string.hpp" + #include #include @@ -149,8 +151,30 @@ class STKPeer : public NoCopy void sendNetstring(NetworkString *data, PacketReliabilityMode reliable = PRM_RELIABLE, PacketEncryptionMode encrypted = PEM_ENCRYPTED); // ------------------------------------------------------------------------ - void sendPacket(Packet* packet, PacketReliabilityMode reliable = PRM_RELIABLE, - PacketEncryptionMode encrypted = PEM_ENCRYPTED); + + // std::is_base_of() + template + void sendPacket(const T& packet, PacketReliabilityMode reliable = PRM_RELIABLE, + PacketEncryptionMode encrypted = PEM_ENCRYPTED) + { + /* kimden: get capacity from the packet itself !!! */ + unsigned capacity = packet.expectedCapacity(); + NetworkString* ns = new NetworkString(); + if (capacity != 0) + ns = new NetworkString(ProtocolType::PROTOCOL_NONE, capacity); + else + ns = new NetworkString(); + + packet.toNetworkString(ns); + sendNetstring(ns, + (PacketReliabilityMode)packet.m_override_reliable.get_or((bool)reliable), + encrypted); + + delete ns; + } // sendPacket + //------------------------------------------------------------------------- + // void sendPacket(Packet* packet, PacketReliabilityMode reliable = PRM_RELIABLE, + // PacketEncryptionMode encrypted = PEM_ENCRYPTED); // ------------------------------------------------------------------------ void disconnect(); // ------------------------------------------------------------------------ From 65719d9f64ac2157e4ec0df8d7f6e9e2138b0993 Mon Sep 17 00:00:00 2001 From: kimden <23140380+kimden@users.noreply.github.com> Date: Sat, 19 Apr 2025 13:48:28 +0400 Subject: [PATCH 21/34] Even fewer NetworkStrings, fix templates It broke server joining for now --- src/modes/capture_the_flag.cpp | 2 +- src/modes/free_for_all.cpp | 4 +- src/modes/linear_world.cpp | 2 +- src/modes/soccer_world.cpp | 2 +- src/network/protocol.hpp | 69 +++++++++++++++++++ src/network/protocols/game_protocol.cpp | 2 +- src/network/protocols/server_lobby.cpp | 89 ++++++------------------- src/network/stk_host.cpp | 78 ++++++++++++++++++++-- src/network/stk_host.hpp | 71 ++++++++++++++++++-- src/network/stk_peer.hpp | 20 +++++- src/utils/chat_manager.cpp | 2 +- 11 files changed, 252 insertions(+), 89 deletions(-) diff --git a/src/modes/capture_the_flag.cpp b/src/modes/capture_the_flag.cpp index c6f7be35feb..c2d66481b51 100644 --- a/src/modes/capture_the_flag.cpp +++ b/src/modes/capture_the_flag.cpp @@ -348,7 +348,7 @@ void CaptureTheFlag::checkScoring(FlagColor color) packet.red_score = (uint8_t)new_red_score; packet.blue_score = (uint8_t)new_blue_score; packet.toNetworkString(&p); - STKHost::get()->sendPacketToAllPeers(&p, PRM_RELIABLE); + STKHost::get()->sendNetstringToAllPeers(&p, PRM_RELIABLE); } ctfScored(active_holder, (red_active) ? false : true /*red_team_scored*/, new_kart_score, new_red_score, new_blue_score); diff --git a/src/modes/free_for_all.cpp b/src/modes/free_for_all.cpp index 9e51f628cb7..ebd3c4ed2fd 100644 --- a/src/modes/free_for_all.cpp +++ b/src/modes/free_for_all.cpp @@ -138,7 +138,7 @@ void FreeForAll::handleScoreInServer(int kart_id, int hitter) } packet.toNetworkString(&p); - STKHost::get()->sendPacketToAllPeers(&p, PRM_RELIABLE); + STKHost::get()->sendNetstringToAllPeers(&p, PRM_RELIABLE); } } // handleScoreInServer @@ -367,6 +367,6 @@ void FreeForAll::notifyAboutScoreIfNonzero(int id) packet.new_score = (int16_t)m_scores[id]; packet.toNetworkString(&p); - STKHost::get()->sendPacketToAllPeers(&p, PRM_RELIABLE); + STKHost::get()->sendNetstringToAllPeers(&p, PRM_RELIABLE); } } // notifyAboutScoreIfNonzero diff --git a/src/modes/linear_world.cpp b/src/modes/linear_world.cpp index 1bb33051af0..d156e7507d6 100644 --- a/src/modes/linear_world.cpp +++ b/src/modes/linear_world.cpp @@ -1360,7 +1360,7 @@ void LinearWorld::updateCheckLinesServer(int check_id, int kart_id) } packet.toNetworkString(&cl); - STKHost::get()->sendPacketToAllPeers(&cl, PRM_RELIABLE); + STKHost::get()->sendNetstringToAllPeers(&cl, PRM_RELIABLE); } // updateCheckLinesServer // ---------------------------------------------------------------------------- diff --git a/src/modes/soccer_world.cpp b/src/modes/soccer_world.cpp index 172a939ad5b..bbbbc5a464a 100644 --- a/src/modes/soccer_world.cpp +++ b/src/modes/soccer_world.cpp @@ -985,7 +985,7 @@ void SoccerWorld::updateBallPosition(int ticks) ResetBallPacket packet; packet.reset_ball_ticks = m_reset_ball_ticks; packet.toNetworkString(&p); - STKHost::get()->sendPacketToAllPeers(&p, PRM_RELIABLE); + STKHost::get()->sendNetstringToAllPeers(&p, PRM_RELIABLE); } else if (!NetworkConfig::get()->isNetworking()) { diff --git a/src/network/protocol.hpp b/src/network/protocol.hpp index aed9b98b468..e684122b72f 100644 --- a/src/network/protocol.hpp +++ b/src/network/protocol.hpp @@ -27,10 +27,12 @@ #include #include +#include class Event; class NetworkString; class STKPeer; +class Packet; /** \enum ProtocolType @@ -119,6 +121,73 @@ class Protocol : public std::enable_shared_from_this, NetworkString* getNetworkString(size_t capacity = 16) const; bool checkDataSize(Event* event, unsigned int minimum_size); + // ---------------------------------------------------------------------------- + template + typename std::enable_if::value, void>::type + sendPacketToPeers(const T& packet, + PacketReliabilityMode reliable = PRM_RELIABLE) const + { + std::shared_ptr ptr1 = std::make_shared(packet); + std::shared_ptr ptr2 = std::dynamic_pointer_cast(ptr1); + return sendPacketPtrToPeers(ptr2, reliable); + } + + template + typename std::enable_if::value, void>::type + sendPacketToPeersInServer(const T& packet, + PacketReliabilityMode reliable = PRM_RELIABLE) const + { + std::shared_ptr ptr1 = std::make_shared(packet); + std::shared_ptr ptr2 = std::dynamic_pointer_cast(ptr1); + return sendPacketPtrToPeersInServer(ptr2, reliable); + } + + template + typename std::enable_if::value, void>::type + sendPacketToServer(const T& packet, + PacketReliabilityMode reliable = PRM_RELIABLE) + { + std::shared_ptr ptr1 = std::make_shared(packet); + std::shared_ptr ptr2 = std::dynamic_pointer_cast(ptr1); + return sendPacketPtrToServer(ptr2, reliable); + } + + + template + typename std::enable_if::value, void>::type + sendPacketExcept(std::shared_ptr peer, const T& packet, + PacketReliabilityMode reliable = PRM_RELIABLE) + { + std::shared_ptr ptr1 = std::make_shared(packet); + std::shared_ptr ptr2 = std::dynamic_pointer_cast(ptr1); + return sendPacketPtrExcept(peer, ptr2, reliable); + } + + template + typename std::enable_if::value, void>::type + sendPacketToAllPeersWith(std::function)> predicate, + const T& packet, PacketReliabilityMode reliable = PRM_RELIABLE) + { + std::shared_ptr ptr1 = std::make_shared(packet); + std::shared_ptr ptr2 = std::dynamic_pointer_cast(ptr1); + return sendPacketPtrToAllPeersWith(predicate, ptr2, reliable); + } + // ---------------------------------------------------------------------------- + void sendPacketPtrToPeers(std::shared_ptr packet, + PacketReliabilityMode reliable = PRM_RELIABLE) const; + + void sendPacketPtrToPeersInServer(std::shared_ptr packet, + PacketReliabilityMode reliable = PRM_RELIABLE) const; + + void sendPacketPtrToServer(std::shared_ptr packet, + PacketReliabilityMode reliable = PRM_RELIABLE); + + void sendPacketPtrExcept(std::shared_ptr peer, std::shared_ptr packet, + PacketReliabilityMode reliable = PRM_RELIABLE); + + void sendPacketPtrToAllPeersWith(std::function)> predicate, + std::shared_ptr packet, PacketReliabilityMode reliable = PRM_RELIABLE); + // ---------------------------------------------------------------------------- virtual void requestStart(); virtual void requestTerminate(); // ------------------------------------------------------------------------ diff --git a/src/network/protocols/game_protocol.cpp b/src/network/protocols/game_protocol.cpp index 627bb017e63..e3024cfc92c 100644 --- a/src/network/protocols/game_protocol.cpp +++ b/src/network/protocols/game_protocol.cpp @@ -245,7 +245,7 @@ void GameProtocol::handleControllerAction(Event *event) // is after the server time peer->updateLastActivity(); if (!will_trigger_rewind) - STKHost::get()->sendPacketExcept(peer, &data, PRM_UNRELIABLE); + STKHost::get()->sendNetstringExcept(peer, &data, PRM_UNRELIABLE); } // if server } // handleControllerAction diff --git a/src/network/protocols/server_lobby.cpp b/src/network/protocols/server_lobby.cpp index acf21d36058..d01f767bbe7 100644 --- a/src/network/protocols/server_lobby.cpp +++ b/src/network/protocols/server_lobby.cpp @@ -913,15 +913,12 @@ void ServerLobby::asynchronousUpdate() resetPeersReady(); m_state = LOAD_WORLD; - NetworkString* ns = getNetworkString(); LoadWorldPacket packet = getLoadWorldMessage(players, false/*live_join*/); - packet.toNetworkString(ns); - Comm::sendMessageToPeers(ns); + sendPacketToPeers(packet); // updatePlayerList so the in lobby players (if any) can see always // spectators join the game if (has_always_on_spectators || !previous_spectate_mode.empty()) updatePlayerList(); - delete ns; if (RaceManager::get()->getMinorMode() == RaceManager::MINOR_MODE_SOCCER) @@ -1449,12 +1446,9 @@ void ServerLobby::update(int ticks) { // Send a notification to all players who may have start live join // or spectate to go back to lobby - NetworkString* ns = getNetworkString(2); BackLobbyPacket packet; packet.reason = BLR_NONE; - packet.toNetworkString(ns); - Comm::sendMessageToPeersInServer(ns, PRM_RELIABLE); - delete ns; + sendPacketToPeersInServer(packet); RaceEventManager::get()->stop(); RaceEventManager::get()->getProtocol()->requestTerminate(); @@ -1484,12 +1478,9 @@ void ServerLobby::update(int ticks) m_state.load() == SELECTING && STKHost::get()->getPlayersInGame() == 1) { - NetworkString* ns = getNetworkString(2); BackLobbyPacket packet; packet.reason = BLR_ONE_PLAYER_IN_RANKED_MATCH; - packet.toNetworkString(ns); - Comm::sendMessageToPeers(ns, PRM_RELIABLE); - delete ns; + sendPacketToPeers(packet); resetVotingTime(); // m_game_setup->cancelOneRace(); @@ -1499,8 +1490,6 @@ void ServerLobby::update(int ticks) handlePlayerDisconnection(); - NetworkString* ns; - switch (m_state.load()) { case SET_PUBLIC_ADDRESS: @@ -1545,10 +1534,7 @@ void ServerLobby::update(int ticks) setTimeoutFromNow(15); m_state = RESULT_DISPLAY; - ns = getNetworkString(); - m_result_packet.toNetworkString(ns); - Comm::sendMessageToPeers(ns, PRM_RELIABLE); - delete ns; + sendPacketToPeers(m_result_packet); Log::info("ServerLobby", "End of game message sent"); break; @@ -1559,12 +1545,9 @@ void ServerLobby::update(int ticks) { // Send a notification to all clients to exit // the race result screen - NetworkString* ns = getNetworkString(2); BackLobbyPacket packet; packet.reason = BLR_NONE; - packet.toNetworkString(ns); - Comm::sendMessageToPeersInServer(ns, PRM_RELIABLE); - delete ns; + sendPacketToPeersInServer(packet); m_rs_state.store(RS_ASYNC_RESET); } @@ -1911,18 +1894,15 @@ void ServerLobby::startSelection(const Event *event) m_state = SELECTING; if (need_to_update || !always_spectate_peers.empty()) { - NetworkString* ns = getNetworkString(2); BackLobbyPacket packet; packet.reason = BLR_SPECTATING_NEXT_GAME; - packet.toNetworkString(ns); - STKHost::get()->sendPacketToAllPeersWith( + sendPacketToAllPeersWith( [always_spectate_peers](std::shared_ptr peer) { return always_spectate_peers.find(peer) != always_spectate_peers.end(); - }, ns, PRM_RELIABLE); - delete ns; + }, packet); updatePlayerList(); } @@ -2169,7 +2149,6 @@ void ServerLobby::clientDisconnected(Event* event) else Log::warn("ServerLobby", "GameInfo is not accessible??"); - NetworkString* ns = getNetworkString(2); PlayerDisconnectedPacket packet; packet.players_size = (uint8_t)players_on_peer.size(); packet.host_id = event->getPeer()->getHostId(); @@ -2184,7 +2163,6 @@ void ServerLobby::clientDisconnected(Event* event) Log::info("ServerLobby", "%s disconnected", name.c_str()); getCommandManager()->deleteUser(name); } - packet.toNetworkString(ns); unsigned players_number; STKHost::get()->updatePlayers(NULL, NULL, &players_number); @@ -2192,7 +2170,7 @@ void ServerLobby::clientDisconnected(Event* event) resetToDefaultSettings(); // Don't show waiting peer disconnect message to in game player - STKHost::get()->sendPacketToAllPeersWith([waiting_peer_disconnected] + sendPacketToAllPeersWith([waiting_peer_disconnected] (std::shared_ptr p) { if (!p->isValidated()) @@ -2200,9 +2178,8 @@ void ServerLobby::clientDisconnected(Event* event) if (!p->isWaitingForGame() && waiting_peer_disconnected) return false; return true; - }, ns); + }, packet); updatePlayerList(); - delete ns; #ifdef ENABLE_SQLITE3 getDbConnector()->writeDisconnectInfoTable(event->getPeerSP()); @@ -2877,11 +2854,8 @@ void ServerLobby::updatePlayerList(bool update_when_reset_server) list_packet.all_profiles.push_back(packet); } - NetworkString* ns = getNetworkString(); - list_packet.toNetworkString(ns); - // Don't send this message to in-game players - STKHost::get()->sendPacketToAllPeersWith([game_started] + sendPacketToAllPeersWith([game_started] (std::shared_ptr p) { if (!p->isValidated()) @@ -2889,8 +2863,7 @@ void ServerLobby::updatePlayerList(bool update_when_reset_server) if (!p->isWaitingForGame() && game_started) return false; return true; - }, ns); - delete ns; + }, list_packet); } // updatePlayerList //----------------------------------------------------------------------------- @@ -3028,13 +3001,10 @@ void ServerLobby::handlePlayerVote(Event* event) vote.m_player_name = event->getPeer()->getMainProfile()->getDecoratedName(m_name_decorator); // Now inform all clients about the vote - NetworkString* ns = getNetworkString(); VotePacket vote_packet; vote_packet.host_id = event->getPeer()->getHostId(); vote_packet.vote = vote.encode(); - vote_packet.toNetworkString(ns); - Comm::sendMessageToPeers(ns); - delete ns; + sendPacketToPeers(vote_packet); } // handlePlayerVote @@ -3304,13 +3274,11 @@ void ServerLobby::configPeersStartTime() uint64_t start_time = STKHost::get()->getNetworkTimer() + (uint64_t)2500; powerup_manager->setRandomSeed(start_time); - NetworkString* ns = getNetworkString(10); StartGamePacket packet; packet.start_time = start_time; packet.check_count = (uint8_t)Track::getCurrentTrack()->getCheckManager()->getCheckStructureCount(); packet.nim_complete_state = m_nim_complete_state; // was operator += - packet.toNetworkString(ns); - Comm::sendMessageToPeers(ns, PRM_RELIABLE); + sendPacketToPeers(packet); m_client_starting_time = start_time; @@ -3321,7 +3289,6 @@ void ServerLobby::configPeersStartTime() m_server_delay = (uint64_t)(max_ping / 2) + (uint64_t)jitter_tolerance; start_time += m_server_delay; m_server_started_at = start_time; - delete ns; m_state = WAIT_FOR_RACE_STARTED; World::getWorld()->setPhase(WorldStatus::SERVER_READY_PHASE); @@ -3384,10 +3351,7 @@ void ServerLobby::resetServer() resetPeersReady(); updatePlayerList(true/*update_when_reset_server*/); - NetworkString* si = getNetworkString(); - m_game_setup->addServerInfo().toNetworkString(si); - Comm::sendMessageToPeersInServer(si); - delete si; + Comm::sendPacketToPeersInServer(m_game_setup->addServerInfo()); for (auto p : m_peers_ready) { @@ -3680,10 +3644,7 @@ void ServerLobby::handleServerConfiguration(std::shared_ptr peer, } } - NetworkString* si = getNetworkString(); - m_game_setup->addServerInfo().toNetworkString(si); - Comm::sendMessageToPeers(si); - delete si; + sendServerInfoToEveryone(); updatePlayerList(); @@ -4021,12 +3982,9 @@ void ServerLobby::clientInGameWantsToBackLobby(Event* event) else exitGameState(); - NetworkString* ns = getNetworkString(2); BackLobbyPacket packet; packet.reason = BLR_SERVER_OWNER_QUIT_THE_GAME; - packet.toNetworkString(ns); - Comm::sendMessageToPeersInServer(ns, PRM_RELIABLE); - delete ns; + sendPacketToPeersInServer(packet); m_rs_state.store(RS_ASYNC_RESET); return; @@ -4090,12 +4048,9 @@ void ServerLobby::clientSelectingAssetsWantsToBackLobby(Event* event) if (m_process_type == PT_CHILD && event->getPeer()->getHostId() == m_client_server_host_id.load()) { - NetworkString* ns = getNetworkString(2); BackLobbyPacket packet; packet.reason = BLR_SERVER_OWNER_QUIT_THE_GAME; - packet.toNetworkString(ns); - Comm::sendMessageToPeersInServer(ns, PRM_RELIABLE); - delete ns; + sendPacketToPeersInServer(packet); resetVotingTime(); resetServer(); @@ -4235,12 +4190,9 @@ void ServerLobby::sendStringToPeer(std::shared_ptr peer, const std::str void ServerLobby::sendStringToAllPeers(const std::string& s) { - NetworkString* ns = getNetworkString(); ChatPacket packet; packet.message = StringUtils::utf8ToWide(s); - packet.toNetworkString(ns); - sendMessageToPeers(ns, PRM_RELIABLE); - delete ns; + sendPacketToPeers(packet); } // sendStringToAllPeers //----------------------------------------------------------------------------- @@ -4442,10 +4394,7 @@ bool ServerLobby::playerReportsTableExists() const void ServerLobby::sendServerInfoToEveryone() const { - NetworkString* si = getNetworkString(); - m_game_setup->addServerInfo().toNetworkString(si); - Comm::sendMessageToPeers(si); - delete si; + sendPacketToPeers(m_game_setup->addServerInfo()); } // sendServerInfoToEveryone //----------------------------------------------------------------------------- diff --git a/src/network/stk_host.cpp b/src/network/stk_host.cpp index 2f5d6354609..2f4355a07be 100644 --- a/src/network/stk_host.cpp +++ b/src/network/stk_host.cpp @@ -1337,7 +1337,7 @@ std::shared_ptr STKHost::getServerPeerForClient() const * \param data Data to sent. * \param reliable If the data should be sent reliable or now. */ -void STKHost::sendPacketToAllPeersInServer(NetworkString *data, PacketReliabilityMode reliable) +void STKHost::sendNetstringToAllPeersInServer(NetworkString *data, PacketReliabilityMode reliable) { std::lock_guard lock(m_peers_mutex); for (auto p : m_peers) @@ -1345,14 +1345,14 @@ void STKHost::sendPacketToAllPeersInServer(NetworkString *data, PacketReliabilit if (p.second->isValidated()) p.second->sendNetstring(data, reliable); } -} // sendPacketToAllPeersInServer +} // sendNetstringToAllPeersInServer //----------------------------------------------------------------------------- /** Sends data to all validated peers currently in game * \param data Data to sent. * \param reliable If the data should be sent reliable or now. */ -void STKHost::sendPacketToAllPeers(NetworkString *data, PacketReliabilityMode reliable) +void STKHost::sendNetstringToAllPeers(NetworkString *data, PacketReliabilityMode reliable) { std::lock_guard lock(m_peers_mutex); for (auto p : m_peers) @@ -1360,7 +1360,7 @@ void STKHost::sendPacketToAllPeers(NetworkString *data, PacketReliabilityMode re if (p.second->isValidated() && !p.second->isWaitingForGame()) p.second->sendNetstring(data, reliable); } -} // sendPacketToAllPeers +} // sendNetstringToAllPeers //----------------------------------------------------------------------------- /** Sends data to all validated peers except the specified currently in game @@ -1368,7 +1368,7 @@ void STKHost::sendPacketToAllPeers(NetworkString *data, PacketReliabilityMode re * \param data Data to sent. * \param reliable If the data should be sent reliable or now. */ -void STKHost::sendPacketExcept(std::shared_ptr peer, NetworkString *data, +void STKHost::sendNetstringExcept(std::shared_ptr peer, NetworkString *data, PacketReliabilityMode reliable) { std::lock_guard lock(m_peers_mutex); @@ -1381,7 +1381,7 @@ void STKHost::sendPacketExcept(std::shared_ptr peer, NetworkString *dat stk_peer->sendNetstring(data, reliable); } } -} // sendPacketExcept +} // sendNetstringExcept //----------------------------------------------------------------------------- /** Sends data to peers with custom rule @@ -1389,7 +1389,7 @@ void STKHost::sendPacketExcept(std::shared_ptr peer, NetworkString *dat * \param data Data to sent. * \param reliable If the data should be sent reliable or now. */ -void STKHost::sendPacketToAllPeersWith(std::function)> predicate, +void STKHost::sendNetstringToAllPeersWith(std::function)> predicate, NetworkString* data, PacketReliabilityMode reliable) { std::lock_guard lock(m_peers_mutex); @@ -1670,3 +1670,67 @@ uint16_t STKHost::getPrivatePort() const { return m_network->getPort(); } // getPrivatePort +// ---------------------------------------------------------------------------- + +void STKHost::sendPacketPtrToAllPeersInServer(std::shared_ptr packet, PacketReliabilityMode reliable) +{ + std::lock_guard lock(m_peers_mutex); + for (auto p : m_peers) + { + if (p.second->isValidated()) + p.second->sendPacketPtr(packet, reliable); + } +} // sendPacketToAllPeersInServer +//----------------------------------------------------------------------------- + +void STKHost::sendPacketPtrToAllPeers(std::shared_ptr packet, PacketReliabilityMode reliable) +{ + std::lock_guard lock(m_peers_mutex); + for (auto p : m_peers) + { + if (p.second->isValidated() && !p.second->isWaitingForGame()) + p.second->sendPacketPtr(packet, reliable); + } +} // sendPacketToAllPeers +//----------------------------------------------------------------------------- + +void STKHost::sendPacketPtrExcept(std::shared_ptr peer, std::shared_ptr packet, + PacketReliabilityMode reliable) +{ + std::lock_guard lock(m_peers_mutex); + for (const auto& p : m_peers) + { + STKPeer* stk_peer = p.second.get(); + if (!stk_peer->isSamePeer(peer.get()) && p.second->isValidated() && + !p.second->isWaitingForGame()) + { + stk_peer->sendPacketPtr(packet, reliable); + } + } +} // sendPacketExcept +//----------------------------------------------------------------------------- + +void STKHost::sendPacketPtrToAllPeersWith(std::function)> predicate, + std::shared_ptr packet, PacketReliabilityMode reliable) +{ + std::lock_guard lock(m_peers_mutex); + for (auto p : m_peers) + { + std::shared_ptr stk_peer = p.second; + if (!stk_peer->isValidated()) + continue; + if (predicate(stk_peer)) + stk_peer->sendPacketPtr(packet, reliable); + } +} // sendPacketToAllPeersWith +//----------------------------------------------------------------------------- + +void STKHost::sendPacketPtrToServer(std::shared_ptr packet, PacketReliabilityMode reliable) +{ + std::lock_guard lock(m_peers_mutex); + if (m_peers.empty()) + return; + assert(NetworkConfig::get()->isClient()); + m_peers.begin()->second->sendPacketPtr(packet, reliable); +} // sendPacketToServer +//----------------------------------------------------------------------------- diff --git a/src/network/stk_host.hpp b/src/network/stk_host.hpp index 8191568533c..4f45fa3c8c4 100644 --- a/src/network/stk_host.hpp +++ b/src/network/stk_host.hpp @@ -60,6 +60,7 @@ class ServerLobby; class ChildLoop; class SocketAddress; class STKPeer; +class Packet; using namespace irr; @@ -244,12 +245,12 @@ class STKHost //------------------------------------------------------------------------- void shutdown(); //------------------------------------------------------------------------- - void sendPacketToAllPeersInServer(NetworkString *data, + void sendNetstringToAllPeersInServer(NetworkString *data, PacketReliabilityMode reliable = PRM_RELIABLE); // ------------------------------------------------------------------------ - void sendPacketToAllPeers(NetworkString *data, PacketReliabilityMode reliable = PRM_RELIABLE); + void sendNetstringToAllPeers(NetworkString *data, PacketReliabilityMode reliable = PRM_RELIABLE); // ------------------------------------------------------------------------ - void sendPacketToAllPeersWith(std::function)> predicate, + void sendNetstringToAllPeersWith(std::function)> predicate, NetworkString* data, PacketReliabilityMode reliable = PRM_RELIABLE); // ------------------------------------------------------------------------ /** Returns true if this client instance is allowed to control the server. @@ -271,7 +272,7 @@ class STKHost std::shared_ptr findPeerByName(const core::stringw& name) const; std::shared_ptr findPeerByWildcard(const core::stringw& name_pattern, std::string &name_found) const; // ------------------------------------------------------------------------ - void sendPacketExcept(std::shared_ptr peer, NetworkString *data, + void sendNetstringExcept(std::shared_ptr peer, NetworkString *data, PacketReliabilityMode reliable = PRM_RELIABLE); // ------------------------------------------------------------------------ void setupClient(int peer_count, int channel_limit, @@ -398,6 +399,68 @@ class STKHost static BareNetworkString getStunRequest(uint8_t* stun_tansaction_id); // ------------------------------------------------------------------------ ChildLoop* getChildLoop() const { return m_client_loop; } + // ------------------------------------------------------------------------ + + template + typename std::enable_if::value, void>::type + sendPacketPtrToAllPeersInServer(const T& packet, PacketReliabilityMode reliable) + { + std::shared_ptr ptr1 = std::make_shared(packet); + std::shared_ptr ptr2 = std::dynamic_pointer_cast(ptr1); + return sendPacketPtrToAllPeersInServer(ptr2, reliable); + } + + template + typename std::enable_if::value, void>::type + sendPacketToAllPeers(const T& packet, PacketReliabilityMode reliable) + { + std::shared_ptr ptr1 = std::make_shared(packet); + std::shared_ptr ptr2 = std::dynamic_pointer_cast(ptr1); + return sendPacketPtrToAllPeers(ptr2, reliable); + } + + template + typename std::enable_if::value, void>::type + sendPacketExcept(std::shared_ptr peer, const T& packet, + PacketReliabilityMode reliable) + { + std::shared_ptr ptr1 = std::make_shared(packet); + std::shared_ptr ptr2 = std::dynamic_pointer_cast(ptr1); + return sendPacketPtrExcept(peer, ptr2, reliable); + } + + template + typename std::enable_if::value, void>::type + sendPacketToAllPeersWith(std::function)> predicate, + const T& packet, PacketReliabilityMode reliable) + { + std::shared_ptr ptr1 = std::make_shared(packet); + std::shared_ptr ptr2 = std::dynamic_pointer_cast(ptr1); + return sendPacketPtrToAllPeersWith(predicate, ptr2, reliable); + } + + template + typename std::enable_if::value, void>::type + sendPacketToServer(const T& packet, PacketReliabilityMode reliable) + { + std::shared_ptr ptr1 = std::make_shared(packet); + std::shared_ptr ptr2 = std::dynamic_pointer_cast(ptr1); + return sendPacketPtrToServer(ptr2, reliable); + } + // ------------------------------------------------------------------------ + + void sendPacketPtrToAllPeersInServer(std::shared_ptr packet, PacketReliabilityMode reliable); + + void sendPacketPtrToAllPeers(std::shared_ptr packet, PacketReliabilityMode reliable); + + void sendPacketPtrExcept(std::shared_ptr peer, std::shared_ptr packet, + PacketReliabilityMode reliable); + + void sendPacketPtrToAllPeersWith(std::function)> predicate, + std::shared_ptr packet, PacketReliabilityMode reliable); + + void sendPacketPtrToServer(std::shared_ptr packet, PacketReliabilityMode reliable); + //------------------------------------------------------------------------- }; // class STKHost #endif // STK_HOST_HPP diff --git a/src/network/stk_peer.hpp b/src/network/stk_peer.hpp index ca31a25f57a..98a6c16af12 100644 --- a/src/network/stk_peer.hpp +++ b/src/network/stk_peer.hpp @@ -157,7 +157,6 @@ class STKPeer : public NoCopy void sendPacket(const T& packet, PacketReliabilityMode reliable = PRM_RELIABLE, PacketEncryptionMode encrypted = PEM_ENCRYPTED) { - /* kimden: get capacity from the packet itself !!! */ unsigned capacity = packet.expectedCapacity(); NetworkString* ns = new NetworkString(); if (capacity != 0) @@ -173,6 +172,25 @@ class STKPeer : public NoCopy delete ns; } // sendPacket //------------------------------------------------------------------------- + + void sendPacketPtr(std::shared_ptr packet, PacketReliabilityMode reliable = PRM_RELIABLE, + PacketEncryptionMode encrypted = PEM_ENCRYPTED) + { + unsigned capacity = packet->expectedCapacity(); + NetworkString* ns = new NetworkString(); + if (capacity != 0) + ns = new NetworkString(ProtocolType::PROTOCOL_NONE, capacity); + else + ns = new NetworkString(); + + packet->toNetworkString(ns); + sendNetstring(ns, + (PacketReliabilityMode)packet->m_override_reliable.get_or((bool)reliable), + encrypted); + + delete ns; + } // sendPacket + //------------------------------------------------------------------------- // void sendPacket(Packet* packet, PacketReliabilityMode reliable = PRM_RELIABLE, // PacketEncryptionMode encrypted = PEM_ENCRYPTED); // ------------------------------------------------------------------------ diff --git a/src/utils/chat_manager.cpp b/src/utils/chat_manager.cpp index 3f9f5abd702..d89b4fd68d3 100644 --- a/src/utils/chat_manager.cpp +++ b/src/utils/chat_manager.cpp @@ -234,7 +234,7 @@ void ChatManager::handleNormalChatMessage(std::shared_ptr peer, packet.message = StringUtils::utf8ToWide(message); packet.toNetworkString(chat); - STKHost::get()->sendPacketToAllPeersWith( + STKHost::get()->sendNetstringToAllPeersWith( std::bind(&ChatManager::shouldMessageBeSent, this, peer, From 44fdae99c8227ad90f0f98c20a52a205f9b23c19 Mon Sep 17 00:00:00 2001 From: kimden <23140380+kimden@users.noreply.github.com> Date: Sat, 19 Apr 2025 20:26:05 +0400 Subject: [PATCH 22/34] Fix inability to join, rework aux fields I got very confused but somehow it works. Live join doesn't though. Client not tested yet, should be horrible right now. --- src/network/network_string.hpp | 5 ++- src/network/packet_types.cpp | 57 +++++++++++++++++++++++++++++-- src/network/packet_types.hpp | 37 +++++++++++++++++++- src/network/packet_types_base.hpp | 19 ++++++++--- 4 files changed, 110 insertions(+), 8 deletions(-) diff --git a/src/network/network_string.hpp b/src/network/network_string.hpp index 4295463b7b8..bca836269eb 100644 --- a/src/network/network_string.hpp +++ b/src/network/network_string.hpp @@ -432,7 +432,10 @@ class NetworkString : public BareNetworkString public: static void unitTesting(); - NetworkString(): BareNetworkString() {} + NetworkString(): BareNetworkString() + { + m_buffer.push_back(ProtocolType::PROTOCOL_NONE); + } /** Constructor for a message to be sent. It sets the * protocol type of this message. It adds 1 byte to the capacity: diff --git a/src/network/packet_types.cpp b/src/network/packet_types.cpp index 73f36407e4f..405f7eab549 100644 --- a/src/network/packet_types.cpp +++ b/src/network/packet_types.cpp @@ -20,6 +20,32 @@ #include "network/remote_kart_info.hpp" #include "network/network_string.hpp" +namespace +{ + template + void setParentMaybePacket(T& value, Packet* pointer, std::true_type) + { + Packet* current = &value; + current->parent = pointer; + for (auto& p: pointer->m_storage) + { + value.m_storage[p.first] = p.second; + } + } + + template + void setParentMaybePacket(T& value, Packet* pointer, std::false_type) + { + // Not a packet, do nothing. + } + + template + void setParent(T& value, Packet* pointer) + { + setParentMaybePacket(value, pointer, std::is_base_of()); + } +} + //---------------------- To NetworkString ------------------------------------- #define DEFINE_CLASS(Name) \ @@ -35,8 +61,14 @@ void Name::toNetworkString(NetworkString* ns) const \ else \ ns->setSynchronous(m_override_synchronous.get_value()); +#define AUX_STORE(Key, Var) + #define AUX_VAR(Type, Var) +#define AUX_VAR_VALUE(Type, Var, Value) + +#define AUX_VAR_FROM_PARENT(Type, Key, Var) + #define DEFINE_FIELD(Type, Var) \ ns->encode(Var); @@ -56,12 +88,13 @@ void Name::toNetworkString(NetworkString* ns) const \ ns->encode(Value); #define DEFINE_VECTOR(Type, Size, Value) \ - for (unsigned Value##_cnt = 0; Value##_cnt < Size; ++Value##_cnt) { \ + for (unsigned Value##_cnt = 0; Value##_cnt < Value.size(); ++Value##_cnt) { \ ns->encode(Value[Value##_cnt]); \ } +/* Might have additional size inconsistencies due to nullptrs being omitted. */ #define DEFINE_VECTOR_PTR(Type, Size, Value) \ - for (unsigned Value##_cnt = 0; Value##_cnt < Size; ++Value##_cnt) { \ + for (unsigned Value##_cnt = 0; Value##_cnt < Value.size(); ++Value##_cnt) { \ if (Value[Value##_cnt]) \ ns->encode(*(Value[Value##_cnt])); \ } @@ -75,7 +108,10 @@ void Name::toNetworkString(NetworkString* ns) const \ #undef DEFINE_CLASS #undef DEFINE_DERIVED_CLASS #undef PROTOCOL_TYPE +#undef AUX_STORE #undef AUX_VAR +#undef AUX_VAR_VALUE +#undef AUX_VAR_FROM_PARENT #undef DEFINE_FIELD #undef DEFINE_FIELD16 #undef DEFINE_FIELD_PTR @@ -99,9 +135,19 @@ void Name::fromNetworkString(NetworkString* ns) \ #define PROTOCOL_TYPE(Type, Sync) +#define AUX_STORE(Key, Var) \ + store(Key, Var); + #define AUX_VAR(Type, Var) +#define AUX_VAR_VALUE(Type, Var, Value) \ + Var = (Value); + +#define AUX_VAR_FROM_PARENT(Type, Key, Var) \ + Var = parent->obtain(Key); + #define DEFINE_FIELD(Type, Var) \ + setParent(Var, this); \ ns->decode(Var); #define DEFINE_FIELD16(Type, Var) \ @@ -110,6 +156,7 @@ void Name::fromNetworkString(NetworkString* ns) \ // Same as optional but unconditional #define DEFINE_FIELD_PTR(Type, Var) \ Type temp_##Var; \ + setParent(temp_##Var, this); \ ns->decode(temp_##Var); \ Var = std::make_shared(temp_##Var); \ @@ -118,6 +165,7 @@ void Name::fromNetworkString(NetworkString* ns) \ if (Condition) { \ int temp_prev_offset = ns->getCurrentOffset(); \ Type temp_##Var; \ + setParent(temp_##Var, this); \ try { \ ns->decode(temp_##Var); \ } catch (...) { \ @@ -131,6 +179,7 @@ void Name::fromNetworkString(NetworkString* ns) \ #define DEFINE_VECTOR(Type, Size, Var) \ Var.resize(Size); \ for (unsigned Var##_cnt = 0; Var##_cnt < Size; ++Var##_cnt) { \ + setParent(Var[Var##_cnt], this); \ ns->decode(Var[Var##_cnt]); \ } @@ -138,6 +187,7 @@ void Name::fromNetworkString(NetworkString* ns) \ Var.resize(Size); \ for (unsigned Var##_cnt = 0; Var##_cnt < Size; ++Var##_cnt) { \ Type temp_##Var; \ + setParent(temp_##Var, this); \ ns->decode(temp_##Var); \ Var[Var##_cnt] = std::make_shared(temp_##Var); \ } @@ -151,7 +201,10 @@ void Name::fromNetworkString(NetworkString* ns) \ #undef DEFINE_CLASS #undef DEFINE_DERIVED_CLASS #undef PROTOCOL_TYPE +#undef AUX_STORE #undef AUX_VAR +#undef AUX_VAR_VALUE +#undef AUX_VAR_FROM_PARENT #undef DEFINE_FIELD #undef DEFINE_FIELD16 #undef DEFINE_FIELD_PTR diff --git a/src/network/packet_types.hpp b/src/network/packet_types.hpp index 72232b984ce..30b85237760 100644 --- a/src/network/packet_types.hpp +++ b/src/network/packet_types.hpp @@ -33,6 +33,7 @@ class BareNetworkString; #include #include #include +#include /** * IMPORTANT! @@ -142,7 +143,33 @@ class Optional { return m_pointer != nullptr ? *m_pointer : rhs; } }; -class Packet: public Checkable +class Storage +{ +public: + std::map> m_storage; + + template + void store(const std::string& key, const T& value) + { + m_storage[key] = std::static_pointer_cast(std::make_shared(value)); + } + + template + T obtain(const std::string& key) + { + auto it = m_storage.find(key); + if (it == m_storage.end()) + return T(); // exception? + + auto ptr = std::static_pointer_cast(it->second); + if (!ptr) + return T(); // exception? + + return *ptr; + } +}; + +class Packet: public Checkable, public Storage { public: std::function m_capability_checker; @@ -156,6 +183,8 @@ class Packet: public Checkable Optional m_override_synchronous; Optional m_override_reliable; + + Packet* parent = nullptr; }; // temp @@ -179,7 +208,10 @@ class Name: public Parent { \ virtual void fromNetworkString(NetworkString* ns) OVERRIDE; #define PROTOCOL_TYPE(Type, Sync) +#define AUX_STORE(Key, Var) #define AUX_VAR(Type, Var) Type Var; +#define AUX_VAR_VALUE(Type, Var, Value) Type Var; +#define AUX_VAR_FROM_PARENT(Type, Key, Var) Type Var; #define DEFINE_FIELD(Type, Var) Type Var; #define DEFINE_FIELD16(Type, Var) Type Var; #define DEFINE_FIELD_PTR(Type, Var) std::shared_ptr Var; @@ -194,7 +226,10 @@ class Name: public Parent { \ #undef DEFINE_CLASS #undef DEFINE_DERIVED_CLASS #undef PROTOCOL_TYPE +#undef AUX_STORE #undef AUX_VAR +#undef AUX_VAR_VALUE +#undef AUX_VAR_FROM_PARENT #undef DEFINE_FIELD #undef DEFINE_FIELD16 #undef DEFINE_FIELD_PTR diff --git a/src/network/packet_types_base.hpp b/src/network/packet_types_base.hpp index ac1e171fa00..4601f5e71ed 100644 --- a/src/network/packet_types_base.hpp +++ b/src/network/packet_types_base.hpp @@ -53,7 +53,7 @@ using widestr = irr::core::stringw; // Make sure all level 0 packets have protocol set! DEFINE_CLASS(EncryptedBuffer) - AUX_VAR(uint32_t, size) + AUX_VAR_FROM_PARENT(uint32_t, "encrypted_size", size) /* ConnectionRequestedPacket::encrypted_size */ DEFINE_VECTOR(uint8_t, size, buffer) END_DEFINE_CLASS(EncryptedBuffer) @@ -126,7 +126,7 @@ DEFINE_CLASS(KartDataPacket) END_DEFINE_CLASS(KartDataPacket) DEFINE_CLASS(MultipleKartDataPacket) - AUX_VAR(uint8_t, players_size) + AUX_VAR_FROM_PARENT(uint8_t, "players_size", players_size) /* LoadWorldPacket::players_size */ DEFINE_VECTOR(KartDataPacket, players_size, players_kart_data) END_DEFINE_CLASS(MultipleKartDataPacket) @@ -136,6 +136,7 @@ DEFINE_CLASS(LoadWorldPacket) DEFINE_FIELD(DefaultVotePacket, default_vote) DEFINE_FIELD(bool, live_join) DEFINE_FIELD(uint8_t, players_size) + AUX_STORE("players_size", players_size) DEFINE_VECTOR(EncodedSinglePlayerPacket, players_size, all_players) DEFINE_FIELD(uint32_t, item_seed) DEFINE_FIELD_OPTIONAL(BattleInfoPacket, battle_info, check(0)) // RaceManager::get()->isBattleMode() @@ -200,7 +201,7 @@ DEFINE_CLASS(CheckStructureSubPacket) END_DEFINE_CLASS(CheckStructureSubPacket) DEFINE_DERIVED_CLASS(CheckStructurePacket, CheckPacket) - AUX_VAR(uint32_t, karts_count) + AUX_VAR_FROM_PARENT(uint32_t, "karts_count", karts_count) /* Checklinepacket or Linearworldcompletestatepacket ::karts_count */ DEFINE_VECTOR(CheckStructureSubPacket, karts_count, player_check_state) END_DEFINE_CLASS(CheckStructurePacket) @@ -209,7 +210,7 @@ DEFINE_CLASS(CheckLineSubPacket) END_DEFINE_CLASS(CheckLineSubPacket) DEFINE_DERIVED_CLASS(CheckLinePacket, CheckPacket) - AUX_VAR(uint32_t, karts_count) + AUX_VAR_FROM_PARENT(uint32_t, "karts_count", karts_count) DEFINE_FIELD_PTR(CheckStructurePacket, check_structure_packet) DEFINE_VECTOR(CheckLineSubPacket, karts_count, subpackets) END_DEFINE_CLASS(CheckLinePacket) @@ -220,6 +221,8 @@ END_DEFINE_CLASS(WorldPacket) DEFINE_DERIVED_CLASS(LinearWorldCompleteStatePacket, WorldPacket) AUX_VAR(uint32_t, karts_count) AUX_VAR(uint32_t, track_sectors_count) + AUX_STORE("karts_count", karts_count) + AUX_STORE("track_sectors_count", track_sectors_count) DEFINE_FIELD(uint32_t, fastest_lap_ticks) DEFINE_FIELD(float, distance_increase) DEFINE_VECTOR(PlacementPacket, karts_count, kart_placements) @@ -240,6 +243,10 @@ DEFINE_CLASS(ScorerDataPacket) END_DEFINE_CLASS(ScorerDataPacket) DEFINE_DERIVED_CLASS(SoccerWorldCompleteStatePacket, WorldPacket) + AUX_VAR(uint32_t, karts_count) + AUX_VAR(uint32_t, track_sectors_count) + AUX_STORE("karts_count", karts_count) + AUX_STORE("track_sectors_count", track_sectors_count) DEFINE_FIELD(uint32_t, red_scorers_count) DEFINE_VECTOR(ScorerDataPacket, red_scorers_count, red_scorers) DEFINE_FIELD(uint32_t, blue_scorers_count) @@ -250,6 +257,9 @@ END_DEFINE_CLASS(SoccerWorldCompleteStatePacket) DEFINE_DERIVED_CLASS(FFAWorldCompleteStatePacket, WorldPacket) AUX_VAR(uint32_t, karts_count) + AUX_VAR(uint32_t, track_sectors_count) + AUX_STORE("karts_count", karts_count) + AUX_STORE("track_sectors_count", track_sectors_count) DEFINE_VECTOR(uint32_t, karts_count, scores) END_DEFINE_CLASS(FFAWorldCompleteStatePacket) @@ -665,6 +675,7 @@ DEFINE_CLASS(ConnectionRequestedPacket) DEFINE_FIELD(uint32_t, id) DEFINE_FIELD(uint32_t, encrypted_size) // 0 if not encrypted + AUX_STORE("encrypted_size", encrypted_size) DEFINE_FIELD_OPTIONAL(widestr, player_name, id != 0 && encrypted_size == 0) DEFINE_FIELD_OPTIONAL(EncryptedBuffer, player_info_encrypted, encrypted_size != 0) DEFINE_FIELD_OPTIONAL(RestConnectionRequestPacket, player_info_unencrypted, encrypted_size == 0) From 72e4396593342623d5567c8ead502525b3718055 Mon Sep 17 00:00:00 2001 From: kimden <23140380+kimden@users.noreply.github.com> Date: Mon, 21 Apr 2025 02:51:53 +0400 Subject: [PATCH 23/34] Some client fixes, then a bit of packets cleanup in ClientLobby --- src/network/packet_types_base.hpp | 3 +- src/network/protocols/client_lobby.cpp | 47 +++++---------------- src/network/stk_host.hpp | 29 ++++++++----- src/states_screens/online/tracks_screen.cpp | 5 +-- 4 files changed, 32 insertions(+), 52 deletions(-) diff --git a/src/network/packet_types_base.hpp b/src/network/packet_types_base.hpp index 4601f5e71ed..a07bb7ba9ae 100644 --- a/src/network/packet_types_base.hpp +++ b/src/network/packet_types_base.hpp @@ -396,7 +396,7 @@ DEFINE_CLASS(PlayerKartsPacket) END_DEFINE_CLASS(PlayerKartsPacket) DEFINE_CLASS(KartSelectionRequestPacket) - PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, true) + PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, false) DEFINE_TYPE(uint8_t, type, LE_KART_SELECTION) DEFINE_FIELD(PlayerKartsPacket, karts) END_DEFINE_CLASS(KartSelectionRequestPacket) @@ -476,6 +476,7 @@ DEFINE_CLASS(VoteRequestPacket) PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, false) DEFINE_TYPE(uint8_t, type, LE_VOTE) DEFINE_FIELD(PeerVotePacket, vote) + RELIABLE(true) END_DEFINE_CLASS(VoteRequestPacket) DEFINE_CLASS(ServerOwnershipPacket) diff --git a/src/network/protocols/client_lobby.cpp b/src/network/protocols/client_lobby.cpp index ae7b341caba..3c1e86143b1 100644 --- a/src/network/protocols/client_lobby.cpp +++ b/src/network/protocols/client_lobby.cpp @@ -177,11 +177,8 @@ void ClientLobby::setup() */ void ClientLobby::doneWithResults() { - NetworkString* done = getNetworkString(1); RaceFinishedAckPacket packet; - packet.toNetworkString(done); - Comm::sendToServer(done, PRM_RELIABLE); - delete done; + sendPacketToServer(packet); } // doneWithResults //----------------------------------------------------------------------------- @@ -401,7 +398,6 @@ void ClientLobby::update(int ticks) std::string user_agent = StringUtils::getUserAgentString(); if (NetworkConfig::get()->isNetworkAIInstance()) user_agent = "AI"; - NetworkString* ns = getNetworkString(); ConnectionRequestedPacket packet; packet.server_version = (uint32_t)ServerConfig::m_server_version; @@ -440,7 +436,6 @@ void ClientLobby::update(int ticks) packet.player_name = PlayerManager::getCurrentOnlineProfile()->getUserName(); } - BareNetworkString* rest = new BareNetworkString(); RestConnectionRequestPacket subpacket; subpacket.private_server_password = ServerConfig::m_private_server_password; @@ -496,9 +491,7 @@ void ClientLobby::update(int ticks) } delete rest; - packet.toNetworkString(ns); - Comm::sendToServer(ns); - delete ns; + sendPacketToServer(packet); if (encryption) { @@ -508,10 +501,8 @@ void ClientLobby::update(int ticks) } else { - *ns += *rest; - delete rest; - Comm::sendToServer(ns); - delete ns; + packet.player_info_unencrypted = subpacket; + sendPacketToServer(packet); } @@ -560,9 +551,8 @@ void ClientLobby::update(int ticks) { // Send a message to the server to start m_auto_started = true; - NetworkString start(PROTOCOL_LOBBY_ROOM); - start.addUInt8(LobbyEvent::LE_REQUEST_BEGIN); - Comm::sendToServer(&start, PRM_RELIABLE); + RequestBeginPacket packet; + sendPacketToServer(packet); } if (m_background_download.joinable()) { @@ -1302,12 +1292,9 @@ void ClientLobby::backToLobby(Event *event) */ void ClientLobby::finishedLoadingWorld() { - NetworkString* ns = getNetworkString(1); FinishedLoadingLiveJoinPacket packet; packet.m_override_synchronous = m_server_send_live_load_world; - packet.toNetworkString(ns); - Comm::sendToServer(ns, PRM_RELIABLE); - delete ns; + sendPacketToServer(packet); } // finishedLoadingWorld //----------------------------------------------------------------------------- @@ -1413,12 +1400,9 @@ void ClientLobby::finishLiveJoin() //----------------------------------------------------------------------------- void ClientLobby::requestKartInfo(uint8_t kart_id) { - NetworkString* ns = getNetworkString(1); KartInfoRequestPacket packet; packet.kart_id = kart_id; - packet.toNetworkString(ns); - Comm::sendToServer(ns, PRM_RELIABLE); - delete ns; + sendPacketToServer(packet); } // requestKartInfo //----------------------------------------------------------------------------- @@ -1508,7 +1492,6 @@ void ClientLobby::sendChat(irr::core::stringw text, KartTeam team) text = text.trim().removeChars(L"\n\r"); if (text.size() > 0) { - NetworkString* chat = getNetworkString(); ChatPacket packet; core::stringw name; @@ -1559,9 +1542,7 @@ void ClientLobby::sendChat(irr::core::stringw text, KartTeam team) if (team != KART_TEAM_NONE) packet.kart_team = team; - packet.toNetworkString(chat); - Comm::sendToServer(chat, PRM_RELIABLE); - delete chat; + sendPacketToServer(packet); } } // sendChat @@ -1906,13 +1887,10 @@ void ClientLobby::handleClientCommand(const std::string& cmd) else { // Send for server command - NetworkString* cmd_ns = getNetworkString(1); CommandPacket packet; packet.language = UserConfigParams::m_language; packet.command = cmd; - packet.toNetworkString(cmd_ns); - Comm::sendToServer(cmd_ns, PRM_RELIABLE); - delete cmd_ns; + sendPacketToServer(packet); } #endif } // handleClientCommand @@ -1953,12 +1931,9 @@ AssetsPacket2 ClientLobby::getKartsTracksPacket() // ---------------------------------------------------------------------------- void ClientLobby::updateAssetsToServer() { - NetworkString* ns = getNetworkString(1); NewAssetsPacket packet; packet.assets = getKartsTracksPacket(); - packet.toNetworkString(ns); - Comm::sendToServer(ns, PRM_RELIABLE); - delete ns; + sendPacketToServer(packet); } // updateAssetsToServer // ---------------------------------------------------------------------------- diff --git a/src/network/stk_host.hpp b/src/network/stk_host.hpp index 4f45fa3c8c4..714a639b5e6 100644 --- a/src/network/stk_host.hpp +++ b/src/network/stk_host.hpp @@ -403,7 +403,8 @@ class STKHost template typename std::enable_if::value, void>::type - sendPacketPtrToAllPeersInServer(const T& packet, PacketReliabilityMode reliable) + sendPacketPtrToAllPeersInServer(const T& packet, + PacketReliabilityMode reliable = PRM_RELIABLE) { std::shared_ptr ptr1 = std::make_shared(packet); std::shared_ptr ptr2 = std::dynamic_pointer_cast(ptr1); @@ -412,7 +413,8 @@ class STKHost template typename std::enable_if::value, void>::type - sendPacketToAllPeers(const T& packet, PacketReliabilityMode reliable) + sendPacketToAllPeers(const T& packet, + PacketReliabilityMode reliable = PRM_RELIABLE) { std::shared_ptr ptr1 = std::make_shared(packet); std::shared_ptr ptr2 = std::dynamic_pointer_cast(ptr1); @@ -422,7 +424,7 @@ class STKHost template typename std::enable_if::value, void>::type sendPacketExcept(std::shared_ptr peer, const T& packet, - PacketReliabilityMode reliable) + PacketReliabilityMode reliable = PRM_RELIABLE) { std::shared_ptr ptr1 = std::make_shared(packet); std::shared_ptr ptr2 = std::dynamic_pointer_cast(ptr1); @@ -432,7 +434,7 @@ class STKHost template typename std::enable_if::value, void>::type sendPacketToAllPeersWith(std::function)> predicate, - const T& packet, PacketReliabilityMode reliable) + const T& packet, PacketReliabilityMode reliable = PRM_RELIABLE) { std::shared_ptr ptr1 = std::make_shared(packet); std::shared_ptr ptr2 = std::dynamic_pointer_cast(ptr1); @@ -441,7 +443,7 @@ class STKHost template typename std::enable_if::value, void>::type - sendPacketToServer(const T& packet, PacketReliabilityMode reliable) + sendPacketToServer(const T& packet, PacketReliabilityMode reliable = PRM_RELIABLE) { std::shared_ptr ptr1 = std::make_shared(packet); std::shared_ptr ptr2 = std::dynamic_pointer_cast(ptr1); @@ -449,17 +451,22 @@ class STKHost } // ------------------------------------------------------------------------ - void sendPacketPtrToAllPeersInServer(std::shared_ptr packet, PacketReliabilityMode reliable); + void sendPacketPtrToAllPeersInServer(std::shared_ptr packet, + PacketReliabilityMode reliable = PRM_RELIABLE); - void sendPacketPtrToAllPeers(std::shared_ptr packet, PacketReliabilityMode reliable); + void sendPacketPtrToAllPeers(std::shared_ptr packet, + PacketReliabilityMode reliable = PRM_RELIABLE); - void sendPacketPtrExcept(std::shared_ptr peer, std::shared_ptr packet, - PacketReliabilityMode reliable); + void sendPacketPtrExcept(std::shared_ptr peer, + std::shared_ptr packet, + PacketReliabilityMode reliable = PRM_RELIABLE); void sendPacketPtrToAllPeersWith(std::function)> predicate, - std::shared_ptr packet, PacketReliabilityMode reliable); + std::shared_ptr packet, + PacketReliabilityMode reliable = PRM_RELIABLE); - void sendPacketPtrToServer(std::shared_ptr packet, PacketReliabilityMode reliable); + void sendPacketPtrToServer(std::shared_ptr packet, + PacketReliabilityMode reliable = PRM_RELIABLE); //------------------------------------------------------------------------- }; // class STKHost diff --git a/src/states_screens/online/tracks_screen.cpp b/src/states_screens/online/tracks_screen.cpp index bf0b136a4f1..03252969a2c 100644 --- a/src/states_screens/online/tracks_screen.cpp +++ b/src/states_screens/online/tracks_screen.cpp @@ -733,8 +733,6 @@ void TracksScreen::voteForPlayer() else UserConfigParams::m_random_arena_item = m_reversed->getState(); - NetworkString vote(PROTOCOL_LOBBY_ROOM); - PeerVotePacket packet; core::stringw player_name; @@ -772,8 +770,7 @@ void TracksScreen::voteForPlayer() // Not encoding packet to netstring before if just in case, too. VoteRequestPacket vr_packet; vr_packet.vote = packet; - vr_packet.toNetworkString(&vote); - Comm::sendToServer(&vote, PRM_RELIABLE); + sendPacketToServer(vr_packet); } } // voteForPlayer From 153163243080171561fb0b2ac656df819d2982fa Mon Sep 17 00:00:00 2001 From: kimden <23140380+kimden@users.noreply.github.com> Date: Tue, 22 Apr 2025 01:55:09 +0400 Subject: [PATCH 24/34] More processed packets, started doing something about rewind, compilation broken [skip ci] --- src/items/item.hpp | 1 - src/modes/capture_the_flag.cpp | 4 +- src/modes/free_for_all.cpp | 9 +---- src/modes/linear_world.cpp | 5 +-- src/modes/soccer_world.cpp | 4 +- src/network/packet_types_base.hpp | 37 +++++++++++++++++-- .../protocols/game_events_protocol.cpp | 8 ++-- src/network/protocols/game_protocol.cpp | 7 +--- .../dialogs/network_player_dialog.cpp | 16 ++------ .../dialogs/race_paused_dialog.cpp | 4 +- .../dialogs/server_configuration_dialog.cpp | 4 +- .../online/network_kart_selection.cpp | 10 ++--- .../online/networking_lobby.cpp | 8 +--- src/tracks/check_structure.hpp | 1 - src/tracks/track_sector.cpp | 20 +++++----- src/tracks/track_sector.hpp | 12 +++--- src/utils/chat_manager.cpp | 7 +--- 17 files changed, 73 insertions(+), 84 deletions(-) diff --git a/src/items/item.hpp b/src/items/item.hpp index d535f3d1333..a91da4b2180 100644 --- a/src/items/item.hpp +++ b/src/items/item.hpp @@ -32,7 +32,6 @@ #include -class BareNetworkString; class AbstractKart; class LODNode; class ItemStatePacket; diff --git a/src/modes/capture_the_flag.cpp b/src/modes/capture_the_flag.cpp index c2d66481b51..64fa94310ed 100644 --- a/src/modes/capture_the_flag.cpp +++ b/src/modes/capture_the_flag.cpp @@ -340,15 +340,13 @@ void CaptureTheFlag::checkScoring(FlagColor color) m_scores.at(active_holder) = new_kart_score; if (NetworkConfig::get()->isServer()) { - NetworkString p(PROTOCOL_GAME_EVENTS); InsideCtfPacket packet; packet.active_holder = (int8_t)active_holder; packet.red_inactive = !red_active; packet.kart_score = (int16_t)new_kart_score; packet.red_score = (uint8_t)new_red_score; packet.blue_score = (uint8_t)new_blue_score; - packet.toNetworkString(&p); - STKHost::get()->sendNetstringToAllPeers(&p, PRM_RELIABLE); + STKHost::get()->sendPacketToAllPeers(packet); } ctfScored(active_holder, (red_active) ? false : true /*red_team_scored*/, new_kart_score, new_red_score, new_blue_score); diff --git a/src/modes/free_for_all.cpp b/src/modes/free_for_all.cpp index ebd3c4ed2fd..769cb2533a5 100644 --- a/src/modes/free_for_all.cpp +++ b/src/modes/free_for_all.cpp @@ -123,7 +123,6 @@ void FreeForAll::handleScoreInServer(int kart_id, int hitter) if (NetworkConfig::get()->isNetworking() && NetworkConfig::get()->isServer()) { - NetworkString p(PROTOCOL_GAME_EVENTS); InsideFfaPacket packet; if (kart_id == hitter || hitter == -1) @@ -137,8 +136,7 @@ void FreeForAll::handleScoreInServer(int kart_id, int hitter) packet.new_score = (int16_t)new_score; } - packet.toNetworkString(&p); - STKHost::get()->sendNetstringToAllPeers(&p, PRM_RELIABLE); + STKHost::get()->sendPacketToAllPeers(packet); } } // handleScoreInServer @@ -360,13 +358,10 @@ void FreeForAll::notifyAboutScoreIfNonzero(int id) NetworkConfig::get()->isServer() && m_scores[id] != 0) { - NetworkString p(PROTOCOL_GAME_EVENTS); - InsideFfaPacket packet; packet.hitter_kart = (uint8_t)id; packet.new_score = (int16_t)m_scores[id]; - packet.toNetworkString(&p); - STKHost::get()->sendNetstringToAllPeers(&p, PRM_RELIABLE); + STKHost::get()->sendPacketToAllPeers(packet); } } // notifyAboutScoreIfNonzero diff --git a/src/modes/linear_world.cpp b/src/modes/linear_world.cpp index d156e7507d6..c769b5be5c2 100644 --- a/src/modes/linear_world.cpp +++ b/src/modes/linear_world.cpp @@ -1339,8 +1339,6 @@ void LinearWorld::updateCheckLinesServer(int check_id, int kart_id) NetworkConfig::get()->isClient()) return; - NetworkString cl(PROTOCOL_GAME_EVENTS); - InsideChecklinePacket packet; packet.kart_id = (uint8_t)kart_id; packet.finished_laps = (int8_t)m_kart_info[kart_id].m_finished_laps; @@ -1359,8 +1357,7 @@ void LinearWorld::updateCheckLinesServer(int check_id, int kart_id) cm->getCheckStructure(i)->saveIsActive(kart_id)); } - packet.toNetworkString(&cl); - STKHost::get()->sendNetstringToAllPeers(&cl, PRM_RELIABLE); + STKHost::get()->sendPacketToAllPeers(packet); } // updateCheckLinesServer // ---------------------------------------------------------------------------- diff --git a/src/modes/soccer_world.cpp b/src/modes/soccer_world.cpp index bbbbc5a464a..d15b116f78c 100644 --- a/src/modes/soccer_world.cpp +++ b/src/modes/soccer_world.cpp @@ -981,11 +981,9 @@ void SoccerWorld::updateBallPosition(int ticks) m_reset_ball_ticks = getTicksSinceStart() + stk_config->time2Ticks(2.0f); - NetworkString p(PROTOCOL_GAME_EVENTS); ResetBallPacket packet; packet.reset_ball_ticks = m_reset_ball_ticks; - packet.toNetworkString(&p); - STKHost::get()->sendNetstringToAllPeers(&p, PRM_RELIABLE); + STKHost::get()->sendPacketToAllPeers(packet); } else if (!NetworkConfig::get()->isNetworking()) { diff --git a/src/network/packet_types_base.hpp b/src/network/packet_types_base.hpp index a07bb7ba9ae..b9939b0d840 100644 --- a/src/network/packet_types_base.hpp +++ b/src/network/packet_types_base.hpp @@ -181,7 +181,7 @@ DEFINE_CLASS(KartInfoInGamePacket) DEFINE_FIELD(float, wrong_way_timer) END_DEFINE_CLASS(KartInfoInGamePacket) -DEFINE_CLASS(TrackSectorPacket) +DEFINE_CLASS(TrackSectorCompleteStatePacket) DEFINE_FIELD(uint32_t, current_graph_node) DEFINE_FIELD(uint32_t, estimated_valid_graph_node) DEFINE_FIELD(uint32_t, last_valid_graph_node) @@ -190,7 +190,7 @@ DEFINE_CLASS(TrackSectorPacket) DEFINE_FIELD(Vec3, latest_valid_track_coords) DEFINE_FIELD(bool, on_road) DEFINE_FIELD(uint32_t, last_triggered_checkline) -END_DEFINE_CLASS(TrackSectorPacket) +END_DEFINE_CLASS(TrackSectorCompleteStatePacket) DEFINE_CLASS(CheckPacket) END_DEFINE_CLASS(CheckPacket) @@ -227,7 +227,7 @@ DEFINE_DERIVED_CLASS(LinearWorldCompleteStatePacket, WorldPacket) DEFINE_FIELD(float, distance_increase) DEFINE_VECTOR(PlacementPacket, karts_count, kart_placements) DEFINE_VECTOR(KartInfoInGamePacket, karts_count, kart_infos) - DEFINE_VECTOR(TrackSectorPacket, track_sectors_count, track_sectors) + DEFINE_VECTOR(TrackSectorCompleteStatePacket, track_sectors_count, track_sectors) DEFINE_FIELD(uint8_t, check_structure_count) DEFINE_VECTOR_PTR(CheckStructurePacket, check_structure_count, check_structures) END_DEFINE_CLASS(LinearWorldCompleteStatePacket) @@ -399,6 +399,7 @@ DEFINE_CLASS(KartSelectionRequestPacket) PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, false) DEFINE_TYPE(uint8_t, type, LE_KART_SELECTION) DEFINE_FIELD(PlayerKartsPacket, karts) + RELIABLE(true) END_DEFINE_CLASS(KartSelectionRequestPacket) DEFINE_CLASS(LiveJoinRequestPacket) @@ -406,6 +407,7 @@ DEFINE_CLASS(LiveJoinRequestPacket) DEFINE_TYPE(uint8_t, type, LE_LIVE_JOIN) DEFINE_FIELD(bool, is_spectator) DEFINE_FIELD_OPTIONAL(PlayerKartsPacket, player_karts, check(0)) // check client side for condition! + RELIABLE(true) END_DEFINE_CLASS(LiveJoinRequestPacket) DEFINE_CLASS(FinishedLoadingLiveJoinPacket) @@ -445,6 +447,7 @@ DEFINE_CLASS(ConfigServerPacket) DEFINE_FIELD(uint8_t, difficulty) DEFINE_FIELD(uint8_t, game_mode) DEFINE_FIELD(bool, soccer_goal_target) + RELIABLE(true) END_DEFINE_CLASS(ConfigServerPacket) DEFINE_CLASS(ConnectionRefusedPacket) @@ -587,6 +590,7 @@ DEFINE_CLASS(InsideChecklinePacket) DEFINE_FIELD(widestr, fastest_kart_name) DEFINE_FIELD(uint8_t, check_structure_count) DEFINE_VECTOR(CheckActivePacket, check_structure_count, check_active) + RELIABLE(true) END_DEFINE_CLASS(InsideChecklinePacket) @@ -641,6 +645,8 @@ DEFINE_CLASS(ItemConfirmationPacket) PROTOCOL_TYPE(PROTOCOL_CONTROLLER_EVENTS, false) DEFINE_TYPE(uint8_t, type, GP_ITEM_CONFIRMATION) DEFINE_FIELD(uint32_t, ticks) + /* This message can be sent unreliable, it's not critical if it doesn't + get delivered, a future update will come through */ RELIABLE(false) END_DEFINE_CLASS(ItemConfirmationPacket) @@ -683,5 +689,30 @@ DEFINE_CLASS(ConnectionRequestedPacket) END_DEFINE_CLASS(ConnectionRequestedPacket) +DEFINE_CLASS(StartupBoostPacket) + PROTOCOL_TYPE(PROTOCOL_GAME_EVENTS, true) + DEFINE_TYPE(uint8_t, type, GE_STARTUP_BOOST) + DEFINE_FIELD(uint8_t, kart_id) + RELIABLE(true) +END_DEFINE_CLASS(StartupBoostPacket) + +DEFINE_CLASS(TrackSectorSmallPacket) + DEFINE_FIELD(uint16_t, cur_graph_mode) + DEFINE_FIELD(float, coord_z) +END_DEFINE_CLASS(TrackSectorSmallPacket) + + +// todo + +DEFINE_CLASS(PluginStatePacket) +END_DEFINE_CLASS(PluginStatePacket) + +DEFINE_CLASS(AttachmentPacket) + DEFINE_FIELD(uint8_t, type) + DEFINE_FIELD(uint16_t, ticks_left) + DEFINE_FIELD_OPTIONAL(uint8_t, previous_owner, type == (ATTACH_BOMB | 64)) + DEFINE_FIELD_OPTIONAL(uint16_t, initial_speed, (type & 63) == ATTACH_PARACHUTE) + DEFINE_FIELD_OPTIONAL(PluginStatePacket, plugin, ((type >> 7) & 1) == 1) +END_DEFINE_CLASS(AttachmentPacket) // end \ No newline at end of file diff --git a/src/network/protocols/game_events_protocol.cpp b/src/network/protocols/game_events_protocol.cpp index 4441bbecdb7..71e921bbfad 100644 --- a/src/network/protocols/game_events_protocol.cpp +++ b/src/network/protocols/game_events_protocol.cpp @@ -201,9 +201,7 @@ void GameEventsProtocol::kartFinishedRace(const NetworkString &ns) // ---------------------------------------------------------------------------- void GameEventsProtocol::sendStartupBoost(uint8_t kart_id) { - NetworkString *ns = getNetworkString(); - ns->setSynchronous(true); - ns->addUInt8(GE_STARTUP_BOOST).addUInt8(kart_id); - Comm::sendToServer(ns, PRM_RELIABLE); - delete ns; + StartupBoostPacket packet; + packet.kart_id = kart_id; + sendPacketToServer(packet); } // sendStartupBoost diff --git a/src/network/protocols/game_protocol.cpp b/src/network/protocols/game_protocol.cpp index e3024cfc92c..7384e2c5403 100644 --- a/src/network/protocols/game_protocol.cpp +++ b/src/network/protocols/game_protocol.cpp @@ -258,16 +258,11 @@ void GameProtocol::handleControllerAction(Event *event) void GameProtocol::sendItemEventConfirmation(int ticks) { assert(NetworkConfig::get()->isClient()); - NetworkString *ns = getNetworkString(5); ItemConfirmationPacket packet; packet.ticks = ticks; - packet.toNetworkString(ns); - // This message can be sent unreliable, it's not critical if it doesn't - // get delivered, a future update will come through - Comm::sendToServer(ns, PRM_UNRELIABLE); - delete ns; + sendPacketToServer(packet); } // sendItemEventConfirmation // ---------------------------------------------------------------------------- diff --git a/src/states_screens/dialogs/network_player_dialog.cpp b/src/states_screens/dialogs/network_player_dialog.cpp index 2aed23b1c4c..47140647df8 100644 --- a/src/states_screens/dialogs/network_player_dialog.cpp +++ b/src/states_screens/dialogs/network_player_dialog.cpp @@ -204,12 +204,10 @@ void NetworkPlayerDialog::onUpdate(float dt) core::stringw info = tb->getText(); if (info.empty()) return false; - NetworkString report(PROTOCOL_LOBBY_ROOM); ReportRequestPacket packet; packet.host_id = host_id; packet.info = info; - packet.toNetworkString(&report); - Comm::sendToServer(&report, PRM_RELIABLE); + sendPacketToServer(packet); return true; }); return; @@ -250,22 +248,18 @@ GUIEngine::EventPropagation } else if (selection == m_kick_widget->m_properties[PROP_ID]) { - NetworkString kick(PROTOCOL_LOBBY_ROOM); KickHostPacket packet; packet.host_id = m_host_id; - packet.toNetworkString(&kick); - Comm::sendToServer(&kick, PRM_RELIABLE); + sendPacketToServer(packet); m_self_destroy = true; return GUIEngine::EVENT_BLOCK; } else if (m_change_team_widget && selection == m_change_team_widget->m_properties[PROP_ID]) { - NetworkString change_team(PROTOCOL_LOBBY_ROOM); ChangeTeamPacket packet; packet.local_id = m_local_id; - packet.toNetworkString(&change_team); - Comm::sendToServer(&change_team, PRM_RELIABLE); + sendPacketToServer(packet); m_self_destroy = true; return GUIEngine::EVENT_BLOCK; } @@ -277,12 +271,10 @@ GUIEngine::EventPropagation { new_handicap = HANDICAP_MEDIUM; } - NetworkString change_handicap(PROTOCOL_LOBBY_ROOM); ChangeHandicapPacket packet; packet.local_id = m_local_id; packet.handicap = new_handicap; - packet.toNetworkString(&change_handicap); - Comm::sendToServer(&change_handicap, PRM_RELIABLE); + sendPacketToServer(packet); m_self_destroy = true; return GUIEngine::EVENT_BLOCK; } diff --git a/src/states_screens/dialogs/race_paused_dialog.cpp b/src/states_screens/dialogs/race_paused_dialog.cpp index 0f4c0c263ff..5bca8317a54 100644 --- a/src/states_screens/dialogs/race_paused_dialog.cpp +++ b/src/states_screens/dialogs/race_paused_dialog.cpp @@ -386,10 +386,8 @@ GUIEngine::EventPropagation if (NetworkConfig::get()->isNetworking()) { // back lobby - NetworkString back(PROTOCOL_LOBBY_ROOM); ClientBackLobbyPacket packet; - packet.toNetworkString(&back); - Comm::sendToServer(&back, PRM_RELIABLE); + sendPacketToServer(packet); } else { diff --git a/src/states_screens/dialogs/server_configuration_dialog.cpp b/src/states_screens/dialogs/server_configuration_dialog.cpp index 81666fd00f2..0aec04f3715 100644 --- a/src/states_screens/dialogs/server_configuration_dialog.cpp +++ b/src/states_screens/dialogs/server_configuration_dialog.cpp @@ -87,7 +87,6 @@ GUIEngine::EventPropagation else if (selection == m_ok_widget->m_properties[PROP_ID]) { m_self_destroy = true; - NetworkString change(PROTOCOL_LOBBY_ROOM); ConfigServerPacket packet; packet.difficulty = (uint8_t)m_difficulty_widget->getSelection(PLAYER_ID_GAME_MASTER); @@ -132,8 +131,7 @@ GUIEngine::EventPropagation break; } } - packet.toNetworkString(&change); - Comm::sendToServer(&change, PRM_RELIABLE); + sendPacketToServer(packet); return GUIEngine::EVENT_BLOCK; } } diff --git a/src/states_screens/online/network_kart_selection.cpp b/src/states_screens/online/network_kart_selection.cpp index 10e962aa53a..c1a013eddd2 100644 --- a/src/states_screens/online/network_kart_selection.cpp +++ b/src/states_screens/online/network_kart_selection.cpp @@ -123,7 +123,6 @@ void NetworkKartSelectionScreen::allPlayersDone() } const uint8_t kart_count = (uint8_t)m_kart_widgets.size(); - NetworkString kart(PROTOCOL_LOBBY_ROOM); PlayerKartsPacket karts_packet; karts_packet.players_count = kart_count; @@ -158,16 +157,15 @@ void NetworkKartSelectionScreen::allPlayersDone() LiveJoinRequestPacket packet; packet.is_spectator = false; packet.player_karts = karts_packet; - packet.toNetworkString(&kart); + sendPacketToServer(packet); } else { KartSelectionRequestPacket packet; packet.karts = karts_packet; - packet.toNetworkString(&kart); + sendPacketToServer(packet); } - Comm::sendToServer(&kart, PRM_RELIABLE); // ---- Switch to assign mode input_manager->getDeviceManager()->setAssignMode(ASSIGN); @@ -196,10 +194,8 @@ bool NetworkKartSelectionScreen::onEscapePressed() // Send go back lobby event to server with an exit timeout, so if // server doesn't react in time we exit the server m_exit_timeout = StkTime::getMonoTimeMs() + 5000; - NetworkString back(PROTOCOL_LOBBY_ROOM); ClientBackLobbyPacket packet; - packet.toNetworkString(&back); - Comm::sendToServer(&back, PRM_RELIABLE); + sendPacketToServer(packet); } return false; } diff --git a/src/states_screens/online/networking_lobby.cpp b/src/states_screens/online/networking_lobby.cpp index 9975c6bcc26..b4842d5f4fc 100644 --- a/src/states_screens/online/networking_lobby.cpp +++ b/src/states_screens/online/networking_lobby.cpp @@ -862,10 +862,8 @@ void NetworkingLobby::eventCallback(Widget* widget, const std::string& name, else { // Send a message to the server to start - NetworkString start(PROTOCOL_LOBBY_ROOM); RequestBeginPacket packet; - packet.toNetworkString(&start); - Comm::sendToServer(&start, PRM_RELIABLE); + sendPacketToServer(packet); } } else if (name == m_config_button->m_properties[PROP_ID]) @@ -880,11 +878,9 @@ void NetworkingLobby::eventCallback(Widget* widget, const std::string& name, auto cl = LobbyProtocol::get(); if (m_client_live_joinable && cl) { - NetworkString start(PROTOCOL_LOBBY_ROOM); LiveJoinRequestPacket packet; packet.is_spectator = true; - packet.toNetworkString(&start); - Comm::sendToServer(&start, PRM_RELIABLE); + sendPacketToServer(packet); return; } if (cl) diff --git a/src/tracks/check_structure.hpp b/src/tracks/check_structure.hpp index 30021e427ad..e7f58859f17 100644 --- a/src/tracks/check_structure.hpp +++ b/src/tracks/check_structure.hpp @@ -26,7 +26,6 @@ #include "utils/aligned_array.hpp" #include "utils/vec3.hpp" -class BareNetworkString; class CheckManager; class Track; class XMLNode; diff --git a/src/tracks/track_sector.cpp b/src/tracks/track_sector.cpp index 92ed7d6d613..b9a8720a04f 100644 --- a/src/tracks/track_sector.cpp +++ b/src/tracks/track_sector.cpp @@ -180,26 +180,28 @@ float TrackSector::getRelativeDistanceToCenter() const // ---------------------------------------------------------------------------- /** Only basket ball is used for rewind for TrackSector so save the minimum. */ -void TrackSector::saveState(BareNetworkString* buffer) const +TrackSectorSmallPacket TrackSector::saveState() const { - buffer->addUInt16((int16_t)m_current_graph_node); - buffer->addFloat(m_current_track_coords.getZ()); + TrackSectorSmallPacket packet; + packet.cur_graph_mode = (int16_t)m_current_graph_node; + packet.coord_z = m_current_track_coords.getZ(); + return packet; } // saveState // ---------------------------------------------------------------------------- -void TrackSector::rewindTo(BareNetworkString* buffer) +void TrackSector::rewindTo(const TrackSectorSmallPacket& packet) { - int16_t node = buffer->getUInt16(); + int16_t node = packet.cur_graph_mode; m_current_graph_node = node; - m_current_track_coords.setZ(buffer->getFloat()); + m_current_track_coords.setZ(packet.coord_z); } // rewindTo // ---------------------------------------------------------------------------- /** Save completely for spectating in linear race */ -TrackSectorPacket TrackSector::saveCompleteState() +TrackSectorCompleteStatePacket TrackSector::saveCompleteState() { - TrackSectorPacket packet; + TrackSectorCompleteStatePacket packet; packet.current_graph_node = m_current_graph_node; packet.estimated_valid_graph_node = m_estimated_valid_graph_node; packet.last_valid_graph_node = m_last_valid_graph_node; @@ -212,7 +214,7 @@ TrackSectorPacket TrackSector::saveCompleteState() } // saveCompleteState // ---------------------------------------------------------------------------- -void TrackSector::restoreCompleteState(const TrackSectorPacket& packet) +void TrackSector::restoreCompleteState(const TrackSectorCompleteStatePacket& packet) { const int max_node = Graph::get()->getNumNodes(); m_current_graph_node = packet.current_graph_node; diff --git a/src/tracks/track_sector.hpp b/src/tracks/track_sector.hpp index 818b88002b0..c56eafe3474 100644 --- a/src/tracks/track_sector.hpp +++ b/src/tracks/track_sector.hpp @@ -21,9 +21,9 @@ #include "utils/vec3.hpp" -class BareNetworkString; class Track; -class TrackSectorPacket; +class TrackSectorCompleteStatePacket; +class TrackSectorSmallPacket; /** This object keeps track of which sector an object is on. A sector is * actually just the graph node (it's called sector to better distinguish @@ -96,13 +96,13 @@ class TrackSector // ------------------------------------------------------------------------ int getLastValidGraphNode() const { return m_last_valid_graph_node; } // ------------------------------------------------------------------------ - void saveState(BareNetworkString* buffer) const; + TrackSectorSmallPacket saveState() const; // ------------------------------------------------------------------------ - void rewindTo(BareNetworkString* buffer); + void rewindTo(const TrackSectorSmallPacket& packet); // ------------------------------------------------------------------------ - TrackSectorPacket saveCompleteState(); + TrackSectorCompleteStatePacket saveCompleteState(); // ------------------------------------------------------------------------ - void restoreCompleteState(const TrackSectorPacket& packet); + void restoreCompleteState(const TrackSectorCompleteStatePacket& packet); }; // TrackSector diff --git a/src/utils/chat_manager.cpp b/src/utils/chat_manager.cpp index d89b4fd68d3..94bde934569 100644 --- a/src/utils/chat_manager.cpp +++ b/src/utils/chat_manager.cpp @@ -229,21 +229,18 @@ void ChatManager::handleNormalChatMessage(std::shared_ptr peer, if (target_team == KART_TEAM_BLUE || (team_speaker && team_mode && teams.has(KART_TEAM_BLUE))) message = g_blue_team + message; - NetworkString* chat = getLobby()->getNetworkString(); ChatPacket packet; packet.message = StringUtils::utf8ToWide(message); - packet.toNetworkString(chat); - STKHost::get()->sendNetstringToAllPeersWith( + STKHost::get()->sendPacketToAllPeersWith( std::bind(&ChatManager::shouldMessageBeSent, this, peer, std::placeholders::_1, game_started, target_team - ), chat + ), packet ); - delete chat; peer->updateLastMessage(); } // handleNormalChatMessage From 529537e93a711df51687814023a956a14cc5b62a Mon Sep 17 00:00:00 2001 From: kimden <23140380+kimden@users.noreply.github.com> Date: Fri, 25 Apr 2025 22:03:45 +0400 Subject: [PATCH 25/34] Small packet processing attempts --- src/karts/abstract_kart_animation.cpp | 26 ++++++++++++++------------ src/karts/abstract_kart_animation.hpp | 4 ++-- src/network/packet_types_base.hpp | 8 ++++++++ 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/karts/abstract_kart_animation.cpp b/src/karts/abstract_kart_animation.cpp index f6fadc9536a..9151ac26bac 100644 --- a/src/karts/abstract_kart_animation.cpp +++ b/src/karts/abstract_kart_animation.cpp @@ -179,25 +179,27 @@ float AbstractKartAnimation::getMaximumHeight(const Vec3& up_vector, } // getMaximumHeight // ---------------------------------------------------------------------------- -void AbstractKartAnimation::saveState(BareNetworkString* buffer) +AbstractKartAnimationPacket AbstractKartAnimation::saveState() { - buffer->addUInt32(m_created_ticks); - buffer->addInt24(m_created_transform_compressed[0]) - .addInt24(m_created_transform_compressed[1]) - .addInt24(m_created_transform_compressed[2]) - .addUInt32(m_created_transform_compressed[3]); + AbstractKartAnimationPacket packet; + packet.created_ticks = m_created_ticks; + packet.transform_compressed_0 = m_created_transform_compressed[0]; + packet.transform_compressed_1 = m_created_transform_compressed[1]; + packet.transform_compressed_2 = m_created_transform_compressed[2]; + packet.transform_compressed_3 = m_created_transform_compressed[3]; + return packet; } // saveState // ---------------------------------------------------------------------------- /** Used in constructor of sub-class as no virtual function can be used there. */ -void AbstractKartAnimation::restoreBasicState(BareNetworkString* buffer) +void AbstractKartAnimation::restoreBasicState(const AbstractKartAnimationPacket& packet) { - m_created_ticks = buffer->getUInt32(); - m_created_transform_compressed[0] = buffer->getInt24(); - m_created_transform_compressed[1] = buffer->getInt24(); - m_created_transform_compressed[2] = buffer->getInt24(); - m_created_transform_compressed[3] = buffer->getUInt32(); + m_created_ticks = packet.created_ticks; + m_created_transform_compressed[0] = packet.transform_compressed_0; + m_created_transform_compressed[1] = packet.transform_compressed_1; + m_created_transform_compressed[2] = packet.transform_compressed_2; + m_created_transform_compressed[3] = packet.transform_compressed_3; m_created_transform = MiniGLM::decompressbtTransform(m_created_transform_compressed); } // restoreBasicState diff --git a/src/karts/abstract_kart_animation.hpp b/src/karts/abstract_kart_animation.hpp index fea5c42f0b6..2b8bd5267a6 100644 --- a/src/karts/abstract_kart_animation.hpp +++ b/src/karts/abstract_kart_animation.hpp @@ -105,11 +105,11 @@ class AbstractKartAnimation: public NoCopy void handleResetRace() { m_end_ticks = std::numeric_limits::max(); } // ------------------------------------------------------------------------ /* Used to recreate animation in \ref KartRewinder. */ - virtual void saveState(BareNetworkString* buffer); + virtual AbstractKartAnimationPacket saveState(); // ------------------------------------------------------------------------ /* Called when kart animation is the same in kart state, which make sure * for example the end or created ticks are the same. */ - virtual void restoreState(BareNetworkString* buffer) + virtual void restoreState(const AbstractKartAnimationPacket& buffer) { restoreBasicState(buffer); } }; // AbstractKartAnimation diff --git a/src/network/packet_types_base.hpp b/src/network/packet_types_base.hpp index b9939b0d840..4b9af5c57d2 100644 --- a/src/network/packet_types_base.hpp +++ b/src/network/packet_types_base.hpp @@ -701,6 +701,14 @@ DEFINE_CLASS(TrackSectorSmallPacket) DEFINE_FIELD(float, coord_z) END_DEFINE_CLASS(TrackSectorSmallPacket) +DEFINE_CLASS(AbstractKartAnimationPacket) + DEFINE_FIELD(uint32_t, created_ticks) + DEFINE_FIELD(int24_t, transform_compressed_0) + DEFINE_FIELD(int24_t, transform_compressed_1) + DEFINE_FIELD(int24_t, transform_compressed_2) + DEFINE_FIELD(uint32_t, transform_compressed_3) +END_DEFINE_CLASS(AbstractKartAnimationPacket) + // todo From b430f4809adb86b46965555312eb6e5f97a4240d Mon Sep 17 00:00:00 2001 From: kimden <23140380+kimden@users.noreply.github.com> Date: Sat, 26 Apr 2025 02:41:58 +0400 Subject: [PATCH 26/34] Blind max speed packet processing [skip ci] --- src/karts/max_speed.cpp | 94 ++++++++++++++++--------------- src/karts/max_speed.hpp | 15 +++-- src/network/packet_types_base.hpp | 22 ++++++++ 3 files changed, 79 insertions(+), 52 deletions(-) diff --git a/src/karts/max_speed.cpp b/src/karts/max_speed.cpp index 34a3fc10ed8..dfda30c3e90 100644 --- a/src/karts/max_speed.cpp +++ b/src/karts/max_speed.cpp @@ -219,29 +219,23 @@ void MaxSpeed::SpeedIncrease::update(int ticks) } // SpeedIncrease::update // ---------------------------------------------------------------------------- -void MaxSpeed::SpeedIncrease::saveState(BareNetworkString *buffer) const +MaxSpeedSpeedIncreasePacket MaxSpeed::SpeedIncrease::saveState() const { - buffer->addUInt16(m_max_add_speed); - buffer->addUInt16(m_duration); - buffer->addUInt16(m_fade_out_time); - buffer->addUInt16(m_engine_force); + MaxSpeedSpeedIncreasePacket packet; + packet.max_add_speed = m_max_add_speed; + packet.duration = m_duration; + packet.fade_out_time = m_fade_out_time; + packet.engine_force = m_engine_force; + return packet; } // saveState // ---------------------------------------------------------------------------- -void MaxSpeed::SpeedIncrease::rewindTo(BareNetworkString *buffer, - bool is_active) +void MaxSpeed::SpeedIncrease::rewindTo(const MaxSpeedSpeedIncreasePacket& packet) { - if(is_active) - { - m_max_add_speed = buffer->getUInt16(); - m_duration = buffer->getUInt16(); - m_fade_out_time = buffer->getUInt16(); - m_engine_force = buffer->getUInt16(); - } - else // make sure to disable this category - { - reset(); - } + m_max_add_speed = packet.max_add_speed; + m_duration = packet.duration; + m_fade_out_time = packet.fade_out_time; + m_engine_force = packet.engine_force; } // rewindTo // ---------------------------------------------------------------------------- @@ -336,31 +330,25 @@ void MaxSpeed::SpeedDecrease::update(int ticks) * if the speed decrease is not active. * \param buffer Buffer which will store the state information. */ -void MaxSpeed::SpeedDecrease::saveState(BareNetworkString *buffer) const +MaxSpeedSpeedDecreasePacket MaxSpeed::SpeedDecrease::saveState() const { - buffer->addUInt16(m_max_speed_fraction); - buffer->addFloat(m_current_fraction); - buffer->addUInt16(m_fade_in_ticks); - buffer->addUInt16(m_duration); + MaxSpeedSpeedDecreasePacket packet; + packet.max_speed_fraction = m_max_speed_fraction; + packet.current_fraction = m_current_fraction; + packet.fade_in_ticks = m_fade_in_ticks; + packet.duration = m_duration; + return packet; } // saveState // ---------------------------------------------------------------------------- /** Restores a previously saved state for an active speed decrease category. */ -void MaxSpeed::SpeedDecrease::rewindTo(BareNetworkString *buffer, - bool is_active) +void MaxSpeed::SpeedDecrease::rewindTo(const MaxSpeedSpeedDecreasePacket& packet) { - if(is_active) - { - m_max_speed_fraction = buffer->getUInt16(); - m_current_fraction = buffer->getFloat(); - m_fade_in_ticks = buffer->getUInt16(); - m_duration = buffer->getUInt16(); - } - else // make sure it is not active - { - reset(); - } + m_max_speed_fraction = packet.max_speed_fraction; + m_current_fraction = packet.current_fraction; + m_fade_in_ticks = packet.fade_in_ticks; + m_duration = packet.duration; } // rewindTo // ---------------------------------------------------------------------------- @@ -458,8 +446,10 @@ void MaxSpeed::update(int ticks) /** Saves the speed data in a network string for rewind. * \param buffer Pointer to the network string to store the data. */ -void MaxSpeed::saveState(BareNetworkString *buffer) const +MaxSpeedPacket MaxSpeed::saveState() const { + MaxSpeedPacket packet; + // Save the slowdown states // ------------------------ // Get the bit pattern of all active slowdowns @@ -472,7 +462,7 @@ void MaxSpeed::saveState(BareNetworkString *buffer) const if (m_speed_decrease[i].isActive()) active_slowdown |= b; } - buffer->addUInt8(active_slowdown); + packet.slowdown_mask = active_slowdown; for(unsigned int i=MS_DECREASE_MIN, b=1; iaddUInt8(active_speedups); + packet.speedup_mask = active_speedups; for(unsigned int i=MS_INCREASE_MIN, b=1; igetUInt8(); + uint8_t active_slowdown = packet.slowdown_mask; + + unsigned idx = 0; for(unsigned int i=MS_DECREASE_MIN, b=1; igetUInt8(); + idx = 0; + uint8_t active_speedups = packet.speedup_mask; for(unsigned int i=MS_INCREASE_MIN, b=1; i Date: Sun, 27 Apr 2025 03:14:47 +0400 Subject: [PATCH 27/34] Saving progress (one more packet)... [skip ci] --- src/karts/skidding.cpp | 22 ++++++++++--------- src/karts/skidding.hpp | 6 +++--- src/modes/soccer_world.cpp | 5 ----- src/network/kart_data.hpp | 1 - src/network/packet_types_base.hpp | 29 ++++++++++++++++++++++++++ src/network/protocols/client_lobby.hpp | 1 - 6 files changed, 44 insertions(+), 20 deletions(-) diff --git a/src/karts/skidding.cpp b/src/karts/skidding.cpp index 1329e836068..ed96007b6c4 100644 --- a/src/karts/skidding.cpp +++ b/src/karts/skidding.cpp @@ -99,24 +99,26 @@ void Skidding::reset() * m_skid_bonus_ready * \param buffer Buffer for the state information. */ -void Skidding::saveState(BareNetworkString *buffer) +SkiddingStatePacket Skidding::saveState() { - buffer->addUInt8(m_skid_state); - buffer->addUInt16(m_skid_time); - buffer->addFloat(m_skid_factor); - buffer->addFloat(m_visual_rotation); + SkiddingStatePacket packet; + packet.skid_state = m_skid_state; + packet.skid_time = m_skid_time; + packet.skid_factor = m_skid_factor; + packet.visual_rotation = m_visual_rotation; + return packet; } // saveState // ---------------------------------------------------------------------------- /** Restores the skidding state of a kart. * \param buffer Buffer with state information. */ -void Skidding::rewindTo(BareNetworkString *buffer) +void Skidding::rewindTo(const SkiddingStatePacket& packet) { - m_skid_state = (SkidState)buffer->getUInt8(); - m_skid_time = buffer->getUInt16(); - m_skid_factor = buffer->getFloat(); - m_visual_rotation = buffer->getFloat(); + m_skid_state = (SkidState)packet.skid_state; + m_skid_time = packet.skid_time; + m_skid_factor = packet.skid_factor; + m_visual_rotation = packet.visual_rotation; } // rewindTo // ---------------------------------------------------------------------------- diff --git a/src/karts/skidding.hpp b/src/karts/skidding.hpp index c54ca14e674..0f564789c84 100644 --- a/src/karts/skidding.hpp +++ b/src/karts/skidding.hpp @@ -24,7 +24,7 @@ #include "utils/no_copy.hpp" #include "utils/types.hpp" -class BareNetworkString; +class SkiddingStatePacket; class Kart; class ShowCurve; @@ -111,8 +111,8 @@ friend class KartRewinder; float updateGraphics(float dt); void update(int dt, bool is_on_ground, float steer, KartControl::SkidControl skidding); - void saveState(BareNetworkString *buffer); - void rewindTo(BareNetworkString *buffer); + SkiddingStatePacket saveState(); + void rewindTo(const SkiddingStatePacket& packet); // ------------------------------------------------------------------------ /** Determines how much the graphics model of the kart should be rotated * additionally (for skidding), depending on how long the kart has been diff --git a/src/modes/soccer_world.cpp b/src/modes/soccer_world.cpp index d15b116f78c..300b1a667f3 100644 --- a/src/modes/soccer_world.cpp +++ b/src/modes/soccer_world.cpp @@ -700,11 +700,6 @@ void SoccerWorld::onCheckGoalTriggered(bool first_goal) packet_1_1.country_code = sd.m_country_code; packet_1_1.handicap = sd.m_handicap_level; - // NetworkString p(PROTOCOL_GAME_EVENTS); - // NetworkString p_1_1(PROTOCOL_GAME_EVENTS); - // packet.toNetworkString(&p); - // packet_1_1.toNetworkString(&p_1_1); - auto peers = STKHost::get()->getPeers(); for (auto& peer : peers) { diff --git a/src/network/kart_data.hpp b/src/network/kart_data.hpp index 95cbc08d83e..e31c757542d 100644 --- a/src/network/kart_data.hpp +++ b/src/network/kart_data.hpp @@ -6,7 +6,6 @@ #include -class BareNetworkString; class KartProperties; class KartData diff --git a/src/network/packet_types_base.hpp b/src/network/packet_types_base.hpp index a6c3b0fddbf..254f7bc0a74 100644 --- a/src/network/packet_types_base.hpp +++ b/src/network/packet_types_base.hpp @@ -731,6 +731,35 @@ DEFINE_CLASS(MaxSpeedPacket) DEFINE_VECTOR(MaxSpeedSpeedIncreasePacket, __builtin_popcount(speedup_mask), speedups) END_DEFINE_CLASS(MaxSpeedPacket) +DEFINE_CLASS(SkiddingStatePacket) + DEFINE_FIELD(uint8_t, skid_state) + DEFINE_FIELD(uint16_t, skid_time) + DEFINE_FIELD(float, skid_factor) + DEFINE_FIELD(float, visual_rotation) +END_DEFINE_CLASS(SkiddingStatePacket) + +// DEFINE_CLASS(ItemEventInfoPacket) +// DEFINE_FIELD(uint8_t, type) +// DEFINE_FIELD(uint32_t, ticks) +// DEFINE_FIELD_OPTIONAL(uint8_t, kart_id, type != IEI_SWITCH) +// DEFINE_FIELD_OPTIONAL(uint16_t, index, type != IEI_SWITCH) +// DEFINE_FIELD_OPTIONAL(uint16_t, index, type != IEI_SWITCH && type == IEI_NEW) + +// assert(NetworkConfig::get()->isServer()); +// buffer->addUInt8(m_type).addTime(m_ticks); +// if (m_type != IEI_SWITCH) +// { +// // Only new item and collecting items need the index and kart id: +// buffer->addUInt8(m_kart_id).addUInt16(m_index); +// if (m_type == IEI_NEW) +// { +// buffer->add(m_xyz); +// buffer->add(m_normal); +// } +// else if (m_type == IEI_COLLECT) +// buffer->addUInt16(m_ticks_till_return); +// } +// END_DEFINE_CLASS(ItemEventInfoPacket) // todo diff --git a/src/network/protocols/client_lobby.hpp b/src/network/protocols/client_lobby.hpp index 9d0d049c277..1216228d4f4 100644 --- a/src/network/protocols/client_lobby.hpp +++ b/src/network/protocols/client_lobby.hpp @@ -34,7 +34,6 @@ enum PeerDisconnectInfo : unsigned int; enum KartTeam : int8_t; enum HandicapLevel : uint8_t; -class BareNetworkString; class Server; namespace Online From f8013530c759b331d434c0b5cf13dc28ba0b5ff7 Mon Sep 17 00:00:00 2001 From: kimden <23140380+kimden@users.noreply.github.com> Date: Mon, 5 May 2025 23:04:14 +0400 Subject: [PATCH 28/34] Packet id + some packets [skip ci] for now --- src/network/packet_types.hpp | 57 +++++++++++++++++++++++++++++++ src/network/packet_types_base.hpp | 14 ++------ src/utils/game_info.hpp | 6 ++++ 3 files changed, 66 insertions(+), 11 deletions(-) diff --git a/src/network/packet_types.hpp b/src/network/packet_types.hpp index 30b85237760..2eb83641888 100644 --- a/src/network/packet_types.hpp +++ b/src/network/packet_types.hpp @@ -21,6 +21,7 @@ // #include "network/network_string.hpp" // #include "network/protocol.hpp" +#include "irrString.h" #include "network/protocols/game_event_types.hpp" #include "utils/cpp2011.hpp" #include "utils/types.hpp" @@ -34,7 +35,9 @@ class BareNetworkString; #include #include #include +#include +using widestr = irr::core::stringw; /** * IMPORTANT! * This class is meant to describe the overall structure of network packets @@ -169,6 +172,8 @@ class Storage } }; +enum PacketTypeId: uint16_t; + class Packet: public Checkable, public Storage { public: @@ -176,6 +181,9 @@ class Packet: public Checkable, public Storage // Needed to dynamic_cast virtual ~Packet() {} + + // 0 = NONE, but I haven't declared it yet + virtual PacketTypeId packetTypeId() const { return (PacketTypeId)0; } virtual void toNetworkString(NetworkString* ns) const {} virtual void fromNetworkString(NetworkString* ns) {} virtual unsigned expectedCapacity() const { return 0; } @@ -191,12 +199,58 @@ class Packet: public Checkable, public Storage constexpr int IDONT_KNOW = 0; constexpr bool UNUSED = false; + +//---------------------- Enum type id --------------------------------------- + +#define DEFINE_CLASS(Name) PTID_##Name, \ + +#define DEFINE_DERIVED_CLASS(Name, Parent) PTID_##Name, \ + +#define PROTOCOL_TYPE(Type, Sync) +#define AUX_STORE(Key, Var) +#define AUX_VAR(Type, Var) +#define AUX_VAR_VALUE(Type, Var, Value) +#define AUX_VAR_FROM_PARENT(Type, Key, Var) +#define DEFINE_FIELD(Type, Var) +#define DEFINE_FIELD16(Type, Var) +#define DEFINE_FIELD_PTR(Type, Var) +#define DEFINE_FIELD_OPTIONAL(Type, Var, Condition) +#define DEFINE_TYPE(Type, Var, Value) +#define DEFINE_VECTOR(Type, Size, Var) +#define DEFINE_VECTOR_PTR(Type, Size, Var) +#define RELIABLE(Value) +#define END_DEFINE_CLASS(Name) + +enum PacketTypeId: uint16_t +{ + PTID_NONE = 0, +#include "network/packet_types_base.hpp" +}; + +#undef DEFINE_CLASS +#undef DEFINE_DERIVED_CLASS +#undef PROTOCOL_TYPE +#undef AUX_STORE +#undef AUX_VAR +#undef AUX_VAR_VALUE +#undef AUX_VAR_FROM_PARENT +#undef DEFINE_FIELD +#undef DEFINE_FIELD16 +#undef DEFINE_FIELD_PTR +#undef DEFINE_TYPE +#undef DEFINE_FIELD_OPTIONAL +#undef DEFINE_VECTOR +#undef DEFINE_VECTOR_PTR +#undef RELIABLE +#undef END_DEFINE_CLASS + //---------------------- Initialization --------------------------------------- #define DEFINE_CLASS(Name) \ class Name: public Packet { \ public: \ virtual ~Name() {} \ + virtual PacketTypeId packetTypeId() const OVERRIDE { return PTID_##Name; } \ virtual void toNetworkString(NetworkString* ns) const OVERRIDE; \ virtual void fromNetworkString(NetworkString* ns) OVERRIDE; @@ -204,6 +258,7 @@ class Name: public Packet { \ class Name: public Parent { \ public: \ virtual ~Name() {} \ + virtual PacketTypeId packetTypeId() const OVERRIDE { return PTID_##Name; } \ virtual void toNetworkString(NetworkString* ns) const OVERRIDE; \ virtual void fromNetworkString(NetworkString* ns) OVERRIDE; @@ -242,4 +297,6 @@ class Name: public Parent { \ /* Don't forget to send RELIABLE(Value) packets with PRM_RELIABLE or PRM_UNRELIABLE if false */ +//---------------------- End --------------------------------------- + #endif // PACKET_TYPES_HPP diff --git a/src/network/packet_types_base.hpp b/src/network/packet_types_base.hpp index 254f7bc0a74..bb608009be7 100644 --- a/src/network/packet_types_base.hpp +++ b/src/network/packet_types_base.hpp @@ -40,14 +40,6 @@ * you can use either a #define or using = to pass it anyway. */ -#include "irrString.h" -#include "utils/types.hpp" - -#include -#include - -using widestr = irr::core::stringw; - // Note that bools are encoded using int8_t // Make sure all level 0 packets have protocol set! @@ -286,7 +278,7 @@ DEFINE_CLASS(LiveJoinPacket) PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, true) DEFINE_TYPE(uint8_t, type, LE_LIVE_JOIN_ACK) DEFINE_FIELD(uint64_t, client_starting_time) - DEFINE_FIELD(uint8_t, check_count); + DEFINE_FIELD(uint8_t, check_count) DEFINE_FIELD(uint64_t, live_join_start_time) DEFINE_FIELD(uint32_t, last_live_join_util_ticks) DEFINE_FIELD(NimCompleteStatePacket, nim_complete_state) @@ -351,7 +343,7 @@ END_DEFINE_CLASS(BackLobbyPacket) DEFINE_CLASS(ServerInfoPacket) PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, true) DEFINE_TYPE(uint8_t, type, LE_SERVER_INFO) - DEFINE_FIELD(std::string, server_name); + DEFINE_FIELD(std::string, server_name) DEFINE_FIELD(uint8_t, difficulty) DEFINE_FIELD(uint8_t, max_players) DEFINE_FIELD(uint8_t, extra_spectators_zero) @@ -413,7 +405,7 @@ END_DEFINE_CLASS(LiveJoinRequestPacket) DEFINE_CLASS(FinishedLoadingLiveJoinPacket) PROTOCOL_TYPE(PROTOCOL_LOBBY_ROOM, UNUSED) DEFINE_TYPE(uint8_t, type, LE_CLIENT_LOADED_WORLD) - RELIABLE(true); + RELIABLE(true) END_DEFINE_CLASS(FinishedLoadingLiveJoinPacket) DEFINE_CLASS(KartInfoRequestPacket) diff --git a/src/utils/game_info.hpp b/src/utils/game_info.hpp index e827450ffbc..d826173198a 100644 --- a/src/utils/game_info.hpp +++ b/src/utils/game_info.hpp @@ -57,6 +57,12 @@ struct GameInfo: public LobbyContextUser double m_game_duration = -1; int m_handicap = 0; std::string m_country_code = ""; + + // Added with version 3a + std::string m_vote_track_name = ""; + int m_vote_num_laps = -1; + int m_vote_reverse = -1; + std::string m_other_info = ""; PlayerInfo(bool reserved = false, bool game_event = false): From 6947e42e45c6909b0c20f786013b042ad246591e Mon Sep 17 00:00:00 2001 From: kimden <23140380+kimden@users.noreply.github.com> Date: Sat, 17 May 2025 01:08:53 +0400 Subject: [PATCH 29/34] Add a fake int24 --- src/network/network_string.cpp | 12 ++++++++++++ src/utils/types.hpp | 6 ++++++ 2 files changed, 18 insertions(+) diff --git a/src/network/network_string.cpp b/src/network/network_string.cpp index 363288f1fce..af3a1766600 100644 --- a/src/network/network_string.cpp +++ b/src/network/network_string.cpp @@ -381,6 +381,18 @@ void NetworkString::decodeSpecific(KartTeam& value) value = (KartTeam)u8; } // decodeSpecific(KartTeam) // //----------------------------------------------------------------------------- +template<> +void NetworkString::encodeSpecific(const int24_t& value) +{ + addInt24(value.value); +} // encodeSpecific(KartTeam) +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +template<> +void NetworkString::decodeSpecific(int24_t& value) +{ + value.value = getInt24(); +} // decodeSpecific(KartTeam) +// //----------------------------------------------------------------------------- // template<> // void NetworkString::encodeSpecific(const T& value) // { diff --git a/src/utils/types.hpp b/src/utils/types.hpp index 082e30e08a0..37b543f60ff 100644 --- a/src/utils/types.hpp +++ b/src/utils/types.hpp @@ -38,4 +38,10 @@ #endif #endif + struct int24_t + { + uint32_t value; + operator uint32_t() { return value; } + }; + #endif From cd5c413642a5d67ede003b78339065c9353a6ccb Mon Sep 17 00:00:00 2001 From: kimden <23140380+kimden@users.noreply.github.com> Date: Sat, 14 Jun 2025 20:29:00 +0400 Subject: [PATCH 30/34] Flyable and abstract animation packets, modify int24, remove unneeded exceptions [skip ci] --- src/items/flyable.cpp | 65 ++++++++++++++++++--------- src/items/flyable.hpp | 8 ++-- src/items/network_item_manager.hpp | 5 ++- src/items/plunger.hpp | 5 ++- src/items/rubber_ball.hpp | 5 ++- src/karts/abstract_kart_animation.cpp | 6 +-- src/karts/abstract_kart_animation.hpp | 16 +++---- src/karts/cannon_animation.cpp | 20 +-------- src/karts/kart_rewinder.cpp | 3 +- src/network/compress_network_body.hpp | 46 +++++++++++-------- src/network/packet_types_base.hpp | 23 ++++++++++ src/network/rewinder.hpp | 2 +- src/utils/types.hpp | 8 +++- 13 files changed, 130 insertions(+), 82 deletions(-) diff --git a/src/items/flyable.cpp b/src/items/flyable.cpp index cef9dcfded6..5268f76d52c 100644 --- a/src/items/flyable.cpp +++ b/src/items/flyable.cpp @@ -664,58 +664,77 @@ void Flyable::moveToInfinity(bool set_moveable_trans) } // moveToInfinity // ---------------------------------------------------------------------------- -BareNetworkString* Flyable::saveState(std::vector* ru) + +FlyablePacket Flyable::saveState(std::vector* ru) { + FlyablePacket packet; + if (m_has_hit_something) - return NULL; + return packet; ru->push_back(getUniqueIdentity()); - BareNetworkString* buffer = new BareNetworkString(); - uint16_t ticks_since_thrown_animation = (m_ticks_since_thrown & 32767) | - (hasAnimation() ? 32768 : 0); - buffer->addUInt16(ticks_since_thrown_animation); + packet.ticks_since_thrown_animation = + (m_ticks_since_thrown & 32767) | (hasAnimation() ? 32768 : 0); + if (m_do_terrain_info) - buffer->addUInt32(m_compressed_gravity_vector); + packet.compressed_gravity_vector = m_compressed_gravity_vector; if (hasAnimation()) - m_animation->saveState(buffer); + { + AbstractKartAnimationPacket subpacket = m_animation->saveState(); + packet.animation = subpacket; + } else { - CompressNetworkBody::compress( - m_body.get(), m_motion_state.get(), buffer); + packet.compressed_network_body = CompressNetworkBody::compress( + m_body.get(), m_motion_state.get()); } - return buffer; -} // saveState + return packet; +} // saveState // ---------------------------------------------------------------------------- -void Flyable::restoreState(BareNetworkString *buffer, int count) + +void Flyable::restoreState(const FlyablePacket& packet, int count) { - uint16_t ticks_since_thrown_animation = buffer->getUInt16(); + // kimden: nonvirtual: in which cases there can be nothing? + if (!packet.ticks_since_thrown_animation.has_value()) + return; + + uint16_t ticks_since_thrown_animation = packet.ticks_since_thrown_animation.get_value(); bool has_animation_in_state = (ticks_since_thrown_animation >> 15 & 1) == 1; + if (m_do_terrain_info) - m_compressed_gravity_vector = buffer->getUInt32(); + { + // kimden: nonvirtual: what if there's no value + if (packet.compressed_gravity_vector.has_value()) + m_compressed_gravity_vector = packet.compressed_gravity_vector.get_value(); + } if (has_animation_in_state) { + // kimden: nonvirtual: what if there's no value + AbstractKartAnimationPacket subpacket; + if (packet.animation.has_value()) + subpacket = packet.animation.get_value(); + // At the moment we only have cannon animation for rubber ball if (!m_animation) { try { - CannonAnimation* ca = new CannonAnimation(this, buffer); + CannonAnimation* ca = new CannonAnimation(this, subpacket); setAnimation(ca); } - catch (const KartAnimationCreationException& kace) + catch (const std::exception& kace) { Log::error("Flyable", "Kart animation creation error: %s", kace.what()); - buffer->skip(kace.getSkippingOffset()); } } else - m_animation->restoreState(buffer); + m_animation->restoreState(subpacket); } else { @@ -725,8 +744,14 @@ void Flyable::restoreState(BareNetworkString *buffer, int count) // will set m_animation to null delete m_animation; } + + // kimden: nonvirtual: what if there's no value + CompressedNetworkBodyPacket subpacket; + if (packet.compressed_network_body.has_value()) + subpacket = packet.compressed_network_body.get_value(); + CompressNetworkBody::decompress( - buffer, m_body.get(), m_motion_state.get()); + subpacket, m_body.get(), m_motion_state.get()); m_transform = m_body->getWorldTransform(); } m_ticks_since_thrown = ticks_since_thrown_animation & 32767; diff --git a/src/items/flyable.hpp b/src/items/flyable.hpp index e2734f60bbf..5dd827a1adf 100644 --- a/src/items/flyable.hpp +++ b/src/items/flyable.hpp @@ -22,11 +22,14 @@ #ifndef HEADER_FLYABLE_HPP #define HEADER_FLYABLE_HPP +#define nonvirtual + #include "items/powerup_manager.hpp" #include "karts/moveable.hpp" #include "network/rewinder.hpp" #include "tracks/terrain_info.hpp" #include "utils/cpp2011.hpp" +#include "network/packet_types.hpp" #include namespace irr @@ -259,10 +262,9 @@ class Flyable : public Moveable, public TerrainInfo, // ------------------------------------------------------------------------ virtual void computeError() OVERRIDE; // ------------------------------------------------------------------------ - virtual BareNetworkString* saveState(std::vector* ru) - OVERRIDE; + nonvirtual FlyablePacket saveState(std::vector* ru); // ------------------------------------------------------------------------ - virtual void restoreState(BareNetworkString *buffer, int count) OVERRIDE; + nonvirtual void restoreState(const FlyablePacket& packet, int count); // ------------------------------------------------------------------------ /* Return true if still in game state, or otherwise can be deleted. */ bool hasServerState() const { return m_has_server_state; } diff --git a/src/items/network_item_manager.hpp b/src/items/network_item_manager.hpp index d51e93690fc..523a4b94940 100644 --- a/src/items/network_item_manager.hpp +++ b/src/items/network_item_manager.hpp @@ -32,6 +32,8 @@ class STKPeer; class NimCompleteStatePacket; +#define nonvirtual + /** \ingroup items * The network item manager is responsible for handling all network related * item manager tasks - synchronisation between clients and servers. It @@ -82,8 +84,7 @@ class NetworkItemManager : public Rewinder, public ItemManager const AbstractKart *kart, const Vec3 *server_xyz = NULL, const Vec3 *server_normal = NULL) OVERRIDE; - virtual BareNetworkString* saveState(std::vector* ru) - OVERRIDE; + nonvirtual BareNetworkString* saveState(std::vector* ru); virtual void restoreState(BareNetworkString *buffer, int count) OVERRIDE; // ------------------------------------------------------------------------ virtual void rewindToEvent(BareNetworkString *bns) OVERRIDE {}; diff --git a/src/items/plunger.hpp b/src/items/plunger.hpp index de72bae014f..18a592f8d1e 100644 --- a/src/items/plunger.hpp +++ b/src/items/plunger.hpp @@ -22,6 +22,8 @@ #ifndef HEADER_MISSILE_HPP #define HEADER_MISSILE_HPP +#define nonvirtual + #include using namespace irr; @@ -67,8 +69,7 @@ class Plunger : public Flyable /** No hit effect when it ends. */ virtual HitEffect *getHitEffect() const OVERRIDE { return NULL; } // ------------------------------------------------------------------------ - virtual BareNetworkString* saveState(std::vector* ru) - OVERRIDE; + nonvirtual BareNetworkString* saveState(std::vector* ru); // ------------------------------------------------------------------------ virtual void restoreState(BareNetworkString *buffer, int count) OVERRIDE; // ------------------------------------------------------------------------ diff --git a/src/items/rubber_ball.hpp b/src/items/rubber_ball.hpp index 034c9229d74..4d46b9c867d 100644 --- a/src/items/rubber_ball.hpp +++ b/src/items/rubber_ball.hpp @@ -19,6 +19,8 @@ #ifndef HEADER_RUBBER_BALL_HPP #define HEADER_RUBBER_BALL_HPP +#define nonvirtual + #include #include "items/flyable.hpp" @@ -222,8 +224,7 @@ class RubberBall: public Flyable, public TrackSector * karts are handled by this hit() function. */ //virtual HitEffect *getHitEffect() const {return NULL; } // ------------------------------------------------------------------------ - virtual BareNetworkString* saveState(std::vector* ru) - OVERRIDE; + nonvirtual BareNetworkString* saveState(std::vector* ru); // ------------------------------------------------------------------------ virtual void restoreState(BareNetworkString *buffer, int count) OVERRIDE; // ------------------------------------------------------------------------ diff --git a/src/karts/abstract_kart_animation.cpp b/src/karts/abstract_kart_animation.cpp index 9151ac26bac..794b5e8d9a6 100644 --- a/src/karts/abstract_kart_animation.cpp +++ b/src/karts/abstract_kart_animation.cpp @@ -196,9 +196,9 @@ AbstractKartAnimationPacket AbstractKartAnimation::saveState() void AbstractKartAnimation::restoreBasicState(const AbstractKartAnimationPacket& packet) { m_created_ticks = packet.created_ticks; - m_created_transform_compressed[0] = packet.transform_compressed_0; - m_created_transform_compressed[1] = packet.transform_compressed_1; - m_created_transform_compressed[2] = packet.transform_compressed_2; + m_created_transform_compressed[0] = (uint32_t)packet.transform_compressed_0; + m_created_transform_compressed[1] = (uint32_t)packet.transform_compressed_1; + m_created_transform_compressed[2] = (uint32_t)packet.transform_compressed_2; m_created_transform_compressed[3] = packet.transform_compressed_3; m_created_transform = MiniGLM::decompressbtTransform(m_created_transform_compressed); diff --git a/src/karts/abstract_kart_animation.hpp b/src/karts/abstract_kart_animation.hpp index 2b8bd5267a6..986fcf9d197 100644 --- a/src/karts/abstract_kart_animation.hpp +++ b/src/karts/abstract_kart_animation.hpp @@ -19,6 +19,8 @@ #ifndef HEADER_ABSTRACT_KART_ANIMATION_HPP #define HEADER_ABSTRACT_KART_ANIMATION_HPP +#define nonvirtual + #include "LinearMath/btTransform.h" #include "config/stk_config.hpp" @@ -39,14 +41,6 @@ enum KartAnimationType : uint8_t KAT_CANNON = 2 }; -/** Exception for kart animation creation in networking, so if thrown it will - * tell the num of bytes skipping in the game state. */ -class KartAnimationCreationException : public std::exception -{ -public: - virtual int getSkippingOffset() const = 0; -}; - /** The base class for all kart animation, like rescue, explosion, or cannon. * Kart animations are done by removing the physics body from the physics * world, and instead modifying the rotation and position of the kart @@ -81,7 +75,7 @@ class AbstractKartAnimation: public NoCopy void resetPowerUp(); // ------------------------------------------------------------------------ - void restoreBasicState(BareNetworkString* buffer); + void restoreBasicState(const AbstractKartAnimationPacket& buffer); // ------------------------------------------------------------------------ float getMaximumHeight(const Vec3& up_vector, float height_remove); @@ -109,7 +103,9 @@ class AbstractKartAnimation: public NoCopy // ------------------------------------------------------------------------ /* Called when kart animation is the same in kart state, which make sure * for example the end or created ticks are the same. */ - virtual void restoreState(const AbstractKartAnimationPacket& buffer) + + // AbstractKartAnimationPacket + nonvirtual void restoreState(const AbstractKartAnimationPacket& buffer) { restoreBasicState(buffer); } }; // AbstractKartAnimation diff --git a/src/karts/cannon_animation.cpp b/src/karts/cannon_animation.cpp index 2e56e7355cb..d75bcb15ef2 100644 --- a/src/karts/cannon_animation.cpp +++ b/src/karts/cannon_animation.cpp @@ -384,34 +384,18 @@ void CannonAnimation::restoreData(BareNetworkString* buffer) // Kart cannon has 2 floats + 1 compressed quaternion // Flyable has 1 float (delta) const int skipping_offset = m_kart ? 12 : 4; - class CannonCreationException : public KartAnimationCreationException - { - private: - const std::string m_error; - - const int m_skipping_offset; - public: - CannonCreationException(const std::string& error, int skipping_offset) - : m_error(error), m_skipping_offset(skipping_offset) {} - // -------------------------------------------------------------------- - virtual int getSkippingOffset() const { return m_skipping_offset; } - // -------------------------------------------------------------------- - virtual const char* what() const throw() { return m_error.c_str(); } - }; int cc_idx = buffer->getInt8(); CheckManager* cm = Track::getCurrentTrack()->getCheckManager(); if ((unsigned)cc_idx > cm->getCheckStructureCount()) { - throw CannonCreationException( - "Server has different check structure size.", skipping_offset); + throw std::logic_error("Server has different check structure size."); } CheckCannon* cc = dynamic_cast (cm->getCheckStructure(cc_idx)); if (!cc) { - throw CannonCreationException( - "Server has different check cannon index.", skipping_offset); + throw std::logic_error("Server has different check cannon index."); } float skid_rot = 0.0f; float fraction_of_line = 0.0f; diff --git a/src/karts/kart_rewinder.cpp b/src/karts/kart_rewinder.cpp index 0cb9af76e30..d58761adf33 100644 --- a/src/karts/kart_rewinder.cpp +++ b/src/karts/kart_rewinder.cpp @@ -354,11 +354,10 @@ void KartRewinder::restoreState(BareNetworkString *buffer, int count) break; } } - catch (const KartAnimationCreationException& kace) + catch (const std::exception& kace) { Log::error("KartRewinder", "Kart animation creation error: %s", kace.what()); - buffer->skip(kace.getSkippingOffset()); m_kart_animation = NULL; } } diff --git a/src/network/compress_network_body.hpp b/src/network/compress_network_body.hpp index 9071cc521b8..b9f6b281d6d 100644 --- a/src/network/compress_network_body.hpp +++ b/src/network/compress_network_body.hpp @@ -59,7 +59,7 @@ namespace CompressNetworkBody * and server have similar state when saving state if you don't provoide * bns. */ - inline void compress(btRigidBody* body, btMotionState* ms, + inline CompressedNetworkBodyPacket compress(btRigidBody* body, btMotionState* ms, BareNetworkString* bns = NULL) { float x = body->getWorldTransform().getOrigin().x(); @@ -75,29 +75,39 @@ namespace CompressNetworkBody short avz = toFloat16(body->getAngularVelocity().z()); setCompressedValues(x, y, z, compressed_q, lvx, lvy, lvz, avx, avy, avz, body, ms); - // if bns is null, it's locally compress (for rounding values) - if (!bns) - return; - bns->addFloat(x).addFloat(y).addFloat(z).addUInt32(compressed_q); - bns->addUInt16(lvx).addUInt16(lvy).addUInt16(lvz) - .addUInt16(avx).addUInt16(avy).addUInt16(avz); + // if bns is null, it's locally compressed (for rounding values) + // in that case, we simply disregard the result, and before it returned NULL + + CompressedNetworkBodyPacket packet; + packet.x = x; + packet.y = y; + packet.z = z; + packet.compressed_q = compressed_q; + packet.lvx = lvx; + packet.lvy = lvy; + packet.lvz = lvz; + packet.avx = avx; + packet.avy = avy; + packet.avz = avz; + + return packet; } // compress // ------------------------------------------------------------------------ /* Called during rewind when restoring data from game state. */ - inline void decompress(const BareNetworkString* bns, + inline void decompress(const CompressedNetworkBodyPacket& packet, btRigidBody* body, btMotionState* ms) { - float x = bns->getFloat(); - float y = bns->getFloat(); - float z = bns->getFloat(); - uint32_t compressed_q = bns->getUInt32(); - short lvx = bns->getUInt16(); - short lvy = bns->getUInt16(); - short lvz = bns->getUInt16(); - short avx = bns->getUInt16(); - short avy = bns->getUInt16(); - short avz = bns->getUInt16(); + float x = packet.x; + float y = packet.y; + float z = packet.z; + uint32_t compressed_q = packet.compressed_q; + short lvx = packet.lvx; + short lvy = packet.lvy; + short lvz = packet.lvz; + short avx = packet.avx; + short avy = packet.avy; + short avz = packet.avz; setCompressedValues(x, y, z, compressed_q, lvx, lvy, lvz, avx, avy, avz, body, ms); } // decompress diff --git a/src/network/packet_types_base.hpp b/src/network/packet_types_base.hpp index bb608009be7..0f757c48aa1 100644 --- a/src/network/packet_types_base.hpp +++ b/src/network/packet_types_base.hpp @@ -766,4 +766,27 @@ DEFINE_CLASS(AttachmentPacket) DEFINE_FIELD_OPTIONAL(PluginStatePacket, plugin, ((type >> 7) & 1) == 1) END_DEFINE_CLASS(AttachmentPacket) +DEFINE_CLASS(CompressedNetworkBodyPacket) + DEFINE_FIELD(float, x) + DEFINE_FIELD(float, y) + DEFINE_FIELD(float, z) + DEFINE_FIELD(uint32_t, compressed_q) + DEFINE_FIELD(uint16_t, lvx) + DEFINE_FIELD(uint16_t, lvy) + DEFINE_FIELD(uint16_t, lvz) + DEFINE_FIELD(uint16_t, avx) + DEFINE_FIELD(uint16_t, avy) + DEFINE_FIELD(uint16_t, avz) +END_DEFINE_CLASS(CompressedNetworkBodyPacket) + +DEFINE_CLASS(FlyablePacket) + // sometimes nothing??? + DEFINE_FIELD_OPTIONAL(uint16_t, ticks_since_thrown_animation, IHAVENOIDEA) + DEFINE_FIELD_OPTIONAL(uint32_t, compressed_gravity_vector, IHAVENOIDEA) + DEFINE_FIELD_OPTIONAL(AbstractKartAnimationPacket, animation, IHAVENOIDEA) + DEFINE_FIELD_OPTIONAL(CompressedNetworkBodyPacket, compressed_network_body, IHAVENOIDEA) +END_DEFINE_CLASS(FlyablePacket) + + + // end \ No newline at end of file diff --git a/src/network/rewinder.hpp b/src/network/rewinder.hpp index c47a960b78b..9f89072b3f4 100644 --- a/src/network/rewinder.hpp +++ b/src/network/rewinder.hpp @@ -75,7 +75,7 @@ class Rewinder : public std::enable_shared_from_this * \param[out] ru The unique identity of rewinder writing to. * \return The address of the memory buffer with the state. */ - virtual BareNetworkString* saveState(std::vector* ru) = 0; + virtual BareNetworkString* saveStateDeprecated(std::vector* ru) = 0; /** Called when an event needs to be undone. This is called while going * backwards for rewinding - all stored events will get an 'undo' call. diff --git a/src/utils/types.hpp b/src/utils/types.hpp index 37b543f60ff..1fa6339e6ba 100644 --- a/src/utils/types.hpp +++ b/src/utils/types.hpp @@ -41,7 +41,13 @@ struct int24_t { uint32_t value; - operator uint32_t() { return value; } + operator uint32_t() const { return value; } + + int24_t& operator = (uint32_t rhs) + { + value = rhs; + return *this; + } }; #endif From f89d8fa2f7a8311b433b02c7c9da12a420c53f38 Mon Sep 17 00:00:00 2001 From: kimden <23140380+kimden@users.noreply.github.com> Date: Sun, 15 Jun 2025 17:08:37 +0400 Subject: [PATCH 31/34] A few more flyable packets, then it becomes harder [skip ci] --- src/items/network_item_manager.hpp | 2 +- src/items/plunger.cpp | 37 ++++++++---- src/items/plunger.hpp | 4 +- src/items/rubber_ball.cpp | 97 +++++++++++++++++------------- src/items/rubber_ball.hpp | 4 +- src/karts/cannon_animation.cpp | 12 ++-- src/karts/cannon_animation.hpp | 4 +- src/network/packet_types_base.hpp | 33 ++++++++++ src/network/rewinder.hpp | 6 +- 9 files changed, 129 insertions(+), 70 deletions(-) diff --git a/src/items/network_item_manager.hpp b/src/items/network_item_manager.hpp index 523a4b94940..ed6dc5409e3 100644 --- a/src/items/network_item_manager.hpp +++ b/src/items/network_item_manager.hpp @@ -85,7 +85,7 @@ class NetworkItemManager : public Rewinder, public ItemManager const Vec3 *server_xyz = NULL, const Vec3 *server_normal = NULL) OVERRIDE; nonvirtual BareNetworkString* saveState(std::vector* ru); - virtual void restoreState(BareNetworkString *buffer, int count) OVERRIDE; + nonvirtual void restoreState(BareNetworkString *buffer, int count); // ------------------------------------------------------------------------ virtual void rewindToEvent(BareNetworkString *bns) OVERRIDE {}; // ------------------------------------------------------------------------ diff --git a/src/items/plunger.cpp b/src/items/plunger.cpp index 0be206f73e4..b72dc125675 100644 --- a/src/items/plunger.cpp +++ b/src/items/plunger.cpp @@ -254,25 +254,36 @@ void Plunger::hitTrack() } // hitTrack // ---------------------------------------------------------------------------- -BareNetworkString* Plunger::saveState(std::vector* ru) +PlungerPacket Plunger::saveState(std::vector* ru) { - BareNetworkString* buffer = Flyable::saveState(ru); - if (!buffer) - return NULL; + PlungerPacket packet; + FlyablePacket subpacket = Flyable::saveState(ru); - buffer->addUInt16(m_keep_alive); + // kimden: it was checking before if BNS is null. + // Temporary solution is below. + if (!subpacket.ticks_since_thrown_animation.has_value()) + return packet; + + packet.flyable_packet = subpacket; + packet.keep_alive = m_keep_alive; + uint8_t state = 255; if (m_rubber_band) - buffer->addUInt8(m_rubber_band->get8BitState()); - else - buffer->addUInt8(255); - return buffer; + state = m_rubber_band->get8BitState(); + packet.rubber_band_state = state; + return packet; } // saveState // ---------------------------------------------------------------------------- -void Plunger::restoreState(BareNetworkString *buffer, int count) +void Plunger::restoreState(const PlungerPacket& packet, int count) { - Flyable::restoreState(buffer, count); - m_keep_alive = buffer->getUInt16(); + // kimden: nonvirtual: in which cases there can be nothing? + // I don't check the presence of other fields for now + // because they are supposed to be there too if flyable_packet is present. + if (!packet.flyable_packet.has_value()) + return; + + Flyable::restoreState(packet.flyable_packet.get_value(), count); + m_keep_alive = packet.keep_alive.get_value(); // Restore position base on m_keep_alive in Plunger::hit if (m_keep_alive == -1) m_moved_to_infinity = false; @@ -282,7 +293,7 @@ void Plunger::restoreState(BareNetworkString *buffer, int count) m_moved_to_infinity = true; } - uint8_t bit_state = buffer->getUInt8(); + uint8_t bit_state = packet.rubber_band_state.get_value(); if (bit_state == 255 && m_rubber_band) { delete m_rubber_band; diff --git a/src/items/plunger.hpp b/src/items/plunger.hpp index 18a592f8d1e..0e51b6d76a7 100644 --- a/src/items/plunger.hpp +++ b/src/items/plunger.hpp @@ -69,9 +69,9 @@ class Plunger : public Flyable /** No hit effect when it ends. */ virtual HitEffect *getHitEffect() const OVERRIDE { return NULL; } // ------------------------------------------------------------------------ - nonvirtual BareNetworkString* saveState(std::vector* ru); + nonvirtual PlungerPacket saveState(std::vector* ru); // ------------------------------------------------------------------------ - virtual void restoreState(BareNetworkString *buffer, int count) OVERRIDE; + nonvirtual void restoreState(const PlungerPacket& packet, int count); // ------------------------------------------------------------------------ virtual void onFireFlyable() OVERRIDE; // ------------------------------------------------------------------------ diff --git a/src/items/rubber_ball.cpp b/src/items/rubber_ball.cpp index bb6413e99ac..6a2bd3d2a86 100644 --- a/src/items/rubber_ball.cpp +++ b/src/items/rubber_ball.cpp @@ -886,57 +886,70 @@ bool RubberBall::hit(AbstractKart* kart, PhysicalObject* object) } // hit // ---------------------------------------------------------------------------- -BareNetworkString* RubberBall::saveState(std::vector* ru) +RubberBallPacket RubberBall::saveState(std::vector* ru) { - BareNetworkString* buffer = Flyable::saveState(ru); - if (!buffer) - return NULL; - - buffer->addUInt16((int16_t)m_last_aimed_graph_node); - buffer->add(m_control_points[0]); - buffer->add(m_control_points[1]); - buffer->add(m_control_points[2]); - buffer->add(m_control_points[3]); - buffer->add(m_previous_xyz); - buffer->addFloat(m_previous_height); - buffer->addFloat(m_length_cp_1_2); - buffer->addFloat(m_length_cp_2_3); - buffer->addFloat(m_t); - buffer->addFloat(m_t_increase); - buffer->addFloat(m_interval); - buffer->addFloat(m_height_timer); - buffer->addUInt16(m_delete_ticks); - buffer->addFloat(m_current_max_height); - buffer->addUInt8(m_tunnel_count | (m_aiming_at_target ? (1 << 7) : 0)); - TrackSector::saveState(buffer); - return buffer; + RubberBallPacket packet; + FlyablePacket subpacket = Flyable::saveState(ru); + + // kimden: it was checking before if BNS is null. + // Temporary solution is below. + if (!subpacket.ticks_since_thrown_animation.has_value()) + return packet; + + packet.flyable_packet = subpacket; + + packet.last_aimed_graph_node = (int16_t)m_last_aimed_graph_node; + packet.control_point_0 = m_control_points[0]; + packet.control_point_1 = m_control_points[1]; + packet.control_point_2 = m_control_points[2]; + packet.control_point_3 = m_control_points[3]; + packet.previous_xyz = m_previous_xyz; + packet.previous_height = m_previous_height; + packet.length_cp_1_2 = m_length_cp_1_2; + packet.length_cp_2_3 = m_length_cp_2_3; + packet.t = m_t; + packet.t_increase = m_t_increase; + packet.interval = m_interval; + packet.height_timer = m_height_timer; + packet.delete_ticks = m_delete_ticks; + packet.current_max_height = m_current_max_height; + packet.properties = m_tunnel_count | (m_aiming_at_target ? (1 << 7) : 0); + packet.track_sector = TrackSector::saveState(); + return packet; } // saveState // ---------------------------------------------------------------------------- -void RubberBall::restoreState(BareNetworkString *buffer, int count) +void RubberBall::restoreState(const RubberBallPacket& packet, int count) { - Flyable::restoreState(buffer, count); + // kimden: nonvirtual: in which cases there can be nothing? + // I don't check the presence of other fields for now + // because they are supposed to be there too if flyable_packet is present. + if (!packet.flyable_packet.has_value()) + return; + + Flyable::restoreState(packet.flyable_packet.get_value(), count); + m_restoring_state = true; - int16_t last_aimed_graph_node = buffer->getUInt16(); + int16_t last_aimed_graph_node = packet.last_aimed_graph_node.get_value(); m_last_aimed_graph_node = last_aimed_graph_node; - m_control_points[0] = buffer->getVec3(); - m_control_points[1] = buffer->getVec3(); - m_control_points[2] = buffer->getVec3(); - m_control_points[3] = buffer->getVec3(); - m_previous_xyz = buffer->getVec3(); - m_previous_height = buffer->getFloat(); - m_length_cp_1_2 = buffer->getFloat(); - m_length_cp_2_3 = buffer->getFloat(); - m_t = buffer->getFloat(); - m_t_increase = buffer->getFloat(); - m_interval = buffer->getFloat(); - m_height_timer = buffer->getFloat(); - m_delete_ticks = buffer->getUInt16(); - m_current_max_height = buffer->getFloat(); - uint8_t tunnel_and_aiming = buffer->getUInt8(); + m_control_points[0] = packet.control_point_0.get_value(); + m_control_points[1] = packet.control_point_1.get_value(); + m_control_points[2] = packet.control_point_2.get_value(); + m_control_points[3] = packet.control_point_3.get_value(); + m_previous_xyz = packet.previous_xyz.get_value(); + m_previous_height = packet.previous_height.get_value(); + m_length_cp_1_2 = packet.length_cp_1_2.get_value(); + m_length_cp_2_3 = packet.length_cp_2_3.get_value(); + m_t = packet.t.get_value(); + m_t_increase = packet.t_increase.get_value(); + m_interval = packet.interval.get_value(); + m_height_timer = packet.height_timer.get_value(); + m_delete_ticks = packet.delete_ticks.get_value(); + m_current_max_height = packet.current_max_height.get_value(); + uint8_t tunnel_and_aiming = packet.properties.get_value(); m_tunnel_count = tunnel_and_aiming & 127; m_aiming_at_target = ((tunnel_and_aiming >> 7) & 1) == 1; - TrackSector::rewindTo(buffer); + TrackSector::rewindTo(packet.track_sector.get_value()); } // restoreState // ---------------------------------------------------------------------------- diff --git a/src/items/rubber_ball.hpp b/src/items/rubber_ball.hpp index 4d46b9c867d..ec0817518c9 100644 --- a/src/items/rubber_ball.hpp +++ b/src/items/rubber_ball.hpp @@ -224,9 +224,9 @@ class RubberBall: public Flyable, public TrackSector * karts are handled by this hit() function. */ //virtual HitEffect *getHitEffect() const {return NULL; } // ------------------------------------------------------------------------ - nonvirtual BareNetworkString* saveState(std::vector* ru); + nonvirtual RubberBallPacket saveState(std::vector* ru); // ------------------------------------------------------------------------ - virtual void restoreState(BareNetworkString *buffer, int count) OVERRIDE; + nonvirtual void restoreState(const RubberBallPacket& packet, int count); // ------------------------------------------------------------------------ virtual void onFireFlyable() OVERRIDE; diff --git a/src/karts/cannon_animation.cpp b/src/karts/cannon_animation.cpp index d75bcb15ef2..5d508112c0d 100644 --- a/src/karts/cannon_animation.cpp +++ b/src/karts/cannon_animation.cpp @@ -61,14 +61,14 @@ CannonAnimation::CannonAnimation(AbstractKart* kart, CheckCannon* cc, // ---------------------------------------------------------------------------- /** The constructor for the cannon animation for kart during rewind. */ -CannonAnimation::CannonAnimation(AbstractKart* kart, BareNetworkString* buffer) +CannonAnimation::CannonAnimation(AbstractKart* kart, const AbstractKartAnimationPacket& packet) : AbstractKartAnimation(kart, "CannonAnimation") { - restoreBasicState(buffer); + restoreBasicState(packet); m_check_cannon = NULL; m_flyable = NULL; m_skid_rot = 0; - restoreData(buffer); + restoreData(packet); } // CannonAnimation // ---------------------------------------------------------------------------- @@ -89,14 +89,14 @@ CannonAnimation::CannonAnimation(Flyable* flyable, CheckCannon* cc) // ---------------------------------------------------------------------------- /** The constructor for the cannon animation for flyable during rewind. */ -CannonAnimation::CannonAnimation(Flyable* flyable, BareNetworkString* buffer) +CannonAnimation::CannonAnimation(Flyable* flyable, const AbstractKartAnimationPacket& packet) : AbstractKartAnimation(NULL, "CannonAnimation") { m_flyable = flyable; - restoreBasicState(buffer); + restoreBasicState(packet); m_check_cannon = NULL; m_skid_rot = 0; - restoreData(buffer); + restoreData(packet); } // CannonAnimation // ---------------------------------------------------------------------------- diff --git a/src/karts/cannon_animation.hpp b/src/karts/cannon_animation.hpp index 721522fe7eb..9fe379b27e2 100644 --- a/src/karts/cannon_animation.hpp +++ b/src/karts/cannon_animation.hpp @@ -41,9 +41,9 @@ class CannonAnimation: public AbstractKartAnimation friend class KartRewinder; friend class Flyable; // ------------------------------------------------------------------------ - CannonAnimation(AbstractKart* kart, BareNetworkString* buffer); + CannonAnimation(AbstractKart* kart, const AbstractKartAnimationPacket& packet); // ------------------------------------------------------------------------ - CannonAnimation(Flyable* flyable, BareNetworkString* buffer); + CannonAnimation(Flyable* flyable, const AbstractKartAnimationPacket& packet); // ------------------------------------------------------------------------ void init(Ipo *ipo, const Vec3 &start_left, const Vec3 &start_right, const Vec3 &end_left, const Vec3 &end_right, float skid_rot); diff --git a/src/network/packet_types_base.hpp b/src/network/packet_types_base.hpp index 0f757c48aa1..d9cb60ef0e1 100644 --- a/src/network/packet_types_base.hpp +++ b/src/network/packet_types_base.hpp @@ -787,6 +787,39 @@ DEFINE_CLASS(FlyablePacket) DEFINE_FIELD_OPTIONAL(CompressedNetworkBodyPacket, compressed_network_body, IHAVENOIDEA) END_DEFINE_CLASS(FlyablePacket) +DEFINE_CLASS(RubberBallPacket) + // sometimes nothing, depends on the same condition for FlyablePacket + DEFINE_FIELD_OPTIONAL(FlyablePacket, flyable_packet, IHAVENOIDEA) + DEFINE_FIELD_OPTIONAL(uint16_t, last_aimed_graph_node, IHAVENOIDEA) + DEFINE_FIELD_OPTIONAL(Vec3, control_point_0, IHAVENOIDEA) + DEFINE_FIELD_OPTIONAL(Vec3, control_point_1, IHAVENOIDEA) + DEFINE_FIELD_OPTIONAL(Vec3, control_point_2, IHAVENOIDEA) + DEFINE_FIELD_OPTIONAL(Vec3, control_point_3, IHAVENOIDEA) + DEFINE_FIELD_OPTIONAL(Vec3, previous_xyz, IHAVENOIDEA) + DEFINE_FIELD_OPTIONAL(float, previous_height, IHAVENOIDEA) + DEFINE_FIELD_OPTIONAL(float, length_cp_1_2, IHAVENOIDEA) + DEFINE_FIELD_OPTIONAL(float, length_cp_2_3, IHAVENOIDEA) + DEFINE_FIELD_OPTIONAL(float, t, IHAVENOIDEA) + DEFINE_FIELD_OPTIONAL(float, t_increase, IHAVENOIDEA) + DEFINE_FIELD_OPTIONAL(float, interval, IHAVENOIDEA) + DEFINE_FIELD_OPTIONAL(float, height_timer, IHAVENOIDEA) + DEFINE_FIELD_OPTIONAL(uint16_t, delete_ticks, IHAVENOIDEA) + DEFINE_FIELD_OPTIONAL(float, current_max_height, IHAVENOIDEA) + DEFINE_FIELD_OPTIONAL(uint8_t, properties, IHAVENOIDEA) + DEFINE_FIELD_OPTIONAL(TrackSectorSmallPacket, track_sector, IHAVENOIDEA) +END_DEFINE_CLASS(RubberBallPacket) + +DEFINE_CLASS(PlungerPacket) + // sometimes nothing, depends on the same condition for FlyablePacket + DEFINE_FIELD_OPTIONAL(FlyablePacket, flyable_packet, IHAVENOIDEA) + DEFINE_FIELD_OPTIONAL(uint16_t, keep_alive, IHAVENOIDEA) + DEFINE_FIELD_OPTIONAL(uint8_t, rubber_band_state, IHAVENOIDEA) +END_DEFINE_CLASS(PlungerPacket) + + + + + // end \ No newline at end of file diff --git a/src/network/rewinder.hpp b/src/network/rewinder.hpp index 9f89072b3f4..2e4a895d0fd 100644 --- a/src/network/rewinder.hpp +++ b/src/network/rewinder.hpp @@ -75,7 +75,8 @@ class Rewinder : public std::enable_shared_from_this * \param[out] ru The unique identity of rewinder writing to. * \return The address of the memory buffer with the state. */ - virtual BareNetworkString* saveStateDeprecated(std::vector* ru) = 0; + // kimden: nonvirtual: temporary non-0 + virtual BareNetworkString* saveStateDeprecated(std::vector* ru) {}; /** Called when an event needs to be undone. This is called while going * backwards for rewinding - all stored events will get an 'undo' call. @@ -91,7 +92,8 @@ class Rewinder : public std::enable_shared_from_this * rewind, i.e. when going forward in time again, and only for confirmed * states. */ - virtual void restoreState(BareNetworkString *buffer, int count) = 0; + // kimden: nonvirtual: temporary non-0 + virtual void restoreStateDeprecated(BareNetworkString *buffer, int count) {}; /** Undo the effects of the given state, but do not rewind to that * state (which is done by rewindTo). This is called while going From 7196df9c824eb67d594b7ae579ea922f90697938 Mon Sep 17 00:00:00 2001 From: kimden <23140380+kimden@users.noreply.github.com> Date: Wed, 9 Jul 2025 01:38:17 +0400 Subject: [PATCH 32/34] Fix a bit of mess in sendXXXToYYY functions - Move sendString, sendPacket to Comm:: - Keep sendPacketPtr, sendNetstring to STKHost - Leave a few sendNetstring-s in Comm:: as deprecated. [skip ci] --- src/modes/capture_the_flag.cpp | 3 +- src/modes/free_for_all.cpp | 5 +- src/modes/linear_world.cpp | 3 +- src/modes/soccer_world.cpp | 3 +- src/network/network_console.cpp | 2 +- src/network/protocol.hpp | 67 +------------------ src/network/protocols/client_lobby.cpp | 18 ++--- src/network/protocols/command_manager.cpp | 58 ++++++++-------- .../protocols/game_events_protocol.cpp | 6 +- src/network/protocols/game_protocol.cpp | 4 +- src/network/protocols/server_lobby.cpp | 53 +++++---------- src/network/protocols/server_lobby.hpp | 2 +- src/network/stk_host.cpp | 24 +++---- src/network/stk_host.hpp | 62 ++--------------- .../dialogs/network_player_dialog.cpp | 8 +-- .../dialogs/race_paused_dialog.cpp | 2 +- .../dialogs/server_configuration_dialog.cpp | 2 +- .../online/network_kart_selection.cpp | 6 +- .../online/networking_lobby.cpp | 4 +- src/states_screens/online/tracks_screen.cpp | 2 +- src/utils/chat_manager.cpp | 3 +- src/utils/communication.cpp | 34 +++++----- src/utils/communication.hpp | 58 +++++++++++++++- src/utils/game_info.cpp | 2 +- src/utils/hit_processor.cpp | 2 +- 25 files changed, 175 insertions(+), 258 deletions(-) diff --git a/src/modes/capture_the_flag.cpp b/src/modes/capture_the_flag.cpp index 64fa94310ed..dd8297d2625 100644 --- a/src/modes/capture_the_flag.cpp +++ b/src/modes/capture_the_flag.cpp @@ -35,6 +35,7 @@ #include "states_screens/race_gui.hpp" #include "tracks/track.hpp" #include "tracks/track_object_manager.hpp" +#include "utils/communication.hpp" #include "utils/game_info.hpp" #include "utils/string_utils.hpp" #include "utils/translation.hpp" @@ -346,7 +347,7 @@ void CaptureTheFlag::checkScoring(FlagColor color) packet.kart_score = (int16_t)new_kart_score; packet.red_score = (uint8_t)new_red_score; packet.blue_score = (uint8_t)new_blue_score; - STKHost::get()->sendPacketToAllPeers(packet); + Comm::sendPacketToPeers(packet); } ctfScored(active_holder, (red_active) ? false : true /*red_team_scored*/, new_kart_score, new_red_score, new_blue_score); diff --git a/src/modes/free_for_all.cpp b/src/modes/free_for_all.cpp index 769cb2533a5..62cbcd0765b 100644 --- a/src/modes/free_for_all.cpp +++ b/src/modes/free_for_all.cpp @@ -23,6 +23,7 @@ #include "network/protocols/game_events_protocol.hpp" #include "network/stk_host.hpp" #include "tracks/track.hpp" +#include "utils/communication.hpp" #include "utils/string_utils.hpp" #include @@ -136,7 +137,7 @@ void FreeForAll::handleScoreInServer(int kart_id, int hitter) packet.new_score = (int16_t)new_score; } - STKHost::get()->sendPacketToAllPeers(packet); + Comm::sendPacketToPeers(packet); } } // handleScoreInServer @@ -362,6 +363,6 @@ void FreeForAll::notifyAboutScoreIfNonzero(int id) packet.hitter_kart = (uint8_t)id; packet.new_score = (int16_t)m_scores[id]; - STKHost::get()->sendPacketToAllPeers(packet); + Comm::sendPacketToPeers(packet); } } // notifyAboutScoreIfNonzero diff --git a/src/modes/linear_world.cpp b/src/modes/linear_world.cpp index c769b5be5c2..a0fc14f4e56 100644 --- a/src/modes/linear_world.cpp +++ b/src/modes/linear_world.cpp @@ -47,6 +47,7 @@ #include "tracks/drive_node.hpp" #include "tracks/track_sector.hpp" #include "tracks/track.hpp" +#include "utils/communication.hpp" #include "utils/constants.hpp" #include "utils/string_utils.hpp" #include "utils/translation.hpp" @@ -1357,7 +1358,7 @@ void LinearWorld::updateCheckLinesServer(int check_id, int kart_id) cm->getCheckStructure(i)->saveIsActive(kart_id)); } - STKHost::get()->sendPacketToAllPeers(packet); + Comm::sendPacketToPeers(packet); } // updateCheckLinesServer // ---------------------------------------------------------------------------- diff --git a/src/modes/soccer_world.cpp b/src/modes/soccer_world.cpp index 300b1a667f3..7740e191815 100644 --- a/src/modes/soccer_world.cpp +++ b/src/modes/soccer_world.cpp @@ -43,6 +43,7 @@ #include "tracks/track.hpp" #include "tracks/track_object_manager.hpp" #include "tracks/track_sector.hpp" +#include "utils/communication.hpp" #include "utils/constants.hpp" #include "utils/game_info.hpp" #include "utils/translation.hpp" @@ -978,7 +979,7 @@ void SoccerWorld::updateBallPosition(int ticks) ResetBallPacket packet; packet.reset_ball_ticks = m_reset_ball_ticks; - STKHost::get()->sendPacketToAllPeers(packet); + Comm::sendPacketToPeers(packet); } else if (!NetworkConfig::get()->isNetworking()) { diff --git a/src/network/network_console.cpp b/src/network/network_console.cpp index 2ea5dfdfcea..53c20a100d7 100644 --- a/src/network/network_console.cpp +++ b/src/network/network_console.cpp @@ -210,7 +210,7 @@ void mainLoop(STKHost* host) message.pop_back(); auto sl = LobbyProtocol::get(); if (sl && !message.empty()) - Comm::sendStringToAllPeers(message); + Comm::sendStringToPeers(message); } else { diff --git a/src/network/protocol.hpp b/src/network/protocol.hpp index e684122b72f..241aec46326 100644 --- a/src/network/protocol.hpp +++ b/src/network/protocol.hpp @@ -24,6 +24,7 @@ #define PROTOCOL_HPP #include "utils/no_copy.hpp" +#include "utils/constants.hpp" #include #include @@ -121,72 +122,6 @@ class Protocol : public std::enable_shared_from_this, NetworkString* getNetworkString(size_t capacity = 16) const; bool checkDataSize(Event* event, unsigned int minimum_size); - // ---------------------------------------------------------------------------- - template - typename std::enable_if::value, void>::type - sendPacketToPeers(const T& packet, - PacketReliabilityMode reliable = PRM_RELIABLE) const - { - std::shared_ptr ptr1 = std::make_shared(packet); - std::shared_ptr ptr2 = std::dynamic_pointer_cast(ptr1); - return sendPacketPtrToPeers(ptr2, reliable); - } - - template - typename std::enable_if::value, void>::type - sendPacketToPeersInServer(const T& packet, - PacketReliabilityMode reliable = PRM_RELIABLE) const - { - std::shared_ptr ptr1 = std::make_shared(packet); - std::shared_ptr ptr2 = std::dynamic_pointer_cast(ptr1); - return sendPacketPtrToPeersInServer(ptr2, reliable); - } - - template - typename std::enable_if::value, void>::type - sendPacketToServer(const T& packet, - PacketReliabilityMode reliable = PRM_RELIABLE) - { - std::shared_ptr ptr1 = std::make_shared(packet); - std::shared_ptr ptr2 = std::dynamic_pointer_cast(ptr1); - return sendPacketPtrToServer(ptr2, reliable); - } - - - template - typename std::enable_if::value, void>::type - sendPacketExcept(std::shared_ptr peer, const T& packet, - PacketReliabilityMode reliable = PRM_RELIABLE) - { - std::shared_ptr ptr1 = std::make_shared(packet); - std::shared_ptr ptr2 = std::dynamic_pointer_cast(ptr1); - return sendPacketPtrExcept(peer, ptr2, reliable); - } - - template - typename std::enable_if::value, void>::type - sendPacketToAllPeersWith(std::function)> predicate, - const T& packet, PacketReliabilityMode reliable = PRM_RELIABLE) - { - std::shared_ptr ptr1 = std::make_shared(packet); - std::shared_ptr ptr2 = std::dynamic_pointer_cast(ptr1); - return sendPacketPtrToAllPeersWith(predicate, ptr2, reliable); - } - // ---------------------------------------------------------------------------- - void sendPacketPtrToPeers(std::shared_ptr packet, - PacketReliabilityMode reliable = PRM_RELIABLE) const; - - void sendPacketPtrToPeersInServer(std::shared_ptr packet, - PacketReliabilityMode reliable = PRM_RELIABLE) const; - - void sendPacketPtrToServer(std::shared_ptr packet, - PacketReliabilityMode reliable = PRM_RELIABLE); - - void sendPacketPtrExcept(std::shared_ptr peer, std::shared_ptr packet, - PacketReliabilityMode reliable = PRM_RELIABLE); - - void sendPacketPtrToAllPeersWith(std::function)> predicate, - std::shared_ptr packet, PacketReliabilityMode reliable = PRM_RELIABLE); // ---------------------------------------------------------------------------- virtual void requestStart(); virtual void requestTerminate(); diff --git a/src/network/protocols/client_lobby.cpp b/src/network/protocols/client_lobby.cpp index 3c1e86143b1..1fa1d3a47cd 100644 --- a/src/network/protocols/client_lobby.cpp +++ b/src/network/protocols/client_lobby.cpp @@ -178,7 +178,7 @@ void ClientLobby::setup() void ClientLobby::doneWithResults() { RaceFinishedAckPacket packet; - sendPacketToServer(packet); + Comm::sendPacketToServer(packet); } // doneWithResults //----------------------------------------------------------------------------- @@ -491,7 +491,7 @@ void ClientLobby::update(int ticks) } delete rest; - sendPacketToServer(packet); + Comm::sendPacketToServer(packet); if (encryption) { @@ -502,7 +502,7 @@ void ClientLobby::update(int ticks) else { packet.player_info_unencrypted = subpacket; - sendPacketToServer(packet); + Comm::sendPacketToServer(packet); } @@ -552,7 +552,7 @@ void ClientLobby::update(int ticks) // Send a message to the server to start m_auto_started = true; RequestBeginPacket packet; - sendPacketToServer(packet); + Comm::sendPacketToServer(packet); } if (m_background_download.joinable()) { @@ -1294,7 +1294,7 @@ void ClientLobby::finishedLoadingWorld() { FinishedLoadingLiveJoinPacket packet; packet.m_override_synchronous = m_server_send_live_load_world; - sendPacketToServer(packet); + Comm::sendPacketToServer(packet); } // finishedLoadingWorld //----------------------------------------------------------------------------- @@ -1402,7 +1402,7 @@ void ClientLobby::requestKartInfo(uint8_t kart_id) { KartInfoRequestPacket packet; packet.kart_id = kart_id; - sendPacketToServer(packet); + Comm::sendPacketToServer(packet); } // requestKartInfo //----------------------------------------------------------------------------- @@ -1542,7 +1542,7 @@ void ClientLobby::sendChat(irr::core::stringw text, KartTeam team) if (team != KART_TEAM_NONE) packet.kart_team = team; - sendPacketToServer(packet); + Comm::sendPacketToServer(packet); } } // sendChat @@ -1890,7 +1890,7 @@ void ClientLobby::handleClientCommand(const std::string& cmd) CommandPacket packet; packet.language = UserConfigParams::m_language; packet.command = cmd; - sendPacketToServer(packet); + Comm::sendPacketToServer(packet); } #endif } // handleClientCommand @@ -1933,7 +1933,7 @@ void ClientLobby::updateAssetsToServer() { NewAssetsPacket packet; packet.assets = getKartsTracksPacket(); - sendPacketToServer(packet); + Comm::sendPacketToServer(packet); } // updateAssetsToServer // ---------------------------------------------------------------------------- diff --git a/src/network/protocols/command_manager.cpp b/src/network/protocols/command_manager.cpp index 5955b78c880..1463d0c239e 100644 --- a/src/network/protocols/command_manager.cpp +++ b/src/network/protocols/command_manager.cpp @@ -896,7 +896,7 @@ void CommandManager::handleCommand(Event* event, std::shared_ptr peer) first_time = false; } } - Comm::sendStringToAllPeers(msg); + Comm::sendStringToPeers(msg); auto res = response.second; if (!res.empty()) { @@ -908,7 +908,7 @@ void CommandManager::handleCommand(Event* event, std::shared_ptr peer) std::string msg2 = StringUtils::insertValues( "Command \"/%s\" has been successfully voted", new_cmd.c_str()); - Comm::sendStringToAllPeers(msg2); + Comm::sendStringToPeers(msg2); Context new_context(getLobby(), event, std::shared_ptr(nullptr), new_argv, new_cmd, UP_EVERYONE, UP_EVERYONE, false); execute(executed_command, new_context); } @@ -969,7 +969,7 @@ void CommandManager::update() std::string msg = StringUtils::insertValues( "Command \"/%s\" has been successfully voted", new_cmd.c_str()); - Comm::sendStringToAllPeers(msg); + Comm::sendStringToPeers(msg); // Happily the name of the votable coincides with the command full name std::shared_ptr command = m_full_name_to_command[votable_pairs.first].lock(); if (!command) @@ -1201,7 +1201,7 @@ void CommandManager::process_replay(Context& context) current_state ^= 1; getSettings()->setConsentOnReplays(current_state); - Comm::sendStringToAllPeers(std::string("Recording ghost replays is now ") + Comm::sendStringToPeers(std::string("Recording ghost replays is now ") + (current_state ? "on" : "off")); } else @@ -2165,12 +2165,12 @@ void CommandManager::process_gnu(Context& context) if (kart == "off") { kart_elimination->disable(); - Comm::sendStringToAllPeers("Gnu Elimination is now off"); + Comm::sendStringToPeers("Gnu Elimination is now off"); } else { kart_elimination->enable(kart); - Comm::sendStringToAllPeers(kart_elimination->getStartingMessage()); + Comm::sendStringToPeers(kart_elimination->getStartingMessage()); } } // process_gnu // ======================================================================== @@ -2376,7 +2376,7 @@ void CommandManager::process_length_multi(Context& context) } double value = std::max(0.0, temp_double); getSettings()->setMultiplier(value); - Comm::sendStringToAllPeers(StringUtils::insertValues( + Comm::sendStringToPeers(StringUtils::insertValues( "Game length is now %f x default", value)); } // process_length_multi // ======================================================================== @@ -2392,20 +2392,20 @@ void CommandManager::process_length_fixed(Context& context) } int value = std::max(0, temp_int); getSettings()->setFixedLapCount(value); - Comm::sendStringToAllPeers(StringUtils::insertValues( + Comm::sendStringToPeers(StringUtils::insertValues( "Game length is now %d", value)); } // process_length_fixed // ======================================================================== void CommandManager::process_length_clear(Context& context) { getSettings()->resetLapRestrictions(); - Comm::sendStringToAllPeers("Game length will be chosen by players"); + Comm::sendStringToPeers("Game length will be chosen by players"); } // process_length_clear // ======================================================================== void CommandManager::process_direction(Context& context) { - Comm::sendStringToAllPeers(getSettings()->getDirectionAsString()); + Comm::sendStringToPeers(getSettings()->getDirectionAsString()); } // process_direction // ======================================================================== @@ -2423,7 +2423,7 @@ void CommandManager::process_direction_assign(Context& context) error(context); return; } - Comm::sendStringToAllPeers(getSettings()->getDirectionAsString(true)); + Comm::sendStringToPeers(getSettings()->getDirectionAsString(true)); } // process_direction_assign // ======================================================================== @@ -2537,7 +2537,7 @@ void CommandManager::process_queue_push(Context& context) } msg.pop_back(); - Comm::sendStringToAllPeers(msg); + Comm::sendStringToPeers(msg); getLobby()->updatePlayerList(); } // process_queue_push // ======================================================================== @@ -2587,7 +2587,7 @@ void CommandManager::process_queue_pop(Context& context) } } msg.pop_back(); - Comm::sendStringToAllPeers(msg); + Comm::sendStringToPeers(msg); getLobby()->updatePlayerList(); } // process_queue_pop // ======================================================================== @@ -2615,7 +2615,7 @@ void CommandManager::process_queue_clear(Context& context) } } msg.pop_back(); - Comm::sendStringToAllPeers(msg); + Comm::sendStringToPeers(msg); getLobby()->updatePlayerList(); } // process_queue_clear // ======================================================================== @@ -2655,7 +2655,7 @@ void CommandManager::process_queue_shuffle(Context& context) } } msg.pop_back(); - Comm::sendStringToAllPeers(msg); + Comm::sendStringToPeers(msg); getLobby()->updatePlayerList(); } // process_queue_shuffle // ======================================================================== @@ -2678,7 +2678,7 @@ void CommandManager::process_allowstart_assign(Context& context) return; } getSettings()->setAllowedToStart(argv[1] != "0"); - Comm::sendStringToAllPeers(getSettings()->getAllowedToStartAsString(true)); + Comm::sendStringToPeers(getSettings()->getAllowedToStartAsString(true)); } // process_allowstart_assign // ======================================================================== @@ -2698,7 +2698,7 @@ void CommandManager::process_shuffle_assign(Context& context) return; } getSettings()->setGPGridShuffled(argv[1] != "0"); - Comm::sendStringToAllPeers(getSettings()->getWhetherShuffledGPGridAsString(true)); + Comm::sendStringToPeers(getSettings()->getWhetherShuffledGPGridAsString(true)); } // process_shuffle_assign // ======================================================================== @@ -2860,7 +2860,7 @@ void CommandManager::process_resetgp(Context& context) getGameSetupFromCtx()->setGrandPrixTrack(number_of_games); } getGPManager()->resetGrandPrix(); - Comm::sendStringToAllPeers("GP is now reset"); + Comm::sendStringToPeers("GP is now reset"); } // process_resetgp // ======================================================================== @@ -2952,7 +2952,7 @@ void CommandManager::process_troll_assign(Context& context) hit_processor->setAntiTroll(true); msg = "Trolls will be kicked"; } - Comm::sendStringToAllPeers(msg); + Comm::sendStringToPeers(msg); } // process_troll_assign // ======================================================================== @@ -2987,7 +2987,7 @@ void CommandManager::process_hitmsg_assign(Context& context) hit_processor->setShowTeammateHits(true); msg = "Teammate hits will be sent to all players"; } - Comm::sendStringToAllPeers(msg); + Comm::sendStringToPeers(msg); } // process_hitmsg_assign // ======================================================================== @@ -3024,7 +3024,7 @@ void CommandManager::process_teamhit_assign(Context& context) hit_processor->setTeammateHitMode(true); msg = "Teammate hits are punished now"; } - Comm::sendStringToAllPeers(msg); + Comm::sendStringToPeers(msg); } // process_teamhit_assign // ======================================================================== @@ -3042,7 +3042,7 @@ void CommandManager::process_scoring_assign(Context& context) std::string cmd2; CommandManager::restoreCmdByArgv(cmd2, argv, ' ', '"', '"', '\\', 1); if (getGPManager()->trySettingGPScoring(cmd2)) - Comm::sendStringToAllPeers("Scoring set to \"" + cmd2 + "\""); + Comm::sendStringToPeers("Scoring set to \"" + cmd2 + "\""); else context.say("Scoring could not be parsed from \"" + cmd2 + "\""); } // process_scoring_assign @@ -3176,7 +3176,7 @@ void CommandManager::process_game(Context& context) msg += StringUtils::insertValues(" %d seconds", new_addition); getSettings()->setFixedLapCount(getSettings()->getFixedLapCount() + 1); } - Comm::sendStringToAllPeers(msg); + Comm::sendStringToPeers(msg); Log::info("CommandManager", "SoccerMatchLog: Game number changed from %d to %d", old_game_number, new_game_number); } // process_game @@ -3337,7 +3337,7 @@ void CommandManager::process_stop(Context& context) return; SoccerWorld *sw = dynamic_cast(w); sw->stop(); - Comm::sendStringToAllPeers("The game is stopped."); + Comm::sendStringToPeers("The game is stopped."); Log::info("CommandManager", "SoccerMatchLog: The game is stopped"); } // process_stop // ======================================================================== @@ -3354,7 +3354,7 @@ void CommandManager::process_go(Context& context) return; SoccerWorld *sw = dynamic_cast(w); sw->resume(); - Comm::sendStringToAllPeers("The game is resumed."); + Comm::sendStringToPeers("The game is resumed."); Log::info("CommandManager", "SoccerMatchLog: The game is resumed"); } // process_go // ======================================================================== @@ -3371,7 +3371,7 @@ void CommandManager::process_lobby(Context& context) return; SoccerWorld *sw = dynamic_cast(w); sw->allToLobby(); - Comm::sendStringToAllPeers("The game will be restarted."); + Comm::sendStringToPeers("The game will be restarted."); } // process_lobby // ======================================================================== @@ -3445,7 +3445,7 @@ void CommandManager::process_test(Context& context) acting_peer->getMainProfile(), acting_peer.get()); } username = "{" + argv[1].substr(4) + "} " + username; - Comm::sendStringToAllPeers(username + ", " + argv[2] + ", " + argv[3]); + Comm::sendStringToPeers(username + ", " + argv[2] + ", " + argv[3]); } // process_test // ======================================================================== @@ -3484,7 +3484,7 @@ void CommandManager::process_slots_assign(Context& context) } getSettings()->setCurrentMaxPlayersInGame((unsigned)number); getLobby()->updatePlayerList(); - Comm::sendStringToAllPeers(StringUtils::insertValues( + Comm::sendStringToPeers(StringUtils::insertValues( "Number of playable slots is now %s", number)); } // process_slots_assign @@ -3550,7 +3550,7 @@ void CommandManager::process_preserve_assign(Context& context) "'%s' is now preserved on server reset", argv[1].c_str()); getSettings()->insertIntoPreserved(argv[1]); } - Comm::sendStringToAllPeers(msg); + Comm::sendStringToPeers(msg); } // process_preserve_assign // ======================================================================== diff --git a/src/network/protocols/game_events_protocol.cpp b/src/network/protocols/game_events_protocol.cpp index 71e921bbfad..0d297c5ba3e 100644 --- a/src/network/protocols/game_events_protocol.cpp +++ b/src/network/protocols/game_events_protocol.cpp @@ -122,7 +122,7 @@ bool GameEventsProtocol::notifyEvent(Event* event) NetworkString *ns = getNetworkString(); ns->setSynchronous(true); ns->addUInt8(GE_STARTUP_BOOST).addUInt8(kart_id).addFloat(f); - Comm::sendMessageToPeers(ns, PRM_RELIABLE); + Comm::sendNetstringToPeers(ns, PRM_RELIABLE); delete ns; } else @@ -170,7 +170,7 @@ void GameEventsProtocol::kartFinishedRace(AbstractKart *kart, float time) ns->setSynchronous(true); ns->addUInt8(GE_KART_FINISHED_RACE).addUInt8(kart->getWorldKartId()) .addFloat(time); - Comm::sendMessageToPeers(ns, PRM_RELIABLE); + Comm::sendNetstringToPeers(ns, PRM_RELIABLE); delete ns; } // kartFinishedRace @@ -203,5 +203,5 @@ void GameEventsProtocol::sendStartupBoost(uint8_t kart_id) { StartupBoostPacket packet; packet.kart_id = kart_id; - sendPacketToServer(packet); + Comm::sendPacketToServer(packet); } // sendStartupBoost diff --git a/src/network/protocols/game_protocol.cpp b/src/network/protocols/game_protocol.cpp index 7384e2c5403..4c80ec62327 100644 --- a/src/network/protocols/game_protocol.cpp +++ b/src/network/protocols/game_protocol.cpp @@ -262,7 +262,7 @@ void GameProtocol::sendItemEventConfirmation(int ticks) ItemConfirmationPacket packet; packet.ticks = ticks; - sendPacketToServer(packet); + Comm::sendPacketToServer(packet); } // sendItemEventConfirmation // ---------------------------------------------------------------------------- @@ -333,7 +333,7 @@ void GameProtocol::finalizeState(std::vector& cur_rewinder) void GameProtocol::sendState() { assert(NetworkConfig::get()->isServer()); - Comm::sendMessageToPeers(m_data_to_send, PRM_UNRELIABLE); + Comm::sendNetstringToPeers(m_data_to_send, PRM_UNRELIABLE); } // sendState // ---------------------------------------------------------------------------- diff --git a/src/network/protocols/server_lobby.cpp b/src/network/protocols/server_lobby.cpp index d01f767bbe7..a49e72a998b 100644 --- a/src/network/protocols/server_lobby.cpp +++ b/src/network/protocols/server_lobby.cpp @@ -914,7 +914,7 @@ void ServerLobby::asynchronousUpdate() m_state = LOAD_WORLD; LoadWorldPacket packet = getLoadWorldMessage(players, false/*live_join*/); - sendPacketToPeers(packet); + Comm::sendPacketToPeers(packet); // updatePlayerList so the in lobby players (if any) can see always // spectators join the game if (has_always_on_spectators || !previous_spectate_mode.empty()) @@ -1448,7 +1448,7 @@ void ServerLobby::update(int ticks) // or spectate to go back to lobby BackLobbyPacket packet; packet.reason = BLR_NONE; - sendPacketToPeersInServer(packet); + Comm::sendPacketToPeersInServer(packet); RaceEventManager::get()->stop(); RaceEventManager::get()->getProtocol()->requestTerminate(); @@ -1480,7 +1480,7 @@ void ServerLobby::update(int ticks) { BackLobbyPacket packet; packet.reason = BLR_ONE_PLAYER_IN_RANKED_MATCH; - sendPacketToPeers(packet); + Comm::sendPacketToPeers(packet); resetVotingTime(); // m_game_setup->cancelOneRace(); @@ -1534,7 +1534,7 @@ void ServerLobby::update(int ticks) setTimeoutFromNow(15); m_state = RESULT_DISPLAY; - sendPacketToPeers(m_result_packet); + Comm::sendPacketToPeers(m_result_packet); Log::info("ServerLobby", "End of game message sent"); break; @@ -1547,7 +1547,7 @@ void ServerLobby::update(int ticks) // the race result screen BackLobbyPacket packet; packet.reason = BLR_NONE; - sendPacketToPeersInServer(packet); + Comm::sendPacketToPeersInServer(packet); m_rs_state.store(RS_ASYNC_RESET); } @@ -1897,7 +1897,7 @@ void ServerLobby::startSelection(const Event *event) BackLobbyPacket packet; packet.reason = BLR_SPECTATING_NEXT_GAME; - sendPacketToAllPeersWith( + Comm::sendPacketToPeersWith( [always_spectate_peers](std::shared_ptr peer) { return always_spectate_peers.find(peer) != @@ -2033,7 +2033,7 @@ void ServerLobby::checkRaceFinished() { std::string msg = getKartElimination()->onRaceFinished(); if (!msg.empty()) - Comm::sendStringToAllPeers(msg); + Comm::sendStringToPeers(msg); } if (getSettings()->isStoringResults()) @@ -2170,7 +2170,7 @@ void ServerLobby::clientDisconnected(Event* event) resetToDefaultSettings(); // Don't show waiting peer disconnect message to in game player - sendPacketToAllPeersWith([waiting_peer_disconnected] + Comm::sendPacketToPeersWith([waiting_peer_disconnected] (std::shared_ptr p) { if (!p->isValidated()) @@ -2695,7 +2695,7 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr peer, } // This ns packet wasn't replaced with function immediately, I could mess up then... - sendStringToPeer(peer, getKartElimination()->getWarningMessage(hasEliminatedPlayer)); + Comm::sendStringToPeer(peer, getKartElimination()->getWarningMessage(hasEliminatedPlayer)); } if (getSettings()->isRecordingReplays()) { @@ -2855,7 +2855,7 @@ void ServerLobby::updatePlayerList(bool update_when_reset_server) } // Don't send this message to in-game players - sendPacketToAllPeersWith([game_started] + Comm::sendPacketToPeersWith([game_started] (std::shared_ptr p) { if (!p->isValidated()) @@ -3004,7 +3004,7 @@ void ServerLobby::handlePlayerVote(Event* event) VotePacket vote_packet; vote_packet.host_id = event->getPeer()->getHostId(); vote_packet.vote = vote.encode(); - sendPacketToPeers(vote_packet); + Comm::sendPacketToPeers(vote_packet); } // handlePlayerVote @@ -3278,7 +3278,7 @@ void ServerLobby::configPeersStartTime() packet.start_time = start_time; packet.check_count = (uint8_t)Track::getCurrentTrack()->getCheckManager()->getCheckStructureCount(); packet.nim_complete_state = m_nim_complete_state; // was operator += - sendPacketToPeers(packet); + Comm::sendPacketToPeers(packet); m_client_starting_time = start_time; @@ -3653,7 +3653,7 @@ void ServerLobby::handleServerConfiguration(std::shared_ptr peer, RaceManager::get()->getMinorMode() != RaceManager::MINOR_MODE_TIME_TRIAL) { getKartElimination()->disable(); - Comm::sendStringToAllPeers("Gnu Elimination is disabled because of non-racing mode"); + Comm::sendStringToPeers("Gnu Elimination is disabled because of non-racing mode"); } } // handleServerConfiguration //----------------------------------------------------------------------------- @@ -3984,7 +3984,7 @@ void ServerLobby::clientInGameWantsToBackLobby(Event* event) BackLobbyPacket packet; packet.reason = BLR_SERVER_OWNER_QUIT_THE_GAME; - sendPacketToPeersInServer(packet); + Comm::sendPacketToPeersInServer(packet); m_rs_state.store(RS_ASYNC_RESET); return; @@ -4050,7 +4050,7 @@ void ServerLobby::clientSelectingAssetsWantsToBackLobby(Event* event) { BackLobbyPacket packet; packet.reason = BLR_SERVER_OWNER_QUIT_THE_GAME; - sendPacketToPeersInServer(packet); + Comm::sendPacketToPeersInServer(packet); resetVotingTime(); resetServer(); @@ -4175,27 +4175,6 @@ void ServerLobby::writeOwnReport(std::shared_ptr reporter, std::shared_ } // writeOwnReport //----------------------------------------------------------------------------- -void ServerLobby::sendStringToPeer(std::shared_ptr peer, const std::string& s) -{ - if (!peer) - { - sendStringToAllPeers(s); - return; - } - ChatPacket packet; - packet.message = StringUtils::utf8ToWide(s); - peer->sendPacket(packet); -} // sendStringToPeer -//----------------------------------------------------------------------------- - -void ServerLobby::sendStringToAllPeers(const std::string& s) -{ - ChatPacket packet; - packet.message = StringUtils::utf8ToWide(s); - sendPacketToPeers(packet); -} // sendStringToAllPeers -//----------------------------------------------------------------------------- - std::string ServerLobby::encodeProfileNameForPeer( std::shared_ptr npp, STKPeer* peer) @@ -4394,7 +4373,7 @@ bool ServerLobby::playerReportsTableExists() const void ServerLobby::sendServerInfoToEveryone() const { - sendPacketToPeers(m_game_setup->addServerInfo()); + Comm::sendPacketToPeers(m_game_setup->addServerInfo()); } // sendServerInfoToEveryone //----------------------------------------------------------------------------- diff --git a/src/network/protocols/server_lobby.hpp b/src/network/protocols/server_lobby.hpp index b5ae03994c8..12f01c7786b 100644 --- a/src/network/protocols/server_lobby.hpp +++ b/src/network/protocols/server_lobby.hpp @@ -335,7 +335,7 @@ class ServerLobby : public LobbyProtocol, public LobbyContextUser // TODO: When using different decorators for everyone, you would need // a structure to store "player profile" placeholders in a string, so that - // you can apply decorators at the very last moment inside sendStringToAllPeers + // you can apply decorators at the very last moment inside sendStringToPeers // and similar functions. std::string encodeProfileNameForPeer( std::shared_ptr npp, diff --git a/src/network/stk_host.cpp b/src/network/stk_host.cpp index 2f4355a07be..cb0c670a6bb 100644 --- a/src/network/stk_host.cpp +++ b/src/network/stk_host.cpp @@ -1337,7 +1337,7 @@ std::shared_ptr STKHost::getServerPeerForClient() const * \param data Data to sent. * \param reliable If the data should be sent reliable or now. */ -void STKHost::sendNetstringToAllPeersInServer(NetworkString *data, PacketReliabilityMode reliable) +void STKHost::sendNetstringToPeersInServer(NetworkString *data, PacketReliabilityMode reliable) { std::lock_guard lock(m_peers_mutex); for (auto p : m_peers) @@ -1345,14 +1345,14 @@ void STKHost::sendNetstringToAllPeersInServer(NetworkString *data, PacketReliabi if (p.second->isValidated()) p.second->sendNetstring(data, reliable); } -} // sendNetstringToAllPeersInServer +} // sendNetstringToPeersInServer //----------------------------------------------------------------------------- /** Sends data to all validated peers currently in game * \param data Data to sent. * \param reliable If the data should be sent reliable or now. */ -void STKHost::sendNetstringToAllPeers(NetworkString *data, PacketReliabilityMode reliable) +void STKHost::sendNetstringToPeers(NetworkString *data, PacketReliabilityMode reliable) { std::lock_guard lock(m_peers_mutex); for (auto p : m_peers) @@ -1360,7 +1360,7 @@ void STKHost::sendNetstringToAllPeers(NetworkString *data, PacketReliabilityMode if (p.second->isValidated() && !p.second->isWaitingForGame()) p.second->sendNetstring(data, reliable); } -} // sendNetstringToAllPeers +} // sendNetstringToPeers //----------------------------------------------------------------------------- /** Sends data to all validated peers except the specified currently in game @@ -1389,7 +1389,7 @@ void STKHost::sendNetstringExcept(std::shared_ptr peer, NetworkString * * \param data Data to sent. * \param reliable If the data should be sent reliable or now. */ -void STKHost::sendNetstringToAllPeersWith(std::function)> predicate, +void STKHost::sendNetstringToPeersWith(std::function)> predicate, NetworkString* data, PacketReliabilityMode reliable) { std::lock_guard lock(m_peers_mutex); @@ -1401,7 +1401,7 @@ void STKHost::sendNetstringToAllPeersWith(std::functionsendNetstring(data, reliable); } -} // sendPacketToAllPeersWith +} // sendPacketToPeersWith //----------------------------------------------------------------------------- /** Sends a message from a client to the server. */ @@ -1672,7 +1672,7 @@ uint16_t STKHost::getPrivatePort() const } // getPrivatePort // ---------------------------------------------------------------------------- -void STKHost::sendPacketPtrToAllPeersInServer(std::shared_ptr packet, PacketReliabilityMode reliable) +void STKHost::sendPacketPtrToPeersInServer(std::shared_ptr packet, PacketReliabilityMode reliable) { std::lock_guard lock(m_peers_mutex); for (auto p : m_peers) @@ -1680,10 +1680,10 @@ void STKHost::sendPacketPtrToAllPeersInServer(std::shared_ptr packet, Pa if (p.second->isValidated()) p.second->sendPacketPtr(packet, reliable); } -} // sendPacketToAllPeersInServer +} // sendPacketToPeersInServer //----------------------------------------------------------------------------- -void STKHost::sendPacketPtrToAllPeers(std::shared_ptr packet, PacketReliabilityMode reliable) +void STKHost::sendPacketPtrToPeers(std::shared_ptr packet, PacketReliabilityMode reliable) { std::lock_guard lock(m_peers_mutex); for (auto p : m_peers) @@ -1691,7 +1691,7 @@ void STKHost::sendPacketPtrToAllPeers(std::shared_ptr packet, PacketReli if (p.second->isValidated() && !p.second->isWaitingForGame()) p.second->sendPacketPtr(packet, reliable); } -} // sendPacketToAllPeers +} // sendPacketToPeers //----------------------------------------------------------------------------- void STKHost::sendPacketPtrExcept(std::shared_ptr peer, std::shared_ptr packet, @@ -1710,7 +1710,7 @@ void STKHost::sendPacketPtrExcept(std::shared_ptr peer, std::shared_ptr } // sendPacketExcept //----------------------------------------------------------------------------- -void STKHost::sendPacketPtrToAllPeersWith(std::function)> predicate, +void STKHost::sendPacketPtrToPeersWith(std::function)> predicate, std::shared_ptr packet, PacketReliabilityMode reliable) { std::lock_guard lock(m_peers_mutex); @@ -1722,7 +1722,7 @@ void STKHost::sendPacketPtrToAllPeersWith(std::functionsendPacketPtr(packet, reliable); } -} // sendPacketToAllPeersWith +} // sendPacketToPeersWith //----------------------------------------------------------------------------- void STKHost::sendPacketPtrToServer(std::shared_ptr packet, PacketReliabilityMode reliable) diff --git a/src/network/stk_host.hpp b/src/network/stk_host.hpp index 714a639b5e6..760076ed753 100644 --- a/src/network/stk_host.hpp +++ b/src/network/stk_host.hpp @@ -245,12 +245,12 @@ class STKHost //------------------------------------------------------------------------- void shutdown(); //------------------------------------------------------------------------- - void sendNetstringToAllPeersInServer(NetworkString *data, + void sendNetstringToPeersInServer(NetworkString *data, PacketReliabilityMode reliable = PRM_RELIABLE); // ------------------------------------------------------------------------ - void sendNetstringToAllPeers(NetworkString *data, PacketReliabilityMode reliable = PRM_RELIABLE); + void sendNetstringToPeers(NetworkString *data, PacketReliabilityMode reliable = PRM_RELIABLE); // ------------------------------------------------------------------------ - void sendNetstringToAllPeersWith(std::function)> predicate, + void sendNetstringTolPeersWith(std::function)> predicate, NetworkString* data, PacketReliabilityMode reliable = PRM_RELIABLE); // ------------------------------------------------------------------------ /** Returns true if this client instance is allowed to control the server. @@ -401,67 +401,17 @@ class STKHost ChildLoop* getChildLoop() const { return m_client_loop; } // ------------------------------------------------------------------------ - template - typename std::enable_if::value, void>::type - sendPacketPtrToAllPeersInServer(const T& packet, - PacketReliabilityMode reliable = PRM_RELIABLE) - { - std::shared_ptr ptr1 = std::make_shared(packet); - std::shared_ptr ptr2 = std::dynamic_pointer_cast(ptr1); - return sendPacketPtrToAllPeersInServer(ptr2, reliable); - } - - template - typename std::enable_if::value, void>::type - sendPacketToAllPeers(const T& packet, - PacketReliabilityMode reliable = PRM_RELIABLE) - { - std::shared_ptr ptr1 = std::make_shared(packet); - std::shared_ptr ptr2 = std::dynamic_pointer_cast(ptr1); - return sendPacketPtrToAllPeers(ptr2, reliable); - } - - template - typename std::enable_if::value, void>::type - sendPacketExcept(std::shared_ptr peer, const T& packet, - PacketReliabilityMode reliable = PRM_RELIABLE) - { - std::shared_ptr ptr1 = std::make_shared(packet); - std::shared_ptr ptr2 = std::dynamic_pointer_cast(ptr1); - return sendPacketPtrExcept(peer, ptr2, reliable); - } - - template - typename std::enable_if::value, void>::type - sendPacketToAllPeersWith(std::function)> predicate, - const T& packet, PacketReliabilityMode reliable = PRM_RELIABLE) - { - std::shared_ptr ptr1 = std::make_shared(packet); - std::shared_ptr ptr2 = std::dynamic_pointer_cast(ptr1); - return sendPacketPtrToAllPeersWith(predicate, ptr2, reliable); - } - - template - typename std::enable_if::value, void>::type - sendPacketToServer(const T& packet, PacketReliabilityMode reliable = PRM_RELIABLE) - { - std::shared_ptr ptr1 = std::make_shared(packet); - std::shared_ptr ptr2 = std::dynamic_pointer_cast(ptr1); - return sendPacketPtrToServer(ptr2, reliable); - } - // ------------------------------------------------------------------------ - - void sendPacketPtrToAllPeersInServer(std::shared_ptr packet, + void sendPacketPtrToPeersInServer(std::shared_ptr packet, PacketReliabilityMode reliable = PRM_RELIABLE); - void sendPacketPtrToAllPeers(std::shared_ptr packet, + void sendPacketPtrToPeers(std::shared_ptr packet, PacketReliabilityMode reliable = PRM_RELIABLE); void sendPacketPtrExcept(std::shared_ptr peer, std::shared_ptr packet, PacketReliabilityMode reliable = PRM_RELIABLE); - void sendPacketPtrToAllPeersWith(std::function)> predicate, + void sendPacketPtrToPeersWith(std::function)> predicate, std::shared_ptr packet, PacketReliabilityMode reliable = PRM_RELIABLE); diff --git a/src/states_screens/dialogs/network_player_dialog.cpp b/src/states_screens/dialogs/network_player_dialog.cpp index 47140647df8..35897e02762 100644 --- a/src/states_screens/dialogs/network_player_dialog.cpp +++ b/src/states_screens/dialogs/network_player_dialog.cpp @@ -207,7 +207,7 @@ void NetworkPlayerDialog::onUpdate(float dt) ReportRequestPacket packet; packet.host_id = host_id; packet.info = info; - sendPacketToServer(packet); + Comm::sendPacketToServer(packet); return true; }); return; @@ -250,7 +250,7 @@ GUIEngine::EventPropagation { KickHostPacket packet; packet.host_id = m_host_id; - sendPacketToServer(packet); + Comm::sendPacketToServer(packet); m_self_destroy = true; return GUIEngine::EVENT_BLOCK; } @@ -259,7 +259,7 @@ GUIEngine::EventPropagation { ChangeTeamPacket packet; packet.local_id = m_local_id; - sendPacketToServer(packet); + Comm::sendPacketToServer(packet); m_self_destroy = true; return GUIEngine::EVENT_BLOCK; } @@ -274,7 +274,7 @@ GUIEngine::EventPropagation ChangeHandicapPacket packet; packet.local_id = m_local_id; packet.handicap = new_handicap; - sendPacketToServer(packet); + Comm::sendPacketToServer(packet); m_self_destroy = true; return GUIEngine::EVENT_BLOCK; } diff --git a/src/states_screens/dialogs/race_paused_dialog.cpp b/src/states_screens/dialogs/race_paused_dialog.cpp index 5bca8317a54..c155b4b765d 100644 --- a/src/states_screens/dialogs/race_paused_dialog.cpp +++ b/src/states_screens/dialogs/race_paused_dialog.cpp @@ -387,7 +387,7 @@ GUIEngine::EventPropagation { // back lobby ClientBackLobbyPacket packet; - sendPacketToServer(packet); + Comm::sendPacketToServer(packet); } else { diff --git a/src/states_screens/dialogs/server_configuration_dialog.cpp b/src/states_screens/dialogs/server_configuration_dialog.cpp index 0aec04f3715..fdf344ab623 100644 --- a/src/states_screens/dialogs/server_configuration_dialog.cpp +++ b/src/states_screens/dialogs/server_configuration_dialog.cpp @@ -131,7 +131,7 @@ GUIEngine::EventPropagation break; } } - sendPacketToServer(packet); + Comm::sendPacketToServer(packet); return GUIEngine::EVENT_BLOCK; } } diff --git a/src/states_screens/online/network_kart_selection.cpp b/src/states_screens/online/network_kart_selection.cpp index c1a013eddd2..be34fe3c600 100644 --- a/src/states_screens/online/network_kart_selection.cpp +++ b/src/states_screens/online/network_kart_selection.cpp @@ -157,13 +157,13 @@ void NetworkKartSelectionScreen::allPlayersDone() LiveJoinRequestPacket packet; packet.is_spectator = false; packet.player_karts = karts_packet; - sendPacketToServer(packet); + Comm::sendPacketToServer(packet); } else { KartSelectionRequestPacket packet; packet.karts = karts_packet; - sendPacketToServer(packet); + Comm::sendPacketToServer(packet); } @@ -195,7 +195,7 @@ bool NetworkKartSelectionScreen::onEscapePressed() // server doesn't react in time we exit the server m_exit_timeout = StkTime::getMonoTimeMs() + 5000; ClientBackLobbyPacket packet; - sendPacketToServer(packet); + Comm::sendPacketToServer(packet); } return false; } diff --git a/src/states_screens/online/networking_lobby.cpp b/src/states_screens/online/networking_lobby.cpp index b4842d5f4fc..5a642ee6275 100644 --- a/src/states_screens/online/networking_lobby.cpp +++ b/src/states_screens/online/networking_lobby.cpp @@ -863,7 +863,7 @@ void NetworkingLobby::eventCallback(Widget* widget, const std::string& name, { // Send a message to the server to start RequestBeginPacket packet; - sendPacketToServer(packet); + Comm::sendPacketToServer(packet); } } else if (name == m_config_button->m_properties[PROP_ID]) @@ -880,7 +880,7 @@ void NetworkingLobby::eventCallback(Widget* widget, const std::string& name, { LiveJoinRequestPacket packet; packet.is_spectator = true; - sendPacketToServer(packet); + Comm::sendPacketToServer(packet); return; } if (cl) diff --git a/src/states_screens/online/tracks_screen.cpp b/src/states_screens/online/tracks_screen.cpp index 03252969a2c..10fc3b52aa9 100644 --- a/src/states_screens/online/tracks_screen.cpp +++ b/src/states_screens/online/tracks_screen.cpp @@ -770,7 +770,7 @@ void TracksScreen::voteForPlayer() // Not encoding packet to netstring before if just in case, too. VoteRequestPacket vr_packet; vr_packet.vote = packet; - sendPacketToServer(vr_packet); + Comm::sendPacketToServer(vr_packet); } } // voteForPlayer diff --git a/src/utils/chat_manager.cpp b/src/utils/chat_manager.cpp index 94bde934569..af59b3497ae 100644 --- a/src/utils/chat_manager.cpp +++ b/src/utils/chat_manager.cpp @@ -27,7 +27,6 @@ #include "network/stk_peer.hpp" #include "utils/communication.hpp" #include "utils/string_utils.hpp" -#include "utils/string_utils.hpp" #include "utils/tournament.hpp" namespace @@ -232,7 +231,7 @@ void ChatManager::handleNormalChatMessage(std::shared_ptr peer, ChatPacket packet; packet.message = StringUtils::utf8ToWide(message); - STKHost::get()->sendPacketToAllPeersWith( + Comm::sendPacketToPeersWith( std::bind(&ChatManager::shouldMessageBeSent, this, peer, diff --git a/src/utils/communication.cpp b/src/utils/communication.cpp index d807705f221..5f9de5595b5 100644 --- a/src/utils/communication.cpp +++ b/src/utils/communication.cpp @@ -36,11 +36,12 @@ namespace Comm * \param message The actual message content. * \param reliable Whether it should be in a reliable way or not. */ -void sendMessageToPeers(NetworkString *message, +[[deprecated("You should send packets to Comm::, it will pass NetString to STKHost,")]] +void sendNetstringToPeers(NetworkString *message, PacketReliabilityMode reliable) { - STKHost::get()->sendPacketToAllPeers(message, reliable); -} // sendMessageToPeers + STKHost::get()->sendNetstringToPeers(message, reliable); +} // sendNetstringToPeers // ---------------------------------------------------------------------------- /** Sends a message to all validated peers in server, encrypt the message if @@ -49,17 +50,19 @@ void sendMessageToPeers(NetworkString *message, * \param message The actual message content. * \param reliable Whether it should be in a reliable way or not. */ -void sendMessageToPeersInServer(NetworkString* message, +[[deprecated("You should send packets to Comm::, it will pass NetString to STKHost,")]] +void sendNetstringToPeersInServer(NetworkString* message, PacketReliabilityMode reliable) { - STKHost::get()->sendPacketToAllPeersInServer(message, reliable); -} // sendMessageToPeersInServer + STKHost::get()->sendNetstringToPeersInServer(message, reliable); +} // sendNetstringToPeersInServer // ---------------------------------------------------------------------------- /** Sends a message from a client to the server. * \param message The actual message content. * \param reliable Whether it should be in a reliable way or not. */ +[[deprecated("You should send packets to Comm::, it will pass NetString to STKHost,")]] void sendToServer(NetworkString *message, PacketReliabilityMode reliable) { @@ -71,26 +74,21 @@ void sendStringToPeer(std::shared_ptr peer, const std::string& s) { if (!peer) { - sendStringToAllPeers(s); + sendStringToPeers(s); return; - } - NetworkString* ns = new NetworkString(ProtocolType::PROTOCOL_LOBBY_ROOM); + } + ChatPacket packet; packet.message = StringUtils::utf8ToWide(s); - packet.toNetworkString(ns); - peer->sendPacket(ns, PRM_RELIABLE); - delete ns; + peer->sendPacket(packet); } // sendStringToPeer //----------------------------------------------------------------------------- -void sendStringToAllPeers(const std::string& s) +void sendStringToPeers(const std::string& s) { - NetworkString* ns = new NetworkString(ProtocolType::PROTOCOL_LOBBY_ROOM); ChatPacket packet; packet.message = StringUtils::utf8ToWide(s); - packet.toNetworkString(ns); - sendMessageToPeers(ns, PRM_RELIABLE); - delete ns; -} // sendStringToAllPeers + sendPacketToPeers(packet); +} // sendStringToPeers //----------------------------------------------------------------------------- } // namespace Comm diff --git a/src/utils/communication.hpp b/src/utils/communication.hpp index 447a23bae31..9e40092b1b2 100644 --- a/src/utils/communication.hpp +++ b/src/utils/communication.hpp @@ -27,9 +27,9 @@ namespace Comm { - void sendMessageToPeers(NetworkString *message, + void sendNetstringToPeers(NetworkString *message, PacketReliabilityMode reliable = PRM_RELIABLE); - void sendMessageToPeersInServer(NetworkString *message, + void sendNetstringToPeersInServer(NetworkString *message, PacketReliabilityMode reliable = PRM_RELIABLE); void sendToServer(NetworkString *message, PacketReliabilityMode reliable = PRM_RELIABLE); @@ -40,7 +40,59 @@ namespace Comm // Uses PROTOCOL_LOBBY_ROOM as chat is sent from there usually. // Using in non-lobby classes would be strange but seemingly ok. - void sendStringToAllPeers(const std::string& s); + void sendStringToPeers(const std::string& s); + + // ---------------------------------------------------------------------------- + template + typename std::enable_if::value, void>::type + sendPacketToPeers(const T& packet, + PacketReliabilityMode reliable = PRM_RELIABLE) + { + std::shared_ptr ptr1 = std::make_shared(packet); + std::shared_ptr ptr2 = std::dynamic_pointer_cast(ptr1); + return STKHost::get()->sendPacketPtrToPeers(ptr2, reliable); + } + + template + typename std::enable_if::value, void>::type + sendPacketToPeersInServer(const T& packet, + PacketReliabilityMode reliable = PRM_RELIABLE) + { + std::shared_ptr ptr1 = std::make_shared(packet); + std::shared_ptr ptr2 = std::dynamic_pointer_cast(ptr1); + return STKHost::get()->sendPacketPtrToPeersInServer(ptr2, reliable); + } + + template + typename std::enable_if::value, void>::type + sendPacketToServer(const T& packet, + PacketReliabilityMode reliable = PRM_RELIABLE) + { + std::shared_ptr ptr1 = std::make_shared(packet); + std::shared_ptr ptr2 = std::dynamic_pointer_cast(ptr1); + return STKHost::get()->sendPacketPtrToServer(ptr2, reliable); + } + + template + typename std::enable_if::value, void>::type + sendPacketExcept(std::shared_ptr peer, const T& packet, + PacketReliabilityMode reliable = PRM_RELIABLE) + { + std::shared_ptr ptr1 = std::make_shared(packet); + std::shared_ptr ptr2 = std::dynamic_pointer_cast(ptr1); + return STKHost::get()->sendPacketPtrExcept(peer, ptr2, reliable); + } + + template + typename std::enable_if::value, void>::type + sendPacketToPeersWith(std::function)> predicate, + const T& packet, PacketReliabilityMode reliable = PRM_RELIABLE) + { + std::shared_ptr ptr1 = std::make_shared(packet); + std::shared_ptr ptr2 = std::dynamic_pointer_cast(ptr1); + return STKHost::get()->sendPacketPtrToPeersWith(predicate, ptr2, reliable); + } + // ------------------------------------------------------------------------ } diff --git a/src/utils/game_info.cpp b/src/utils/game_info.cpp index 7c441612406..acf004af07d 100644 --- a/src/utils/game_info.cpp +++ b/src/utils/game_info.cpp @@ -453,7 +453,7 @@ void GameInfo::fillAndStoreResults() StringUtils::timeToString(best_result), best_user); } if (!message.empty()) - Comm::sendStringToAllPeers(message); + Comm::sendStringToPeers(message); } } // fillAndStoreResults diff --git a/src/utils/hit_processor.cpp b/src/utils/hit_processor.cpp index 170356fa2d3..13300cb6f72 100644 --- a/src/utils/hit_processor.cpp +++ b/src/utils/hit_processor.cpp @@ -100,7 +100,7 @@ void HitProcessor::sendTeammateHitMsg(std::string& s) if (ticks - m_last_hit_msg > STKConfig::get()->time2Ticks(g_hit_message_delay)) { m_last_hit_msg = ticks; - Comm::sendStringToAllPeers(s); + Comm::sendStringToPeers(s); } } // sendTeammateHitMsg //----------------------------------------------------------------------------- From d5ab3cf6962087b50fb99e2daa66d5399511a4a4 Mon Sep 17 00:00:00 2001 From: kimden <23140380+kimden@users.noreply.github.com> Date: Thu, 10 Jul 2025 03:58:55 +0400 Subject: [PATCH 33/34] Some packets in GameEventsProtocol and GameProtocol, unfinished [skip ci] --- src/network/packet_types_base.hpp | 49 +++++++ .../protocols/game_events_protocol.cpp | 40 +++--- .../protocols/game_events_protocol.hpp | 4 +- src/network/protocols/game_protocol.cpp | 126 +++++++++--------- src/network/protocols/game_protocol.hpp | 2 +- 5 files changed, 135 insertions(+), 86 deletions(-) diff --git a/src/network/packet_types_base.hpp b/src/network/packet_types_base.hpp index d9cb60ef0e1..d03bf9bd852 100644 --- a/src/network/packet_types_base.hpp +++ b/src/network/packet_types_base.hpp @@ -816,10 +816,59 @@ DEFINE_CLASS(PlungerPacket) DEFINE_FIELD_OPTIONAL(uint8_t, rubber_band_state, IHAVENOIDEA) END_DEFINE_CLASS(PlungerPacket) +DEFINE_CLASS(GameEventKartFinishedPacket) + PROTOCOL_TYPE(PROTOCOL_GAME_EVENTS, true) + DEFINE_TYPE(uint8_t, type, GE_KART_FINISHED_RACE) + DEFINE_FIELD(uint8_t, kart_id) + DEFINE_FIELD(float, time) + RELIABLE(true) +END_DEFINE_CLASS(GameEventKartFinishedPacket) + +DEFINE_CLASS(GameEventStartupBoostPacket) + PROTOCOL_TYPE(PROTOCOL_GAME_EVENTS, true) + DEFINE_TYPE(uint8_t, type, GE_STARTUP_BOOST) + DEFINE_FIELD(uint8_t, kart_id) + DEFINE_FIELD(float, value) + RELIABLE(true) +END_DEFINE_CLASS(GameEventStartupBoostPacket) + +DEFINE_CLASS(ControllerActionPacket) + DEFINE_FIELD(uint8_t, kart_id) + DEFINE_FIELD(uint8_t, compressed_action_0) + DEFINE_FIELD(uint16_t, compressed_action_1) + DEFINE_FIELD(uint16_t, compressed_action_2) + DEFINE_FIELD(uint16_t, compressed_action_3) +END_DEFINE_CLASS(ControllerActionPacket) +DEFINE_CLASS(ControllerActionBigPacket) + PROTOCOL_TYPE(PROTOCOL_GAME_EVENTS, true) + DEFINE_TYPE(uint8_t, type, GP_CONTROLLER_ACTION) + DEFINE_FIELD(uint8_t, count) + DEFINE_VECTOR(ControllerSingleActionPacket, count, actions) + /* We don't specify RELIABLE here as it can be sent both ways. Or maybe I forgot how overriding works here? */ + /*RELIABLE(true)*/ +END_DEFINE_CLASS(ControllerActionBigPacket) + +DEFINE_CLASS(ControllerSingleActionPacket) + DEFINE_FIELD(uint32_t, ticks) + DEFINE_FIELD(ControllerActionPacket, subpacket) +END_DEFINE_CLASS(ControllerSingleActionPacket) +DEFINE_CLASS(GameEventStatePacket) + DEFINE_TYPE(uint8_t, type, GP_STATE) + DEFINE_FIELD(uint32_t, ticks_since_start) +END_DEFINE_CLASS(GameEventStatePacket) +DEFINE_CLASS(BigGameStatesPacket) + PROTOCOL_TYPE(PROTOCOL_GAME_EVENTS, true) + DEFINE_TYPE(uint8_t, type, GP_CONTROLLER_ACTION) + DEFINE_FIELD(uint32_t, ticks) + DEFINE_FIELD(uint8_t, rewinders_size) + DEFINE_VECTOR(std::string, rewinders_size, rewinder_names) /* Previous encoding was manual, adjust if needed. */ + DEFINE_FIELD(ControllerActionBigPacket, actions) + /* Don't define RELIABLE, can be sent either way */ +END_DEFINE_CLASS(BigGameStatesPacket) // end \ No newline at end of file diff --git a/src/network/protocols/game_events_protocol.cpp b/src/network/protocols/game_events_protocol.cpp index 0d297c5ba3e..64a6183e736 100644 --- a/src/network/protocols/game_events_protocol.cpp +++ b/src/network/protocols/game_events_protocol.cpp @@ -64,10 +64,16 @@ bool GameEventsProtocol::notifyEvent(Event* event) FreeForAll* ffa = dynamic_cast(World::getWorld()); SoccerWorld* sw = dynamic_cast(World::getWorld()); LinearWorld* lw = dynamic_cast(World::getWorld()); + + // Scopes are added to allow initializing variables inside switch (type) { case GE_KART_FINISHED_RACE: - kartFinishedRace(data); break; + { + auto packet = event->getPacket(); + kartFinishedRace(packet); + break; + } case GE_RESET_BALL: { if (!sw) @@ -119,11 +125,11 @@ bool GameEventsProtocol::notifyEvent(Event* event) float f = LobbyProtocol::get() ->getStartupBoostOrPenaltyForKart( event->getPeer()->getAveragePing(), kart_id); - NetworkString *ns = getNetworkString(); - ns->setSynchronous(true); - ns->addUInt8(GE_STARTUP_BOOST).addUInt8(kart_id).addFloat(f); - Comm::sendNetstringToPeers(ns, PRM_RELIABLE); - delete ns; + + GameEventStartupBoostPacket packet; + packet.kart_id = kart_id; + packet.value = f; + Comm::sendPacketToPeers(packet); } else { @@ -166,12 +172,10 @@ bool GameEventsProtocol::notifyEvent(Event* event) */ void GameEventsProtocol::kartFinishedRace(AbstractKart *kart, float time) { - NetworkString *ns = getNetworkString(20); - ns->setSynchronous(true); - ns->addUInt8(GE_KART_FINISHED_RACE).addUInt8(kart->getWorldKartId()) - .addFloat(time); - Comm::sendNetstringToPeers(ns, PRM_RELIABLE); - delete ns; + GameEventKartFinishedPacket packet; + packet.kart_id = kart->getWorldKartId(); + packet.time = time; + Comm::sendPacketToPeers(packet); } // kartFinishedRace // ---------------------------------------------------------------------------- @@ -179,16 +183,10 @@ void GameEventsProtocol::kartFinishedRace(AbstractKart *kart, float time) * event from the server. It updates the game with this information. * \param ns The message from the server. */ -void GameEventsProtocol::kartFinishedRace(const NetworkString &ns) +void GameEventsProtocol::kartFinishedRace(const GameEventKartFinishedPacket& packet) { - if (ns.size() < 5) - { - Log::warn("GameEventsProtocol", "kartFinisheRace: Too short message."); - return; - } - - uint8_t kart_id = ns.getUInt8(); - float time = ns.getFloat(); + uint8_t kart_id = packet.kart_id; + float time = packet.time; if (RaceManager::get()->modeHasLaps()) { World::getWorld()->getKart(kart_id) diff --git a/src/network/protocols/game_events_protocol.hpp b/src/network/protocols/game_events_protocol.hpp index c987147aa26..60009559df7 100644 --- a/src/network/protocols/game_events_protocol.hpp +++ b/src/network/protocols/game_events_protocol.hpp @@ -11,15 +11,13 @@ class GameEventsProtocol : public Protocol private: int m_last_finished_position; - void eliminatePlayer(const NetworkString &ns); - public: GameEventsProtocol(); virtual ~GameEventsProtocol(); virtual bool notifyEvent(Event* event) OVERRIDE; void kartFinishedRace(AbstractKart *kart, float time); - void kartFinishedRace(const NetworkString &ns); + void kartFinishedRace(const GameEventKartFinishedPacket& packet); void sendStartupBoost(uint8_t kart_id); virtual void setup() OVERRIDE {} virtual void update(int ticks) OVERRIDE; diff --git a/src/network/protocols/game_protocol.cpp b/src/network/protocols/game_protocol.cpp index 4c80ec62327..0269bcc0d3a 100644 --- a/src/network/protocols/game_protocol.cpp +++ b/src/network/protocols/game_protocol.cpp @@ -63,13 +63,12 @@ GameProtocol::GameProtocol() { m_network_item_manager = static_cast (Track::getCurrentTrack()->getItemManager()); - m_data_to_send = getNetworkString(); + m_packet_to_send = {}; } // GameProtocol //----------------------------------------------------------------------------- GameProtocol::~GameProtocol() { - delete m_data_to_send; } // ~GameProtocol //----------------------------------------------------------------------------- @@ -82,15 +81,15 @@ void GameProtocol::sendActions() // Clear left-over data from previous frame. This way the network // string will increase till it reaches maximum size necessary - m_data_to_send->clear(); + m_packet_to_send = {}; if (m_all_actions.size() > 255) { Log::warn("GameProtocol", "Too many actions unsent %d.", (int)m_all_actions.size()); m_all_actions.resize(255); } - m_data_to_send->addUInt8(GP_CONTROLLER_ACTION) - .addUInt8(uint8_t(m_all_actions.size())); + ControllerActionBigPacket big_packet; + big_packet.count = m_all_actions.size(); // Add all actions for (auto& a : m_all_actions) @@ -102,15 +101,22 @@ void GameProtocol::sendActions() a.m_ticks, a.m_kart_id, a.m_action, a.m_value, a.m_value_l, a.m_value_r); } - m_data_to_send->addUInt32(a.m_ticks); - m_data_to_send->addUInt8(a.m_kart_id); const auto& c = compressAction(a); - m_data_to_send->addUInt8(std::get<0>(c)).addUInt16(std::get<1>(c)) - .addUInt16(std::get<2>(c)).addUInt16(std::get<3>(c)); + + ControllerSingleActionPacket packet; + packet.ticks = a.m_ticks; + packet.subpacket.kart_id = a.m_kart_id; + packet.subpacket.compressed_action_0 = std::get<0>(c); + packet.subpacket.compressed_action_1 = std::get<1>(c); + packet.subpacket.compressed_action_2 = std::get<2>(c); + packet.subpacket.compressed_action_3 = std::get<3>(c); + big_packet.actions.push_back(packet); } // for a in m_all_actions - // FIXME: for now send reliable - Comm::sendToServer(m_data_to_send, PRM_RELIABLE); + Comm::sendPacketToServer(big_packet, PRM_RELIABLE); + + m_packet_to_send = big_packet; + m_all_actions.clear(); } // sendActions @@ -169,11 +175,15 @@ void GameProtocol::controllerAction(int kart_id, PlayerAction action, const auto& c = compressAction(a); // Store the event in the rewind manager, which is responsible // for freeing the allocated memory - BareNetworkString *s = new BareNetworkString(4); - s->addUInt8(kart_id).addUInt8(std::get<0>(c)).addUInt16(std::get<1>(c)) - .addUInt16(std::get<2>(c)).addUInt16(std::get<3>(c)); - RewindManager::get()->addEvent(this, s, /*confirmed*/true, + ControllerActionPacket packet; + packet.kart_id = kart_id; + packet.compressed_action_0 = std::get<0>(c); + packet.compressed_action_1 = std::get<1>(c); + packet.compressed_action_2 = std::get<2>(c); + packet.compressed_action_3 = std::get<3>(c); + + RewindManager::get()->addEvent(this, packet, /*confirmed*/true, World::getWorld()->getTicksSinceStart()); } // controllerAction @@ -189,15 +199,17 @@ void GameProtocol::handleControllerAction(Event *event) if (NetworkConfig::get()->isServer() && (peer->isWaitingForGame() || peer->getAvailableKartIDs().empty())) return; - NetworkString &data = event->data(); - uint8_t count = data.getUInt8(); + + auto packet = event->getPacket(); + uint8_t count = packet.count; bool will_trigger_rewind = false; //int rewind_delta = 0; int cur_ticks = 0; const int not_rewound = RewindManager::get()->getNotRewoundWorldTicks(); for (unsigned int i = 0; i < count; i++) { - cur_ticks = data.getUInt32(); + auto& action_packet = packet.actions[i]; + cur_ticks = action_packet.ticks; // Since this is running in a thread, it might be called during // a rewind, i.e. with an incorrect world time. So the event // time needs to be compared with the World time independent @@ -207,7 +219,7 @@ void GameProtocol::handleControllerAction(Event *event) will_trigger_rewind = true; //rewind_delta = not_rewound - cur_ticks; } - uint8_t kart_id = data.getUInt8(); + uint8_t kart_id = action_packet.subpacket.kart_id; if (NetworkConfig::get()->isServer() && !peer->availableKartID(kart_id)) { @@ -216,10 +228,10 @@ void GameProtocol::handleControllerAction(Event *event) return; } - uint8_t w = data.getUInt8(); - uint16_t x = data.getUInt16(); - uint16_t y = data.getUInt16(); - uint16_t z = data.getUInt16(); + uint8_t w = action_packet.subpacket.compressed_action_0; + uint16_t x = action_packet.subpacket.compressed_action_1; + uint16_t y = action_packet.subpacket.compressed_action_2; + uint16_t z = action_packet.subpacket.compressed_action_3; if (Network::m_connection_debug) { const auto& a = decompressAction(w, x, y, z); @@ -228,24 +240,16 @@ void GameProtocol::handleControllerAction(Event *event) cur_ticks, kart_id, std::get<0>(a), std::get<1>(a), std::get<2>(a), std::get<3>(a)); } - BareNetworkString *s = new BareNetworkString(3); - s->addUInt8(kart_id).addUInt8(w).addUInt16(x).addUInt16(y) - .addUInt16(z); - RewindManager::get()->addNetworkEvent(this, s, cur_ticks); + RewindManager::get()->addNetworkEvent(this, action_packet.subpacket, cur_ticks); } - if (data.size() > 0) - { - Log::warn("GameProtocol", - "Received invalid controller data - remains %d",data.size()); - } if (NetworkConfig::get()->isServer()) { // Send update to all clients except the original sender if the event // is after the server time peer->updateLastActivity(); if (!will_trigger_rewind) - STKHost::get()->sendNetstringExcept(peer, &data, PRM_UNRELIABLE); + Comm::sendPacketExcept(peer, packet, PRM_UNRELIABLE); } // if server } // handleControllerAction @@ -274,7 +278,8 @@ void GameProtocol::sendItemEventConfirmation(int ticks) void GameProtocol::handleItemEventConfirmation(Event *event) { assert(NetworkConfig::get()->isServer()); - int ticks = event->data().getTime(); + auto packet = event->getPacket(); + int ticks = packet.ticks; m_network_item_manager->setItemConfirmationTime(event->getPeerSP(), ticks); } // handleItemEventConfirmation @@ -285,9 +290,11 @@ void GameProtocol::handleItemEventConfirmation(Event *event) void GameProtocol::startNewState() { assert(NetworkConfig::get()->isServer()); - m_data_to_send->clear(); - m_data_to_send->addUInt8(GP_STATE) - .addUInt32(World::getWorld()->getTicksSinceStart()); + m_packet_to_send = {}; + + GameEventStatePacket packet; + packet.ticks_since_start = World::getWorld()->getTicksSinceStart(); + m_packet_to_send.push_back_state(packet); } // startNewState // ---------------------------------------------------------------------------- @@ -295,11 +302,11 @@ void GameProtocol::startNewState() * is copied, so the data can be freed after this call/. * \param buffer Adds the data in the buffer to the current state. */ -void GameProtocol::addState(BareNetworkString *buffer) +void GameProtocol::addState(const GameEventStatePacket& packet) { assert(NetworkConfig::get()->isServer()); - m_data_to_send->addUInt16(buffer->size()); - (*m_data_to_send) += *buffer; + + m_packet_to_send.push_back_size_packet(packet); } // addState // ---------------------------------------------------------------------------- @@ -310,20 +317,13 @@ void GameProtocol::addState(BareNetworkString *buffer) void GameProtocol::finalizeState(std::vector& cur_rewinder) { assert(NetworkConfig::get()->isServer()); - auto& buffer = m_data_to_send->getBuffer(); - auto pos = buffer.begin() + 1/*protocol type*/ + 1 /*gp event type*/+ - 4/*time*/; - m_data_to_send->reset(); - std::vector names; - names.push_back((uint8_t)cur_rewinder.size()); + std::vector names; for (std::string& name : cur_rewinder) - { - names.push_back((uint8_t)name.size()); - std::vector rewinder(name.begin(), name.end()); - names.insert(names.end(), rewinder.begin(), rewinder.end()); - } - buffer.insert(pos, names.begin(), names.end()); + names.push_back(name); + + m_packet_to_send.rewinders_size = names.size(); + m_packet_to_send.rewinder_names = names; // they should be after time } // finalizeState // ---------------------------------------------------------------------------- @@ -333,7 +333,7 @@ void GameProtocol::finalizeState(std::vector& cur_rewinder) void GameProtocol::sendState() { assert(NetworkConfig::get()->isServer()); - Comm::sendNetstringToPeers(m_data_to_send, PRM_UNRELIABLE); + Comm::sendPacketToPeers(m_packet_to_send, PRM_UNRELIABLE); } // sendState // ---------------------------------------------------------------------------- @@ -343,8 +343,10 @@ void GameProtocol::handleState(Event *event) { if (!NetworkConfig::get()->isClient()) return; - NetworkString &data = event->data(); - int ticks = data.getUInt32(); + + auto packet = event->getPacket(); + + int ticks = packet.ticks_since_start; // Check for updated rewinder using unsigned rewinder_size = data.getUInt8(); @@ -376,13 +378,15 @@ void GameProtocol::undo(BareNetworkString *buffer) * events. * \param buffer Pointer to the saved state information. */ -void GameProtocol::rewind(BareNetworkString *buffer) +void GameProtocol::rewind(const ControllerActionPacket& packet) { - int kart_id = buffer->getUInt8(); - uint8_t w = buffer->getUInt8(); - uint16_t x = buffer->getUInt16(); - uint16_t y = buffer->getUInt16(); - uint16_t z = buffer->getUInt16(); + // kimden: I think the packet type is correct. + // I will likely have to change it to shared_ptr though. + int kart_id = packet.kart_id; + uint8_t w = packet.compressed_action_0; + uint16_t x = packet.compressed_action_1; + uint16_t y = packet.compressed_action_2; + uint16_t z = packet.compressed_action_3; const auto& a = decompressAction(w, x, y, z); Controller *c = World::getWorld()->getKart(kart_id)->getController(); PlayerController *pc = dynamic_cast(c); diff --git a/src/network/protocols/game_protocol.hpp b/src/network/protocols/game_protocol.hpp index 0287e62adae..80391633168 100644 --- a/src/network/protocols/game_protocol.hpp +++ b/src/network/protocols/game_protocol.hpp @@ -46,7 +46,7 @@ class GameProtocol : public Protocol /** A network string that collects all information from the server to be sent * next. */ - NetworkString *m_data_to_send; + std::shared_ptr m_packet_to_send; /** The server might request that the world clock of a client is adjusted * to reduce number of rollbacks. */ From 211fc191bd52aa8670f48dd1c431c6a2ccb83de4 Mon Sep 17 00:00:00 2001 From: kimden <23140380+kimden@users.noreply.github.com> Date: Fri, 11 Jul 2025 02:29:48 +0400 Subject: [PATCH 34/34] A lot of stuff in GameProtocol, and being helpless [skip ci] You look at GameProtocol's network packet formation. It is confusing. The order of things is confusing. You look at places where it's decoded. They are confusing. You look at places where the decoded packet is applied. They are of a base class which means you'll still have to work on them, but for now, you can do nothing without diving deep into them. You look at the rest of code, and you see a map from network packet encoded as array of uint8_t encoded as string. I would like to express my profound gratitude to creators of this code. --- src/items/projectile_manager.cpp | 16 +++----- src/items/projectile_manager.hpp | 5 ++- src/network/packet_types_base.hpp | 21 +++++++++-- src/network/protocols/game_protocol.cpp | 41 +++++++------------- src/network/protocols/game_protocol.hpp | 14 ++++--- src/network/rewind_info.cpp | 50 +++++++++---------------- src/network/rewind_info.hpp | 29 +++++++------- src/network/rewind_manager.cpp | 9 ++--- src/network/rewind_manager.hpp | 21 ++++++----- src/network/rewind_queue.cpp | 10 ++--- src/network/rewind_queue.hpp | 4 +- 11 files changed, 101 insertions(+), 119 deletions(-) diff --git a/src/items/projectile_manager.cpp b/src/items/projectile_manager.cpp index f44e220b1e3..4e817469f19 100644 --- a/src/items/projectile_manager.cpp +++ b/src/items/projectile_manager.cpp @@ -316,19 +316,15 @@ std::string ProjectileManager::getUniqueIdentity(AbstractKart* kart, /* If any flyable is not found in current game state, create it with respect to * its uid as below. */ std::shared_ptr - ProjectileManager::addRewinderFromNetworkState(const std::string& uid) + ProjectileManager::addRewinderFromNetworkState(const ProjectilePacket& packet) { - if (uid.size() != 6) - return nullptr; - BareNetworkString data(uid.data(), (int)uid.size()); - - RewinderName rn = (RewinderName)data.getUInt8(); + RewinderName rn = (RewinderName)packet.rewinder_type; if (!(rn == RN_BOWLING || rn == RN_PLUNGER || rn == RN_CAKE || rn == RN_RUBBERBALL)) return nullptr; - AbstractKart* kart = World::getWorld()->getKart(data.getUInt8()); - int created_ticks = data.getUInt32(); + AbstractKart* kart = World::getWorld()->getKart(packet.kart_id); + int created_ticks = packet.created_ticks; std::shared_ptr f; switch (rn) { @@ -360,7 +356,7 @@ std::shared_ptr assert(f); f->setCreatedTicks(created_ticks); f->onFireFlyable(); - f->addForRewind(uid); + f->addForRewind(packet); Flyable* flyable = f.get(); Log::debug("ProjectileManager", "Missed a firing event, " "add the flyable %s by %s created at %d manually.", @@ -368,7 +364,7 @@ std::shared_ptr StringUtils::wideToUtf8(kart->getController()->getName()).c_str(), created_ticks); - m_active_projectiles[uid] = f; + m_active_projectiles[packet] = f; return f; } // addProjectileFromNetworkState diff --git a/src/items/projectile_manager.hpp b/src/items/projectile_manager.hpp index 52fca14f43e..146164fa93d 100644 --- a/src/items/projectile_manager.hpp +++ b/src/items/projectile_manager.hpp @@ -31,6 +31,7 @@ namespace irr #include "items/powerup_manager.hpp" #include "utils/no_copy.hpp" +#include "network/packet_types.hpp" class AbstractKart; class Flyable; @@ -49,7 +50,7 @@ class ProjectileManager : public NoCopy /** The list of all active projectiles, i.e. projectiles which are * currently moving on the track. */ - std::map > m_active_projectiles; + std::map > m_active_projectiles; /** All active hit effects, i.e. hit effects which are currently * being shown or have a sfx playing. */ @@ -88,7 +89,7 @@ class ProjectileManager : public NoCopy { m_active_hit_effects.push_back(hit_effect); } // ------------------------------------------------------------------------ std::shared_ptr - addRewinderFromNetworkState(const std::string& uid); + addRewinderFromNetworkState(const ProjectilePacket& packet); // ------------------------------------------------------------------------ std::shared_ptr newProjectile(AbstractKart *kart, PowerupManager::PowerupType type); diff --git a/src/network/packet_types_base.hpp b/src/network/packet_types_base.hpp index d03bf9bd852..e3cd79a6667 100644 --- a/src/network/packet_types_base.hpp +++ b/src/network/packet_types_base.hpp @@ -859,16 +859,31 @@ DEFINE_CLASS(GameEventStatePacket) DEFINE_FIELD(uint32_t, ticks_since_start) END_DEFINE_CLASS(GameEventStatePacket) +DEFINE_CLASS(ProjectilePacket) + DEFINE_FIELD(uint8_t, rewinder_type) /* RewinderName enum */ + DEFINE_FIELD(uint8_t, kart_id) + DEFINE_FIELD(uint32_t, created_ticks) +END_DEFINE_CLASS(ProjectilePacket) + +DEFINE_CLASS(TheRestOfBgsPacket) + DEFINE_FIELD(uint16_t, data_size) + DEFINE_FIELD(IHaveNoIdeaActuallyButItHasSizeEqualToDataSize, something) +END_DEFINE_CLASS(TheRestOfBgsPacket) + DEFINE_CLASS(BigGameStatesPacket) PROTOCOL_TYPE(PROTOCOL_GAME_EVENTS, true) DEFINE_TYPE(uint8_t, type, GP_CONTROLLER_ACTION) DEFINE_FIELD(uint32_t, ticks) DEFINE_FIELD(uint8_t, rewinders_size) - DEFINE_VECTOR(std::string, rewinders_size, rewinder_names) /* Previous encoding was manual, adjust if needed. */ - DEFINE_FIELD(ControllerActionBigPacket, actions) - + DEFINE_FIELD(GameEventStatePacket, state) /* kimden: I'm not sure where this should be located within the packet */ + DEFINE_VECTOR(ProjectilePacket, rewinders_size, rewinders) + /* DEFINE_FIELD(ControllerActionBigPacket, actions) --------- kimden: for now, I have no idea why this is here. Probably a leftover. */ + DEFINE_VECTOR(TheRestOfBgsPacket, rewinders_size, the_rest) + // kimden: I have no idea for now /* Don't define RELIABLE, can be sent either way */ END_DEFINE_CLASS(BigGameStatesPacket) + + // end \ No newline at end of file diff --git a/src/network/protocols/game_protocol.cpp b/src/network/protocols/game_protocol.cpp index 0269bcc0d3a..0826114c19d 100644 --- a/src/network/protocols/game_protocol.cpp +++ b/src/network/protocols/game_protocol.cpp @@ -63,7 +63,7 @@ GameProtocol::GameProtocol() { m_network_item_manager = static_cast (Track::getCurrentTrack()->getItemManager()); - m_packet_to_send = {}; + m_packet_to_send = std::make_shared(); } // GameProtocol //----------------------------------------------------------------------------- @@ -81,7 +81,6 @@ void GameProtocol::sendActions() // Clear left-over data from previous frame. This way the network // string will increase till it reaches maximum size necessary - m_packet_to_send = {}; if (m_all_actions.size() > 255) { Log::warn("GameProtocol", @@ -115,7 +114,7 @@ void GameProtocol::sendActions() Comm::sendPacketToServer(big_packet, PRM_RELIABLE); - m_packet_to_send = big_packet; + m_packet_to_send = std::make_shared(big_packet); m_all_actions.clear(); } // sendActions @@ -290,11 +289,11 @@ void GameProtocol::handleItemEventConfirmation(Event *event) void GameProtocol::startNewState() { assert(NetworkConfig::get()->isServer()); - m_packet_to_send = {}; + m_packet_to_send = std::make_shared(); GameEventStatePacket packet; packet.ticks_since_start = World::getWorld()->getTicksSinceStart(); - m_packet_to_send.push_back_state(packet); + m_packet_to_send->state = packet; } // startNewState // ---------------------------------------------------------------------------- @@ -302,11 +301,11 @@ void GameProtocol::startNewState() * is copied, so the data can be freed after this call/. * \param buffer Adds the data in the buffer to the current state. */ -void GameProtocol::addState(const GameEventStatePacket& packet) +void GameProtocol::addState(TheRestOfBgsPacket packet) { assert(NetworkConfig::get()->isServer()); - m_packet_to_send.push_back_size_packet(packet); + m_packet_to_send->the_rest.push_back(std::move(packet)); } // addState // ---------------------------------------------------------------------------- @@ -314,16 +313,12 @@ void GameProtocol::addState(const GameEventStatePacket& packet) * names of rewinder using to the beginning of state buffer * \param cur_rewinder List of current rewinder using. */ -void GameProtocol::finalizeState(std::vector& cur_rewinder) +void GameProtocol::finalizeState(const std::vector& cur_rewinder) { assert(NetworkConfig::get()->isServer()); - std::vector names; - for (std::string& name : cur_rewinder) - names.push_back(name); - - m_packet_to_send.rewinders_size = names.size(); - m_packet_to_send.rewinder_names = names; // they should be after time + m_packet_to_send->rewinders_size = cur_rewinder.size(); + m_packet_to_send->rewinders = cur_rewinder; // they should be after time } // finalizeState // ---------------------------------------------------------------------------- @@ -333,7 +328,7 @@ void GameProtocol::finalizeState(std::vector& cur_rewinder) void GameProtocol::sendState() { assert(NetworkConfig::get()->isServer()); - Comm::sendPacketToPeers(m_packet_to_send, PRM_UNRELIABLE); + Comm::sendPacketToPeers(*m_packet_to_send, PRM_UNRELIABLE); } // sendState // ---------------------------------------------------------------------------- @@ -344,23 +339,15 @@ void GameProtocol::handleState(Event *event) if (!NetworkConfig::get()->isClient()) return; - auto packet = event->getPacket(); + auto packet = event->getPacket(); - int ticks = packet.ticks_since_start; + int ticks = packet.ticks; // Check for updated rewinder using - unsigned rewinder_size = data.getUInt8(); - std::vector rewinder_using; - for (unsigned i = 0; i < rewinder_size; i++) - { - std::string name; - data.decodeString(&name); - rewinder_using.push_back(name); - } + unsigned rewinder_size = packet.rewinders_size; // The memory for bns will be handled in the RewindInfoState object - RewindInfoState* ris = new RewindInfoState(ticks, data.getCurrentOffset(), - rewinder_using, data.getBuffer()); + RewindInfoState* ris = new RewindInfoState(ticks, packet.rewinders, packet.the_rest); RewindManager::get()->addNetworkRewindInfo(ris); } // handleState diff --git a/src/network/protocols/game_protocol.hpp b/src/network/protocols/game_protocol.hpp index 80391633168..f9c14652ec9 100644 --- a/src/network/protocols/game_protocol.hpp +++ b/src/network/protocols/game_protocol.hpp @@ -21,6 +21,7 @@ #include "network/event_rewinder.hpp" #include "network/protocol.hpp" +#include "network/packet_types.hpp" #include "input/input.hpp" // for PlayerAction #include "utils/cpp2011.hpp" @@ -33,7 +34,6 @@ class BareNetworkString; class NetworkItemManager; -class NetworkString; class STKPeer; class GameProtocol : public Protocol @@ -104,13 +104,15 @@ class GameProtocol : public Protocol void controllerAction(int kart_id, PlayerAction action, int value, int val_l, int val_r); void startNewState(); - void addState(BareNetworkString *buffer); + void addState(TheRestOfBgsPacket packet); void sendState(); - void finalizeState(std::vector& cur_rewinder); + void finalizeState(std::vector& cur_rewinder); void sendItemEventConfirmation(int ticks); +#define nonvirtual + virtual void undo(BareNetworkString *buffer) OVERRIDE; - virtual void rewind(BareNetworkString *buffer) OVERRIDE; + nonvirtual void rewind(const ControllerActionPacket& packet) /*OVERRIDE*/; // ------------------------------------------------------------------------ virtual void setup() OVERRIDE {}; // ------------------------------------------------------------------------ @@ -130,8 +132,8 @@ class GameProtocol : public Protocol return m_game_protocol[pt].lock(); } // lock // ------------------------------------------------------------------------ - /** Returns the NetworkString in which a state was saved. */ - NetworkString* getState() const { return m_data_to_send; } + /** Returns the packet ptr in which a state was saved. */ + std::shared_ptr getState() const { return m_packet_to_send; } // ------------------------------------------------------------------------ std::unique_lock acquireWorldDeletingMutex() const { return std::unique_lock(m_world_deleting_mutex); } diff --git a/src/network/rewind_info.cpp b/src/network/rewind_info.cpp index a53cb8c7ebd..a63e2e34c2a 100644 --- a/src/network/rewind_info.cpp +++ b/src/network/rewind_info.cpp @@ -47,26 +47,23 @@ void RewindInfo::setTicks(int ticks) } // setTicks // ============================================================================ -RewindInfoState::RewindInfoState(int ticks, int start_offset, - std::vector& rewinder_using, - std::vector& buffer) +RewindInfoState::RewindInfoState(int ticks, + std::vector rewinder_using, + std::vector the_rest) : RewindInfo(ticks, true/*is_confirmed*/) { - std::swap(m_rewinder_using, rewinder_using); - m_start_offset = start_offset; - m_buffer = new BareNetworkString(); - std::swap(m_buffer->getBuffer(), buffer); + m_rewinder_using = std::move(rewinder_using); + m_buffer = std::move(the_rest); } // RewindInfoState // ------------------------------------------------------------------------ /** Constructor used only in unit testing (without list of rewinder using). */ -RewindInfoState::RewindInfoState(int ticks, BareNetworkString* buffer, +RewindInfoState::RewindInfoState(int ticks, std::vector the_rest, bool is_confirmed) : RewindInfo(ticks, is_confirmed) { - m_start_offset = 0; - m_buffer = buffer; + m_buffer = std::move(the_rest); } // RewindInfoState // ------------------------------------------------------------------------ @@ -76,14 +73,12 @@ RewindInfoState::RewindInfoState(int ticks, BareNetworkString* buffer, */ void RewindInfoState::restore() { - m_buffer->reset(); - m_buffer->skip(m_start_offset); - for (const std::string& name : m_rewinder_using) + size_t idx = 0; + for (const ProjectilePacket& name : m_rewinder_using) { - const uint16_t data_size = m_buffer->getUInt16(); - const unsigned current_offset_now = m_buffer->getCurrentOffset(); - std::shared_ptr r = - RewindManager::get()->getRewinder(name); + TheRestOfBgsPacket& subpacket = m_buffer[idx++]; + const uint16_t data_size = subpacket.data_size; + std::shared_ptr r = RewindManager::get()->getRewinder(name); if (!r) { @@ -95,42 +90,31 @@ void RewindInfoState::restore() { if (!RewindManager::get()->hasMissingRewinder(name)) { - Log::error("RewindInfoState", "Missing rewinder %s", - name.c_str()); + Log::error("RewindInfoState", "Missing rewinder (%d, %d, %d)", + name.rewinder_type, name.kart_id, name.created_ticks); RewindManager::get()->addMissingRewinder(name); } - m_buffer->skip(data_size); continue; } try { - r->restoreState(m_buffer, data_size); + r->restoreState(subpacket.something); } catch (std::exception& e) { Log::error("RewindInfoState", "Restore state error: %s", e.what()); - m_buffer->reset(); - m_buffer->skip(current_offset_now + data_size); continue; } - - if (m_buffer->getCurrentOffset() - current_offset_now != data_size) - { - Log::error("RewindInfoState", "Wrong size read when restore " - "state, incompatible binary?"); - m_buffer->reset(); - m_buffer->skip(current_offset_now + data_size); - } } // for all rewinder } // restore // ============================================================================ RewindInfoEvent::RewindInfoEvent(int ticks, EventRewinder *event_rewinder, - BareNetworkString *buffer, bool is_confirmed) + ControllerActionPacket packet, bool is_confirmed) : RewindInfo(ticks, is_confirmed) { m_event_rewinder = event_rewinder; - m_buffer = buffer; + m_buffer = std::move(packet); } // RewindInfoEvent diff --git a/src/network/rewind_info.hpp b/src/network/rewind_info.hpp index b7376d8d567..c4665816e17 100644 --- a/src/network/rewind_info.hpp +++ b/src/network/rewind_info.hpp @@ -21,6 +21,7 @@ #include "network/event_rewinder.hpp" #include "network/network_string.hpp" +#include "network/packet_types.hpp" #include "utils/cpp2011.hpp" #include "utils/leak_check.hpp" #include "utils/ptr_vector.hpp" @@ -92,27 +93,27 @@ class RewindInfo class RewindInfoState: public RewindInfo { private: - std::vector m_rewinder_using; + std::vector m_rewinder_using; int m_start_offset; - /** Pointer to the buffer which stores all states. */ - BareNetworkString *m_buffer; + std::vector m_buffer; public: // ------------------------------------------------------------------------ - RewindInfoState(int ticks, int start_offset, - std::vector& rewinder_using, - std::vector& buffer); + RewindInfoState(int ticks, + std::vector rewinder_using, + std::vector the_rest); // ------------------------------------------------------------------------ - RewindInfoState(int ticks, BareNetworkString *buffer, bool is_confirmed); + RewindInfoState(int ticks, std::vector the_rest, + bool is_confirmed); // ------------------------------------------------------------------------ - virtual ~RewindInfoState() { delete m_buffer; } + virtual ~RewindInfoState() { } // ------------------------------------------------------------------------ virtual void restore(); // ------------------------------------------------------------------------ /** Returns a pointer to the state buffer. */ - BareNetworkString *getBuffer() const { return m_buffer; } + std::vector getBuffer() const { return m_buffer; } // ------------------------------------------------------------------------ virtual bool isState() const { return true; } // ------------------------------------------------------------------------ @@ -139,13 +140,12 @@ class RewindInfoEvent : public RewindInfo EventRewinder *m_event_rewinder; /** Buffer with the event data. */ - BareNetworkString *m_buffer; + ControllerActionPacket m_buffer; public: RewindInfoEvent(int ticks, EventRewinder *event_rewinder, - BareNetworkString *buffer, bool is_confirmed); + ControllerActionPacket packet, bool is_confirmed); virtual ~RewindInfoEvent() { - delete m_buffer; } // ~RewindInfoEvent // ------------------------------------------------------------------------ @@ -158,7 +158,6 @@ class RewindInfoEvent : public RewindInfo * It calls undoEvent in the rewinder. */ virtual void undo() { - m_buffer->reset(); m_event_rewinder->undo(m_buffer); } // undo // ------------------------------------------------------------------------ @@ -167,13 +166,11 @@ class RewindInfoEvent : public RewindInfo */ virtual void replay() { - // Make sure to reset the buffer so we read from the beginning - m_buffer->reset(); m_event_rewinder->rewind(m_buffer); } // rewind // ------------------------------------------------------------------------ /** Returns the buffer with the event information in it. */ - BareNetworkString *getBuffer() { return m_buffer; } + ControllerActionPacket getBuffer() { return m_buffer; } }; // class RewindIndoEvent diff --git a/src/network/rewind_manager.cpp b/src/network/rewind_manager.cpp index e6afe109976..a3d1712278d 100644 --- a/src/network/rewind_manager.cpp +++ b/src/network/rewind_manager.cpp @@ -105,19 +105,18 @@ void RewindManager::reset() * \param buffer Pointer to the event data. */ void RewindManager::addEvent(EventRewinder *event_rewinder, - BareNetworkString *buffer, bool confirmed, + const ControllerActionPacket& packet, bool confirmed, int ticks) { if (m_is_rewinding) { - delete buffer; Log::error("RewindManager", "Adding event when rewinding"); return; } if (ticks < 0) ticks = World::getWorld()->getTicksSinceStart(); - m_rewind_queue.addLocalEvent(event_rewinder, buffer, confirmed, ticks); + m_rewind_queue.addLocalEvent(event_rewinder, packet, confirmed, ticks); } // addEvent // ---------------------------------------------------------------------------- @@ -129,9 +128,9 @@ void RewindManager::addEvent(EventRewinder *event_rewinder, * \param buffer Pointer to the event data. */ void RewindManager::addNetworkEvent(EventRewinder *event_rewinder, - BareNetworkString *buffer, int ticks) + ControllerActionPacket packet, int ticks) { - m_rewind_queue.addNetworkEvent(event_rewinder, buffer, ticks); + m_rewind_queue.addNetworkEvent(event_rewinder, std::move(packet), ticks); } // addNetworkEvent // ---------------------------------------------------------------------------- diff --git a/src/network/rewind_manager.hpp b/src/network/rewind_manager.hpp index ee171260e0f..7c02fca14ae 100644 --- a/src/network/rewind_manager.hpp +++ b/src/network/rewind_manager.hpp @@ -20,6 +20,7 @@ #define HEADER_REWIND_MANAGER_HPP #include "network/rewind_queue.hpp" +#include "network/packet_types.hpp" #include "utils/stk_process.hpp" #include @@ -94,7 +95,7 @@ class RewindManager std::map > > m_local_state; /** A list of all objects that can be rewound. */ - std::map > m_all_rewinder; + std::map > m_all_rewinder; /** The queue that stores all rewind infos. */ RewindQueue m_rewind_queue; @@ -117,7 +118,7 @@ class RewindManager bool m_schedule_reset_network_body; - std::set m_missing_rewinders; + std::set m_missing_rewinders; RewindManager(); ~RewindManager(); @@ -170,16 +171,16 @@ class RewindManager void update(int ticks); void rewindTo(int target_ticks, int ticks_now, bool fast_forward); void playEventsTill(int world_ticks, bool fast_forward); - void addEvent(EventRewinder *event_rewinder, BareNetworkString *buffer, + void addEvent(EventRewinder *event_rewinder, const ControllerActionPacket& packet, bool confirmed, int ticks = -1); void addNetworkEvent(EventRewinder *event_rewinder, - BareNetworkString *buffer, int ticks); + ControllerActionPacket packet, int ticks); void addNetworkState(BareNetworkString *buffer, int ticks); void saveState(); // ------------------------------------------------------------------------ - std::shared_ptr getRewinder(const std::string& name) + std::shared_ptr getRewinder(const ProjectilePacket& packet) { - auto it = m_all_rewinder.find(name); + auto it = m_all_rewinder.find(packet); if (it != m_all_rewinder.end()) { if (auto r = it->second.lock()) @@ -223,11 +224,11 @@ class RewindManager // ------------------------------------------------------------------------ void handleResetSmoothNetworkBody(); // ------------------------------------------------------------------------ - void addMissingRewinder(const std::string& name) - { m_missing_rewinders.insert(name); } + void addMissingRewinder(const ProjectilePacket& packet) + { m_missing_rewinders.insert(packet); } // ------------------------------------------------------------------------ - bool hasMissingRewinder(const std::string& name) const - { return m_missing_rewinders.find(name) != m_missing_rewinders.end(); } + bool hasMissingRewinder(const ProjectilePacket& packet) const + { return m_missing_rewinders.find(packet) != m_missing_rewinders.end(); } }; // RewindManager diff --git a/src/network/rewind_queue.cpp b/src/network/rewind_queue.cpp index d8eeb3f9921..73df6044250 100644 --- a/src/network/rewind_queue.cpp +++ b/src/network/rewind_queue.cpp @@ -120,11 +120,11 @@ void RewindQueue::insertRewindInfo(RewindInfo *ri) * \param ticks Time at which the event happened. */ void RewindQueue::addLocalEvent(EventRewinder *event_rewinder, - BareNetworkString *buffer, bool confirmed, - int ticks ) + const ControllerActionPacket& packet, bool confirmed, + int ticks) { RewindInfo *ri = new RewindInfoEvent(ticks, event_rewinder, - buffer, confirmed); + packet, confirmed); insertRewindInfo(ri); } // addLocalEvent @@ -160,10 +160,10 @@ void RewindQueue::addLocalState(BareNetworkString *buffer, * \param ticks Time at which the event happened. */ void RewindQueue::addNetworkEvent(EventRewinder *event_rewinder, - BareNetworkString *buffer, int ticks) + ControllerActionPacket packet, int ticks) { RewindInfo *ri = new RewindInfoEvent(ticks, event_rewinder, - buffer, /*confirmed*/true); + std::move(packet), /*confirmed*/true); m_network_events.lock(); m_network_events.getData().push_back(ri); diff --git a/src/network/rewind_queue.hpp b/src/network/rewind_queue.hpp index 4daadf4d4db..b1d8aa1128c 100644 --- a/src/network/rewind_queue.hpp +++ b/src/network/rewind_queue.hpp @@ -64,11 +64,11 @@ class RewindQueue RewindQueue(); ~RewindQueue(); void reset(); - void addLocalEvent(EventRewinder *event_rewinder, BareNetworkString *buffer, + void addLocalEvent(EventRewinder *event_rewinder, const ControllerActionPacket& packet, bool confirmed, int ticks); void addLocalState(BareNetworkString *buffer, bool confirmed, int ticks); void addNetworkEvent(EventRewinder *event_rewinder, - BareNetworkString *buffer, int ticks); + ControllerActionPacket packet, int ticks); void addNetworkState(BareNetworkString *buffer, int ticks); void addNetworkRewindInfo(RewindInfo* ri) {