diff options
-rw-r--r-- | src/network/core/core.h | 2 | ||||
-rw-r--r-- | src/network/network_server.cpp | 13 | ||||
-rw-r--r-- | src/network/network_udp.cpp | 33 |
3 files changed, 44 insertions, 4 deletions
diff --git a/src/network/core/core.h b/src/network/core/core.h index 932199a9c..10df20af7 100644 --- a/src/network/core/core.h +++ b/src/network/core/core.h @@ -76,7 +76,7 @@ public: void SendGRFIdentifier(Packet *p, const GRFIdentifier *grf); void ReceiveGRFIdentifier(Packet *p, GRFIdentifier *grf); - void SendCompanyInformation(Packet *p, const struct Company *c, const struct NetworkCompanyStats *stats); + void SendCompanyInformation(Packet *p, const struct Company *c, const struct NetworkCompanyStats *stats, uint max_len = NETWORK_COMPANY_NAME_LENGTH); }; #endif /* ENABLE_NETWORK */ diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index 39da21632..791d766d7 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -1373,12 +1373,21 @@ DEF_GAME_RECEIVE_COMMAND(Server, PACKET_CLIENT_MOVE) return NETWORK_RECV_STATUS_OKAY; } -void NetworkSocketHandler::SendCompanyInformation(Packet *p, const Company *c, const NetworkCompanyStats *stats) +/** + * Package some generic company information into a packet. + * @param p The packet that will contain the data. + * @param c The company to put the of into the packet. + * @param stats The statistics to put in the packet. + * @param max_len The maximum length of the company name. + */ +void NetworkSocketHandler::SendCompanyInformation(Packet *p, const Company *c, const NetworkCompanyStats *stats, uint max_len) { /* Grab the company name */ char company_name[NETWORK_COMPANY_NAME_LENGTH]; SetDParam(0, c->index); - GetString(company_name, STR_COMPANY_NAME, lastof(company_name)); + + assert(max_len <= lengthof(company_name)); + GetString(company_name, STR_COMPANY_NAME, company_name + max_len - 1); /* Get the income */ Money income = 0; diff --git a/src/network/network_udp.cpp b/src/network/network_udp.cpp index 11e27d749..ed7cd3581 100644 --- a/src/network/network_udp.cpp +++ b/src/network/network_udp.cpp @@ -29,6 +29,8 @@ #include "../thread/thread.h" #include "../rev.h" #include "../newgrf_text.h" +#include "../strings_func.h" +#include "table/strings.h" #include "core/udp.h" @@ -138,11 +140,40 @@ DEF_UDP_RECEIVE_COMMAND(Server, PACKET_UDP_CLIENT_DETAIL_INFO) NetworkCompanyStats company_stats[MAX_COMPANIES]; NetworkPopulateCompanyStats(company_stats); + /* The minimum company information "blob" size. */ + static const uint MIN_CI_SIZE = 54; + uint max_cname_length = NETWORK_COMPANY_NAME_LENGTH; + + if (Company::GetNumItems() * (MIN_CI_SIZE + NETWORK_COMPANY_NAME_LENGTH) >= (uint)packet.size - packet.pos) { + /* Assume we can at least put the company information in the packets. */ + assert(Company::GetNumItems() * MIN_CI_SIZE < (uint)packet.size - packet.pos); + + /* At this moment the company names might not fit in the + * packet. Check whether that is really the case. */ + + for (;;) { + int free = packet.size - packet.pos; + Company *company; + FOR_ALL_COMPANIES(company) { + char company_name[NETWORK_COMPANY_NAME_LENGTH]; + SetDParam(0, company->index); + GetString(company_name, STR_COMPANY_NAME, company_name + max_cname_length - 1); + free -= MIN_CI_SIZE; + free -= strlen(company_name); + } + if (free >= 0) break; + + /* Try again, with slightly shorter strings. */ + assert(max_cname_length > 0); + max_cname_length--; + } + } + Company *company; /* Go through all the companies */ FOR_ALL_COMPANIES(company) { /* Send the information */ - this->SendCompanyInformation(&packet, company, &company_stats[company->index]); + this->SendCompanyInformation(&packet, company, &company_stats[company->index], max_cname_length); } this->SendPacket(&packet, client_addr); |