Avoid network incompatibility if players add or remove official karts

This commit is contained in:
Benau 2021-07-17 11:07:34 +08:00
parent a62c355e91
commit 24f96ccfc9
5 changed files with 70 additions and 38 deletions

View File

@ -26,9 +26,11 @@
#include "karts/kart_model.hpp" #include "karts/kart_model.hpp"
#include "karts/kart_properties.hpp" #include "karts/kart_properties.hpp"
#include "karts/kart_properties_manager.hpp" #include "karts/kart_properties_manager.hpp"
#include "karts/official_karts.hpp"
#include "network/network_config.hpp" #include "network/network_config.hpp"
#include "physics/physics.hpp" #include "physics/physics.hpp"
#include "utils/log.hpp" #include "utils/log.hpp"
#include "utils/string_utils.hpp"
/** Creates a kart. /** Creates a kart.
* \param ident The identifier of the kart. * \param ident The identifier of the kart.
@ -81,6 +83,8 @@ void AbstractKart::loadKartProperties(const std::string& new_ident,
m_kart_properties.reset(new KartProperties()); m_kart_properties.reset(new KartProperties());
const KartProperties* kp = kart_properties_manager->getKart(new_ident); const KartProperties* kp = kart_properties_manager->getKart(new_ident);
const KartProperties* kp_addon = NULL; const KartProperties* kp_addon = NULL;
const KartProperties* official_kp = NULL;
Vec3 gravity_shift;
if (NetworkConfig::get()->isNetworking() && if (NetworkConfig::get()->isNetworking() &&
NetworkConfig::get()->useTuxHitboxAddon() && kp && kp->isAddon()) NetworkConfig::get()->useTuxHitboxAddon() && kp && kp->isAddon())
{ {
@ -92,17 +96,30 @@ void AbstractKart::loadKartProperties(const std::string& new_ident,
} }
if (kp == NULL) if (kp == NULL)
{ {
bool official_kart = !StringUtils::startsWith(new_ident, "addon_");
if (!NetworkConfig::get()->isNetworking() || if (!NetworkConfig::get()->isNetworking() ||
!NetworkConfig::get()->useTuxHitboxAddon()) (!NetworkConfig::get()->useTuxHitboxAddon() && !official_kart))
{ {
Log::warn("Abstract_Kart", "Unknown kart %s, fallback to tux", Log::warn("Abstract_Kart", "Unknown kart %s, fallback to tux",
new_ident.c_str()); new_ident.c_str());
} }
kp = kart_properties_manager->getKart(std::string("tux")); kp = kart_properties_manager->getKart(std::string("tux"));
if (NetworkConfig::get()->isNetworking() && official_kart)
{
official_kp = OfficialKarts::getKartByIdent(new_ident,
&m_kart_width, &m_kart_height, &m_kart_length, &gravity_shift);
if (official_kp)
kp = official_kp;
}
} }
m_kart_properties->copyForPlayer(kp, handicap); m_kart_properties->copyForPlayer(kp, handicap);
if (kp_addon) if (kp_addon)
m_kart_properties->adjustForOnlineAddonKart(kp_addon); m_kart_properties->adjustForOnlineAddonKart(kp_addon);
if (official_kp)
{
m_kart_properties->updateForOnlineKart(new_ident, gravity_shift,
m_kart_length);
}
m_name = m_kart_properties->getName(); m_name = m_kart_properties->getName();
m_handicap = handicap; m_handicap = handicap;
m_kart_animation = NULL; m_kart_animation = NULL;
@ -119,9 +136,12 @@ void AbstractKart::loadKartProperties(const std::string& new_ident,
m_kart_model.reset(kp_addon->getKartModelCopy(ri)); m_kart_model.reset(kp_addon->getKartModelCopy(ri));
else else
m_kart_model.reset(m_kart_properties->getKartModelCopy(ri)); m_kart_model.reset(m_kart_properties->getKartModelCopy(ri));
m_kart_width = kp->getMasterKartModel().getWidth(); if (official_kp == NULL)
m_kart_height = kp->getMasterKartModel().getHeight(); {
m_kart_length = kp->getMasterKartModel().getLength(); m_kart_width = kp->getMasterKartModel().getWidth();
m_kart_height = kp->getMasterKartModel().getHeight();
m_kart_length = kp->getMasterKartModel().getLength();
}
m_kart_highest_point = m_kart_model->getHighestPoint(); m_kart_highest_point = m_kart_model->getHighestPoint();
m_wheel_graphics_position = m_kart_model->getWheelsGraphicsPosition(); m_wheel_graphics_position = m_kart_model->getWheelsGraphicsPosition();
} // loadKartProperties } // loadKartProperties

View File

@ -86,7 +86,7 @@ KartProperties::KartProperties(const std::string &filename)
// if everything is defined properly. // if everything is defined properly.
m_wheel_base = m_friction_slip = m_collision_terrain_impulse = m_wheel_base = m_friction_slip = m_collision_terrain_impulse =
m_collision_impulse = m_collision_impulse_time = m_collision_impulse = m_collision_impulse_time =
m_max_lean = m_lean_speed = m_physical_wheel_position = UNDEFINED; m_physical_wheel_position = UNDEFINED;
m_terrain_impulse_type = IMPULSE_NONE; m_terrain_impulse_type = IMPULSE_NONE;
m_gravity_center_shift = Vec3(UNDEFINED); m_gravity_center_shift = Vec3(UNDEFINED);
@ -328,13 +328,7 @@ void KartProperties::load(const std::string &filename, const std::string &node)
m_gravity_center_shift.setZ(0); m_gravity_center_shift.setZ(0);
} }
// The longer the kart,the bigger its turn radius if using an identical setWheelBase(m_kart_model->getLength());
// wheel base, exactly proportionally to its length.
// The wheel base is used to compensate this
// We divide by 1.425 to have a default turn radius which conforms
// closely (+-0,1%) with the specifications in kart_characteristics.xml
m_wheel_base = fabsf(m_kart_model->getLength()/1.425f);
m_shadow_material = material_manager->getMaterialSPM(m_shadow_file, "", m_shadow_material = material_manager->getMaterialSPM(m_shadow_file, "",
"alphablend"); "alphablend");

View File

@ -159,14 +159,6 @@ private:
/** Wheel base of the kart. */ /** Wheel base of the kart. */
float m_wheel_base; float m_wheel_base;
/** The maximum roll a kart graphics should show when driving in a fast
* curve. This is read in as degrees, but stored in radians. */
float m_max_lean;
/** The speed with which the roll (when leaning in a curve) changes
* (in radians/second). */
float m_lean_speed;
/** Engine sound effect. */ /** Engine sound effect. */
std::string m_engine_sfx_type; std::string m_engine_sfx_type;
@ -208,6 +200,15 @@ private:
const std::string &node); const std::string &node);
void combineCharacteristics(HandicapLevel h); void combineCharacteristics(HandicapLevel h);
void setWheelBase(float kart_length)
{
// The longer the kart,the bigger its turn radius if using an identical
// wheel base, exactly proportionally to its length.
// The wheel base is used to compensate this
// We divide by 1.425 to have a default turn radius which conforms
// closely (+-0,1%) with the specifications in kart_characteristics.xml
m_wheel_base = fabsf(kart_length / 1.425f);
}
public: public:
/** Returns the string representation of a handicap level. */ /** Returns the string representation of a handicap level. */
static std::string getHandicapAsString(HandicapLevel h); static std::string getHandicapAsString(HandicapLevel h);
@ -217,6 +218,13 @@ public:
void copyForPlayer (const KartProperties *source, void copyForPlayer (const KartProperties *source,
HandicapLevel h = HANDICAP_NONE); HandicapLevel h = HANDICAP_NONE);
void adjustForOnlineAddonKart(const KartProperties* source); void adjustForOnlineAddonKart(const KartProperties* source);
void updateForOnlineKart(const std::string& id, const Vec3& gravity_shift,
float kart_length)
{
m_ident = id;
m_gravity_center_shift = gravity_shift;
setWheelBase(kart_length);
}
void copyFrom (const KartProperties *source); void copyFrom (const KartProperties *source);
void getAllData (const XMLNode * root); void getAllData (const XMLNode * root);
void checkAllSet (const std::string &filename); void checkAllSet (const std::string &filename);

View File

@ -36,6 +36,7 @@
#include "karts/controller/controller.hpp" #include "karts/controller/controller.hpp"
#include "karts/kart_properties.hpp" #include "karts/kart_properties.hpp"
#include "karts/kart_properties_manager.hpp" #include "karts/kart_properties_manager.hpp"
#include "karts/official_karts.hpp"
#include "modes/linear_world.hpp" #include "modes/linear_world.hpp"
#include "network/crypto.hpp" #include "network/crypto.hpp"
#include "network/event.hpp" #include "network/event.hpp"
@ -1785,10 +1786,20 @@ void ClientLobby::handleClientCommand(const std::string& cmd)
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void ClientLobby::getKartsTracksNetworkString(BareNetworkString* ns) void ClientLobby::getKartsTracksNetworkString(BareNetworkString* ns)
{ {
auto all_k = kart_properties_manager->getAllAvailableKarts(); std::vector<std::string> all_k;
for (unsigned i = 0; i < kart_properties_manager->getNumberOfKarts(); i++)
{
const KartProperties* kp = kart_properties_manager->getKartById(i);
if (kp->isAddon())
all_k.push_back(kp->getIdent());
}
std::set<std::string> oks = OfficialKarts::getOfficialKarts();
if (all_k.size() >= 65536 - (unsigned)oks.size())
all_k.resize(65535 - (unsigned)oks.size());
for (const std::string& k : oks)
all_k.push_back(k);
auto all_t = track_manager->getAllTrackIdentifiers(); auto all_t = track_manager->getAllTrackIdentifiers();
if (all_k.size() >= 65536)
all_k.resize(65535);
if (all_t.size() >= 65536) if (all_t.size() >= 65536)
all_t.resize(65535); all_t.resize(65535);
ns->addUInt16((uint16_t)all_k.size()).addUInt16((uint16_t)all_t.size()); ns->addUInt16((uint16_t)all_k.size()).addUInt16((uint16_t)all_t.size());

View File

@ -26,6 +26,7 @@
#include "karts/controller/player_controller.hpp" #include "karts/controller/player_controller.hpp"
#include "karts/kart_properties.hpp" #include "karts/kart_properties.hpp"
#include "karts/kart_properties_manager.hpp" #include "karts/kart_properties_manager.hpp"
#include "karts/official_karts.hpp"
#include "modes/capture_the_flag.hpp" #include "modes/capture_the_flag.hpp"
#include "modes/linear_world.hpp" #include "modes/linear_world.hpp"
#include "network/crypto.hpp" #include "network/crypto.hpp"
@ -207,8 +208,6 @@ ServerLobby::ServerLobby() : LobbyProtocol()
{ {
m_client_server_host_id.store(0); m_client_server_host_id.store(0);
m_lobby_players.store(0); m_lobby_players.store(0);
std::vector<int> all_k =
kart_properties_manager->getKartsInGroup("standard");
std::vector<int> all_t = std::vector<int> all_t =
track_manager->getTracksInGroup("standard"); track_manager->getTracksInGroup("standard");
std::vector<int> all_arenas = std::vector<int> all_arenas =
@ -218,16 +217,7 @@ ServerLobby::ServerLobby() : LobbyProtocol()
all_t.insert(all_t.end(), all_arenas.begin(), all_arenas.end()); all_t.insert(all_t.end(), all_arenas.begin(), all_arenas.end());
all_t.insert(all_t.end(), all_soccers.begin(), all_soccers.end()); all_t.insert(all_t.end(), all_soccers.begin(), all_soccers.end());
for (int kart : all_k) m_official_kts.first = OfficialKarts::getOfficialKarts();
{
const KartProperties* kp = kart_properties_manager->getKartById(kart);
// Some distro put kart itself, ignore it online for the rest of stk
// user
if (kp->getIdent() == "geeko")
continue;
if (!kp->isAddon())
m_official_kts.first.insert(kp->getIdent());
}
for (int track : all_t) for (int track : all_t)
{ {
Track* t = track_manager->getTrack(track); Track* t = track_manager->getTrack(track);
@ -614,9 +604,18 @@ void ServerLobby::updateAddons()
m_addon_kts.second.insert(t->getIdent()); m_addon_kts.second.insert(t->getIdent());
} }
auto all_k = kart_properties_manager->getAllAvailableKarts(); std::vector<std::string> all_k;
if (all_k.size() >= 65536) for (unsigned i = 0; i < kart_properties_manager->getNumberOfKarts(); i++)
all_k.resize(65535); {
const KartProperties* kp = kart_properties_manager->getKartById(i);
if (kp->isAddon())
all_k.push_back(kp->getIdent());
}
std::set<std::string> oks = OfficialKarts::getOfficialKarts();
if (all_k.size() >= 65536 - (unsigned)oks.size())
all_k.resize(65535 - (unsigned)oks.size());
for (const std::string& k : oks)
all_k.push_back(k);
if (ServerConfig::m_live_players) if (ServerConfig::m_live_players)
m_available_kts.first = m_official_kts.first; m_available_kts.first = m_official_kts.first;
else else