From bbca00f53b09320600e8d6e5a38dda5456116d03 Mon Sep 17 00:00:00 2001 From: Alina Lenk Date: Sat, 4 May 2024 02:08:00 +0200 Subject: [PATCH 5/6] network protocol: directly transmit requirement vectors See RM #540 Signed-off-by: Alina Lenk --- client/packhand.c | 161 ++++++++--------------------- common/effects.c | 17 ++-- common/networking/packets.def | 66 ++++-------- server/ruleset/ruleload.c | 187 ++++++++++------------------------ 4 files changed, 120 insertions(+), 311 deletions(-) diff --git a/client/packhand.c b/client/packhand.c index e877ac059b..9bdf08dda0 100644 --- a/client/packhand.c +++ b/client/packhand.c @@ -3624,9 +3624,7 @@ void handle_ruleset_unit(const struct packet_ruleset_unit *p) u->attack_strength = p->attack_strength; u->defense_strength = p->defense_strength; u->move_rate = p->move_rate; - for (i = 0; i < p->build_reqs_count; i++) { - requirement_vector_append(&u->build_reqs, p->build_reqs[i]); - } + requirement_vector_copy(&u->build_reqs, &p->build_reqs); u->vision_radius_sq = p->vision_radius_sq; u->transport_capacity = p->transport_capacity; u->hp = p->hp; @@ -3745,29 +3743,26 @@ void handle_ruleset_unit_class_flag( } /************************************************************************//** - Unpack a traditional tech req from a standard requirement vector (that - still is in the network serialized format rather than a proper - requirement vector). + Unpack a traditional tech req from a standard requirement vector. Returns the position in the requirement vector after unpacking. It will increase if a tech req was extracted. ****************************************************************************/ static int unpack_tech_req(const enum tech_req r_num, - const int reqs_size, - const struct requirement *reqs, + const struct requirement_vector *reqs, struct advance *a, int i) { - if (i < reqs_size - && reqs[i].source.kind == VUT_ADVANCE) { + if (i < requirement_vector_size(reqs) + && requirement_vector_get(reqs, i)->source.kind == VUT_ADVANCE) { /* Extract the tech req so the old code can reason about it. */ /* This IS a traditional tech req... right? */ - fc_assert(reqs[i].present); - fc_assert(reqs[i].range == REQ_RANGE_PLAYER); + fc_assert(requirement_vector_get(reqs, i)->present); + fc_assert(requirement_vector_get(reqs, i)->range == REQ_RANGE_PLAYER); /* Put it in the advance structure. */ - a->require[r_num] = reqs[i].source.value.advance; + a->require[r_num] = requirement_vector_get(reqs, i)->source.value.advance; /* Move on in the requirement vector. */ i++; @@ -3813,15 +3808,19 @@ void handle_ruleset_tech(const struct packet_ruleset_tech *p) a->require[AR_TWO] = A_NEVER; } else { /* Unpack req1 and req2 from the research_reqs requirement vector. */ - i = unpack_tech_req(AR_ONE, p->research_reqs_count, p->research_reqs, a, i); - i = unpack_tech_req(AR_TWO, p->research_reqs_count, p->research_reqs, a, i); + i = unpack_tech_req(AR_ONE, &p->research_reqs, a, i); + i = unpack_tech_req(AR_TWO, &p->research_reqs, a, i); } /* Any remaining requirements are a part of the research_reqs requirement * vector. */ - for (; i < p->research_reqs_count; i++) { - requirement_vector_append(&a->research_reqs, p->research_reqs[i]); - } + requirement_vector_copy(&a->research_reqs, + /* slice of the vector starting at index i */ + &(const struct requirement_vector) { + .p = p->research_reqs.p + i, + .size = p->research_reqs.size - i, + /* .size_alloc shouldn't matter */ + }); /* The packet's research_reqs should contain req1, req2 and the * requirements of the tech's research_reqs. */ @@ -3832,7 +3831,7 @@ void handle_ruleset_tech(const struct packet_ruleset_tech *p) + ((a->require[AR_TWO] && (advance_number(a->require[AR_TWO]) != A_NONE)) ? 1 : 0)) - == p->research_reqs_count); + == requirement_vector_size(&p->research_reqs)); a->require[AR_ROOT] = advance_by_number(p->root_req); @@ -3887,7 +3886,6 @@ void handle_ruleset_tech_flag(const struct packet_ruleset_tech_flag *p) ****************************************************************************/ void handle_ruleset_building(const struct packet_ruleset_building *p) { - int i; struct impr_type *b = improvement_by_number(p->id); fc_assert_ret_msg(NULL != b, "Bad improvement %d.", p->id); @@ -3897,14 +3895,8 @@ void handle_ruleset_building(const struct packet_ruleset_building *p) sz_strlcpy(b->graphic_str, p->graphic_str); sz_strlcpy(b->graphic_alt, p->graphic_alt); sz_strlcpy(b->graphic_alt2, p->graphic_alt2); - for (i = 0; i < p->reqs_count; i++) { - requirement_vector_append(&b->reqs, p->reqs[i]); - } - fc_assert(b->reqs.size == p->reqs_count); - for (i = 0; i < p->obs_count; i++) { - requirement_vector_append(&b->obsolete_by, p->obs_reqs[i]); - } - fc_assert(b->obsolete_by.size == p->obs_count); + requirement_vector_copy(&b->reqs, &p->reqs); + requirement_vector_copy(&b->obsolete_by, &p->obs_reqs); b->build_cost = p->build_cost; b->upkeep = p->upkeep; b->sabotage = p->sabotage; @@ -3965,7 +3957,6 @@ void handle_ruleset_impr_flag(const struct packet_ruleset_impr_flag *p) void handle_ruleset_multiplier(const struct packet_ruleset_multiplier *p) { struct multiplier *pmul = multiplier_by_number(p->id); - int j; fc_assert_ret_msg(NULL != pmul, "Bad multiplier %d.", p->id); @@ -3978,12 +3969,7 @@ void handle_ruleset_multiplier(const struct packet_ruleset_multiplier *p) pmul->minimum_turns = p->minimum_turns; names_set(&pmul->name, NULL, p->name, p->rule_name); - - for (j = 0; j < p->reqs_count; j++) { - requirement_vector_append(&pmul->reqs, p->reqs[j]); - } - fc_assert(pmul->reqs.size == p->reqs_count); - + requirement_vector_copy(&pmul->reqs, &p->reqs); PACKET_STRVEC_EXTRACT(pmul->helptext, p->helptext); } @@ -3992,18 +3978,13 @@ void handle_ruleset_multiplier(const struct packet_ruleset_multiplier *p) ****************************************************************************/ void handle_ruleset_government(const struct packet_ruleset_government *p) { - int j; struct government *gov = government_by_number(p->id); fc_assert_ret_msg(NULL != gov, "Bad government %d.", p->id); gov->item_number = p->id; - for (j = 0; j < p->reqs_count; j++) { - requirement_vector_append(&gov->reqs, p->reqs[j]); - } - fc_assert(gov->reqs.size == p->reqs_count); - + requirement_vector_copy(&gov->reqs, &p->reqs); names_set(&gov->name, NULL, p->name, p->rule_name); sz_strlcpy(gov->graphic_str, p->graphic_str); sz_strlcpy(gov->graphic_alt, p->graphic_alt); @@ -4227,27 +4208,14 @@ void handle_ruleset_extra(const struct packet_ruleset_extra *p) sz_strlcpy(pextra->graphic_str, p->graphic_str); sz_strlcpy(pextra->graphic_alt, p->graphic_alt); - for (i = 0; i < p->reqs_count; i++) { - requirement_vector_append(&pextra->reqs, p->reqs[i]); - } - fc_assert(pextra->reqs.size == p->reqs_count); - - for (i = 0; i < p->rmreqs_count; i++) { - requirement_vector_append(&pextra->rmreqs, p->rmreqs[i]); - } - fc_assert(pextra->rmreqs.size == p->rmreqs_count); + requirement_vector_copy(&pextra->reqs, &p->reqs); + requirement_vector_copy(&pextra->rmreqs, &p->rmreqs); pextra->appearance_chance = p->appearance_chance; - for (i = 0; i < p->appearance_reqs_count; i++) { - requirement_vector_append(&pextra->appearance_reqs, p->appearance_reqs[i]); - } - fc_assert(pextra->appearance_reqs.size == p->appearance_reqs_count); + requirement_vector_copy(&pextra->appearance_reqs, &p->appearance_reqs); pextra->disappearance_chance = p->disappearance_chance; - for (i = 0; i < p->disappearance_reqs_count; i++) { - requirement_vector_append(&pextra->disappearance_reqs, p->disappearance_reqs[i]); - } - fc_assert(pextra->disappearance_reqs.size == p->disappearance_reqs_count); + requirement_vector_copy(&pextra->disappearance_reqs, &p->disappearance_reqs); pextra->visibility_req = p->visibility_req; pextra->buildable = p->buildable; @@ -4345,17 +4313,13 @@ void handle_ruleset_base(const struct packet_ruleset_base *p) ****************************************************************************/ void handle_ruleset_road(const struct packet_ruleset_road *p) { - int i; struct road_type *proad = road_by_number(p->id); fc_assert_ret_msg(NULL != proad, "Bad road %d.", p->id); proad->gui_type = p->gui_type; - for (i = 0; i < p->first_reqs_count; i++) { - requirement_vector_append(&proad->first_reqs, p->first_reqs[i]); - } - fc_assert(proad->first_reqs.size == p->first_reqs_count); + requirement_vector_copy(&proad->first_reqs, &p->first_reqs); proad->move_cost = p->move_cost; proad->move_mode = p->move_mode; @@ -4377,16 +4341,12 @@ void handle_ruleset_road(const struct packet_ruleset_road *p) void handle_ruleset_goods(const struct packet_ruleset_goods *p) { struct goods_type *pgood = goods_by_number(p->id); - int i; fc_assert_ret_msg(NULL != pgood, "Bad goods %d.", p->id); names_set(&pgood->name, NULL, p->name, p->rule_name); - for (i = 0; i < p->reqs_count; i++) { - requirement_vector_append(&pgood->reqs, p->reqs[i]); - } - fc_assert(pgood->reqs.size == p->reqs_count); + requirement_vector_copy(&pgood->reqs, &p->reqs); pgood->from_pct = p->from_pct; pgood->to_pct = p->to_pct; @@ -4436,7 +4396,6 @@ void handle_ruleset_action_enabler(const struct packet_ruleset_action_enabler *p) { struct action_enabler *enabler; - int i; if (!action_id_exists(p->enabled_action)) { /* Non existing action */ @@ -4451,15 +4410,8 @@ handle_ruleset_action_enabler(const struct packet_ruleset_action_enabler *p) enabler->action = p->enabled_action; - for (i = 0; i < p->actor_reqs_count; i++) { - requirement_vector_append(&enabler->actor_reqs, p->actor_reqs[i]); - } - fc_assert(enabler->actor_reqs.size == p->actor_reqs_count); - - for (i = 0; i < p->target_reqs_count; i++) { - requirement_vector_append(&enabler->target_reqs, p->target_reqs[i]); - } - fc_assert(enabler->target_reqs.size == p->target_reqs_count); + requirement_vector_copy(&enabler->actor_reqs, &p->actor_reqs); + requirement_vector_copy(&enabler->target_reqs, &p->target_reqs); action_enabler_add(enabler); } @@ -4476,10 +4428,7 @@ void handle_ruleset_action_auto(const struct packet_ruleset_action_auto *p) auto_perf->cause = p->cause; - for (i = 0; i < p->reqs_count; i++) { - requirement_vector_append(&auto_perf->reqs, p->reqs[i]); - } - fc_assert(auto_perf->reqs.size == p->reqs_count); + requirement_vector_copy(&auto_perf->reqs, &p->reqs); for (i = 0; i < p->alternatives_count; i++) { auto_perf->alternatives[i] = p->alternatives[i]; @@ -4492,16 +4441,12 @@ void handle_ruleset_action_auto(const struct packet_ruleset_action_auto *p) void handle_ruleset_disaster(const struct packet_ruleset_disaster *p) { struct disaster_type *pdis = disaster_by_number(p->id); - int i; fc_assert_ret_msg(NULL != pdis, "Bad disaster %d.", p->id); names_set(&pdis->name, NULL, p->name, p->rule_name); - for (i = 0; i < p->reqs_count; i++) { - requirement_vector_append(&pdis->reqs, p->reqs[i]); - } - fc_assert(pdis->reqs.size == p->reqs_count); + requirement_vector_copy(&pdis->reqs, &p->reqs); pdis->frequency = p->frequency; @@ -4720,26 +4665,14 @@ void handle_ruleset_style(const struct packet_ruleset_style *p) void handle_ruleset_clause(const struct packet_ruleset_clause *p) { struct clause_info *info = clause_info_get(p->type); - int i; fc_assert_ret_msg(NULL != info, "Bad clause %d.", p->type); info->enabled = p->enabled; - for (i = 0; i < p->giver_reqs_count; i++) { - requirement_vector_append(&info->giver_reqs, p->giver_reqs[i]); - } - fc_assert(info->giver_reqs.size == p->giver_reqs_count); - - for (i = 0; i < p->receiver_reqs_count; i++) { - requirement_vector_append(&info->receiver_reqs, p->receiver_reqs[i]); - } - fc_assert(info->receiver_reqs.size == p->receiver_reqs_count); - - for (i = 0; i < p->either_reqs_count; i++) { - requirement_vector_append(&info->either_reqs, p->either_reqs[i]); - } - fc_assert(info->either_reqs.size == p->either_reqs_count); + requirement_vector_copy(&info->giver_reqs, &p->giver_reqs); + requirement_vector_copy(&info->receiver_reqs, &p->receiver_reqs); + requirement_vector_copy(&info->either_reqs, &p->either_reqs); } /************************************************************************//** @@ -4747,7 +4680,7 @@ void handle_ruleset_clause(const struct packet_ruleset_clause *p) ****************************************************************************/ void handle_ruleset_city(const struct packet_ruleset_city *packet) { - int id, j; + int id; struct citystyle *cs; id = packet->style_id; @@ -4755,11 +4688,7 @@ void handle_ruleset_city(const struct packet_ruleset_city *packet) "Bad citystyle %d.", id); cs = &city_styles[id]; - for (j = 0; j < packet->reqs_count; j++) { - requirement_vector_append(&cs->reqs, packet->reqs[j]); - } - fc_assert(cs->reqs.size == packet->reqs_count); - + requirement_vector_copy(&cs->reqs, &packet->reqs); names_set(&cs->name, NULL, packet->name, packet->rule_name); sz_strlcpy(cs->graphic, packet->graphic); sz_strlcpy(cs->graphic_alt, packet->graphic_alt); @@ -4773,7 +4702,7 @@ void handle_ruleset_city(const struct packet_ruleset_city *packet) ****************************************************************************/ void handle_ruleset_music(const struct packet_ruleset_music *packet) { - int id, j; + int id; struct music_style *pmus; id = packet->id; @@ -4782,11 +4711,7 @@ void handle_ruleset_music(const struct packet_ruleset_music *packet) pmus = music_style_by_number(id); - for (j = 0; j < packet->reqs_count; j++) { - requirement_vector_append(&pmus->reqs, packet->reqs[j]); - } - fc_assert(pmus->reqs.size == packet->reqs_count); - + requirement_vector_copy(&pmus->reqs, &packet->reqs); sz_strlcpy(pmus->music_peaceful, packet->music_peaceful); sz_strlcpy(pmus->music_combat, packet->music_combat); } @@ -4841,7 +4766,6 @@ void handle_ruleset_game(const struct packet_ruleset_game *packet) ****************************************************************************/ void handle_ruleset_specialist(const struct packet_ruleset_specialist *p) { - int j; struct specialist *s = specialist_by_number(p->id); fc_assert_ret_msg(NULL != s, "Bad specialist %d.", p->id); @@ -4851,12 +4775,7 @@ void handle_ruleset_specialist(const struct packet_ruleset_specialist *p) sz_strlcpy(s->graphic_str, p->graphic_str); sz_strlcpy(s->graphic_alt, p->graphic_alt); - - for (j = 0; j < p->reqs_count; j++) { - requirement_vector_append(&s->reqs, p->reqs[j]); - } - fc_assert(s->reqs.size == p->reqs_count); - + requirement_vector_copy(&s->reqs, &p->reqs); PACKET_STRVEC_EXTRACT(s->helptext, p->helptext); tileset_setup_specialist_type_default_set(tileset, p->id); diff --git a/common/effects.c b/common/effects.c index 2fad1a52e8..2ccbc52ce8 100644 --- a/common/effects.c +++ b/common/effects.c @@ -592,16 +592,15 @@ void recv_ruleset_effect(const struct packet_ruleset_effect *packet) { struct effect *peffect; struct multiplier *pmul; - int i; pmul = packet->has_multiplier ? multiplier_by_number(packet->multiplier) : NULL; peffect = effect_new(packet->effect_type, packet->effect_value, pmul); - for (i = 0; i < packet->reqs_count; i++) { - effect_req_append(peffect, packet->reqs[i]); - } - fc_assert(peffect->reqs.size == packet->reqs_count); + requirement_vector_iterate(&(packet->reqs), preq) { + effect_req_append(peffect, *preq); + } requirement_vector_iterate_end; + fc_assert(peffect->reqs.size == packet->reqs.size); } /**********************************************************************//** @@ -611,7 +610,6 @@ void send_ruleset_cache(struct conn_list *dest) { effect_list_iterate(ruleset_cache.tracker, peffect) { struct packet_ruleset_effect effect_packet; - int counter; effect_packet.effect_type = peffect->type; effect_packet.effect_value = peffect->value; @@ -623,11 +621,8 @@ void send_ruleset_cache(struct conn_list *dest) effect_packet.multiplier = 0; /* arbitrary */ } - counter = 0; - requirement_vector_iterate(&(peffect->reqs), req) { - effect_packet.reqs[counter++] = *req; - } requirement_vector_iterate_end; - effect_packet.reqs_count = counter; + /* Shallow-copy (borrow) requirement vector */ + effect_packet.reqs = peffect->reqs; lsend_packet_ruleset_effect(dest, &effect_packet); } effect_list_iterate_end; diff --git a/common/networking/packets.def b/common/networking/packets.def index f018715779..562616981e 100644 --- a/common/networking/packets.def +++ b/common/networking/packets.def @@ -1421,8 +1421,7 @@ PACKET_RULESET_UNIT = 140; sc, lsend UINT8 attack_strength; UINT8 defense_strength; MOVEFRAGS move_rate; - UINT8 build_reqs_count; - REQUIREMENT build_reqs[MAX_NUM_REQS:build_reqs_count]; + REQUIREMENT build_reqs[*]; UINT16 vision_radius_sq; UINT8 transport_capacity; UINT8 hp; @@ -1515,8 +1514,7 @@ PACKET_RULESET_SPECIALIST = 142; sc, lsend STRING graphic_str[MAX_LEN_NAME]; STRING graphic_alt[MAX_LEN_NAME]; - UINT8 reqs_count; - REQUIREMENT reqs[MAX_NUM_REQS:reqs_count]; + REQUIREMENT reqs[*]; STRVEC helptext; end @@ -1531,8 +1529,7 @@ end PACKET_RULESET_TECH = 144; sc, lsend TECH id; TECH root_req; - UINT8 research_reqs_count; - REQUIREMENT research_reqs[MAX_NUM_REQS:research_reqs_count]; + REQUIREMENT research_reqs[*]; UINT8 tclass; BOOL removed; BV_TECH_FLAGS flags; @@ -1561,8 +1558,7 @@ end PACKET_RULESET_GOVERNMENT = 145; sc, lsend GOVERNMENT id; - UINT8 reqs_count; - REQUIREMENT reqs[MAX_NUM_REQS:reqs_count]; + REQUIREMENT reqs[*]; STRING name[MAX_LEN_NAME]; STRING rule_name[MAX_LEN_NAME]; @@ -1659,8 +1655,7 @@ PACKET_RULESET_CITY = 149; sc, lsend STRING name[MAX_LEN_NAME]; STRING rule_name[MAX_LEN_NAME]; STRING citizens_graphic[MAX_LEN_NAME]; - UINT8 reqs_count; - REQUIREMENT reqs[MAX_NUM_REQS:reqs_count]; + REQUIREMENT reqs[*]; STRING graphic[MAX_LEN_NAME]; STRING graphic_alt[MAX_LEN_NAME]; end @@ -1673,10 +1668,7 @@ PACKET_RULESET_BUILDING = 150; sc, lsend STRING graphic_str[MAX_LEN_NAME]; STRING graphic_alt[MAX_LEN_NAME]; STRING graphic_alt2[MAX_LEN_NAME]; - UINT8 reqs_count; - REQUIREMENT reqs[MAX_NUM_REQS:reqs_count]; - UINT8 obs_count; - REQUIREMENT obs_reqs[MAX_NUM_REQS:obs_count]; + REQUIREMENT reqs[*], obs_reqs[*]; UINT16 build_cost; UINT8 upkeep, sabotage; BV_IMPR_FLAGS flags; @@ -1781,16 +1773,11 @@ PACKET_RULESET_EXTRA = 232; sc, lsend STRING rmact_gfx_alt2[MAX_LEN_NAME]; STRING graphic_str[MAX_LEN_NAME]; STRING graphic_alt[MAX_LEN_NAME]; - UINT8 reqs_count; - REQUIREMENT reqs[MAX_NUM_REQS:reqs_count]; - UINT8 rmreqs_count; - REQUIREMENT rmreqs[MAX_NUM_REQS:rmreqs_count]; + REQUIREMENT reqs[*], rmreqs[*]; UINT16 appearance_chance; - UINT8 appearance_reqs_count; - REQUIREMENT appearance_reqs[MAX_NUM_REQS:appearance_reqs_count]; + REQUIREMENT appearance_reqs[*]; UINT16 disappearance_chance; - UINT8 disappearance_reqs_count; - REQUIREMENT disappearance_reqs[MAX_NUM_REQS:disappearance_reqs_count]; + REQUIREMENT disappearance_reqs[*]; TECH visibility_req; BOOL buildable; BOOL generated; @@ -1828,8 +1815,7 @@ end PACKET_RULESET_ROAD = 220; sc, lsend UINT8 id; ROAD_GUI gui_type; - UINT8 first_reqs_count; - REQUIREMENT first_reqs[MAX_NUM_REQS:first_reqs_count]; + REQUIREMENT first_reqs[*]; SINT16 move_cost; # not MOVEFRAGS because -1 is valid MOVE_MODE move_mode; UINT16 tile_incr_const[O_LAST]; @@ -1844,8 +1830,7 @@ PACKET_RULESET_GOODS = 248; sc, lsend UINT8 id; STRING name[MAX_LEN_NAME]; STRING rule_name[MAX_LEN_NAME]; - UINT8 reqs_count; - REQUIREMENT reqs[MAX_NUM_REQS:reqs_count]; + REQUIREMENT reqs[*]; UINT16 from_pct; UINT16 to_pct; UINT16 onetime_pct; @@ -1857,8 +1842,7 @@ PACKET_RULESET_DISASTER = 224; sc, lsend UINT8 id; STRING name[MAX_LEN_NAME]; STRING rule_name[MAX_LEN_NAME]; - UINT8 reqs_count; - REQUIREMENT reqs[MAX_NUM_REQS:reqs_count]; + REQUIREMENT reqs[*]; UINT8 frequency; BV_DISASTER_EFFECTS effects; end @@ -1900,18 +1884,14 @@ end PACKET_RULESET_ACTION_ENABLER = 235; sc, lsend ACTION_ID enabled_action; - UINT8 actor_reqs_count; - REQUIREMENT actor_reqs[MAX_NUM_REQS:actor_reqs_count]; - UINT8 target_reqs_count; - REQUIREMENT target_reqs[MAX_NUM_REQS:target_reqs_count]; + REQUIREMENT actor_reqs[*], target_reqs[*]; end PACKET_RULESET_ACTION_AUTO = 252; sc, lsend UINT8 id; ACTION_AUTO_CAUSE cause; - UINT8 reqs_count; - REQUIREMENT reqs[MAX_NUM_REQS:reqs_count]; + REQUIREMENT reqs[*]; UINT8 alternatives_count; ACTION_ID alternatives[MAX_NUM_ACTIONS:alternatives_count]; @@ -1931,11 +1911,10 @@ PACKET_RULESET_MUSIC = 240; sc, lsend UINT8 id; STRING music_peaceful[MAX_LEN_NAME]; STRING music_combat[MAX_LEN_NAME]; - UINT8 reqs_count; - REQUIREMENT reqs[MAX_NUM_REQS:reqs_count]; + REQUIREMENT reqs[*]; end -PACKET_RULESET_MULTIPLIER = 243; sc, dsend, lsend +PACKET_RULESET_MULTIPLIER = 243; sc, lsend MULTIPLIER id; SINT32 start; SINT32 stop; @@ -1946,20 +1925,14 @@ PACKET_RULESET_MULTIPLIER = 243; sc, dsend, lsend UINT16 minimum_turns; STRING name[MAX_LEN_NAME]; STRING rule_name[MAX_LEN_NAME]; - UINT8 reqs_count; - REQUIREMENT reqs[MAX_NUM_REQS:reqs_count]; + REQUIREMENT reqs[*]; STRVEC helptext; end PACKET_RULESET_CLAUSE = 512; sc, lsend CLAUSE type; BOOL enabled; - UINT8 giver_reqs_count; - REQUIREMENT giver_reqs[MAX_NUM_REQS:giver_reqs_count]; - UINT8 receiver_reqs_count; - REQUIREMENT receiver_reqs[MAX_NUM_REQS:receiver_reqs_count]; - UINT8 either_reqs_count; - REQUIREMENT either_reqs[MAX_NUM_REQS:either_reqs_count]; + REQUIREMENT giver_reqs[*], receiver_reqs[*], either_reqs[*]; end /************************************************************************** @@ -2128,8 +2101,7 @@ PACKET_RULESET_EFFECT = 175; sc, lsend BOOL has_multiplier; MULTIPLIER multiplier; - UINT8 reqs_count; - REQUIREMENT reqs[MAX_NUM_REQS:reqs_count]; + REQUIREMENT reqs[*]; end PACKET_RULESET_RESOURCE = 177; sc, lsend diff --git a/server/ruleset/ruleload.c b/server/ruleset/ruleload.c index dbd52e1983..b45acf9914 100644 --- a/server/ruleset/ruleload.c +++ b/server/ruleset/ruleload.c @@ -7987,11 +7987,8 @@ static void send_ruleset_units(struct conn_list *dest) packet.defense_strength = u->defense_strength; packet.move_rate = u->move_rate; - i = 0; - requirement_vector_iterate(&u->build_reqs, req) { - packet.build_reqs[i++] = *req; - } requirement_vector_iterate_end; - packet.build_reqs_count = i; + /* Shallow-copy (borrow) requirement vector */ + packet.build_reqs = u->build_reqs; packet.vision_radius_sq = u->vision_radius_sq; packet.transport_capacity = u->transport_capacity; @@ -8082,7 +8079,6 @@ static void send_ruleset_specialists(struct conn_list *dest) specialist_type_iterate(spec_id) { struct specialist *s = specialist_by_number(spec_id); - int j; packet.id = spec_id; sz_strlcpy(packet.plural_name, untranslated_name(&s->name)); @@ -8090,11 +8086,9 @@ static void send_ruleset_specialists(struct conn_list *dest) sz_strlcpy(packet.short_name, untranslated_name(&s->abbreviation)); sz_strlcpy(packet.graphic_str, s->graphic_str); sz_strlcpy(packet.graphic_alt, s->graphic_alt); - j = 0; - requirement_vector_iterate(&s->reqs, preq) { - packet.reqs[j++] = *preq; - } requirement_vector_iterate_end; - packet.reqs_count = j; + + /* Shallow-copy (borrow) requirement vector */ + packet.reqs = s->reqs; PACKET_STRVEC_INSERT(packet.helptext, s->helptext); @@ -8151,6 +8145,11 @@ static void send_ruleset_techs(struct conn_list *dest) lsend_packet_ruleset_tech_flag(dest, &fpacket); } + /* Since we have to prepend the tech requirements to the requirement + * vector, we need to initialize a separate vector and deep-copy the + * other requirements into it. */ + requirement_vector_init(&packet.research_reqs); + advance_iterate(a) { packet.id = advance_number(a); packet.removed = !valid_advance(a); @@ -8164,8 +8163,8 @@ static void send_ruleset_techs(struct conn_list *dest) sz_strlcpy(packet.graphic_str, a->graphic_str); sz_strlcpy(packet.graphic_alt, a->graphic_alt); - /* Current size of the packet's research_reqs requirement vector. */ - i = 0; + /* Reset requirement vector. */ + requirement_vector_reserve(&packet.research_reqs, 0); /* The requirements req1 and req2 are needed to research a tech. Send * them in the research_reqs requirement vector. Range is set to player @@ -8173,30 +8172,28 @@ static void send_ruleset_techs(struct conn_list *dest) if ((a->require[AR_ONE] != A_NEVER) && advance_number(a->require[AR_ONE]) > A_NONE) { - packet.research_reqs[i++] + struct requirement req = req_from_values(VUT_ADVANCE, REQ_RANGE_PLAYER, FALSE, TRUE, FALSE, advance_number(a->require[AR_ONE])); + requirement_vector_append(&packet.research_reqs, req); } if ((a->require[AR_TWO] != A_NEVER) && advance_number(a->require[AR_TWO]) > A_NONE) { - packet.research_reqs[i++] + struct requirement req = req_from_values(VUT_ADVANCE, REQ_RANGE_PLAYER, FALSE, TRUE, FALSE, advance_number(a->require[AR_TWO])); + requirement_vector_append(&packet.research_reqs, req); } /* The requirements of the tech's research_reqs also goes in the * packet's research_reqs requirement vector. */ requirement_vector_iterate(&a->research_reqs, req) { - packet.research_reqs[i++] = *req; + requirement_vector_append(&packet.research_reqs, *req); } requirement_vector_iterate_end; - /* The packet's research_reqs should contain req1, req2 and the - * requirements of the tech's research_reqs. */ - packet.research_reqs_count = i; - packet.root_req = a->require[AR_ROOT] ? advance_number(a->require[AR_ROOT]) : advance_count(); @@ -8208,6 +8205,8 @@ static void send_ruleset_techs(struct conn_list *dest) lsend_packet_ruleset_tech(dest, &packet); } advance_iterate_end; + + requirement_vector_free(&packet.research_reqs); } /**********************************************************************//** @@ -8264,7 +8263,6 @@ static void send_ruleset_buildings(struct conn_list *dest) improvement_iterate(b) { struct packet_ruleset_building packet; - int j; packet.id = improvement_number(b); packet.genus = b->genus; @@ -8273,16 +8271,11 @@ static void send_ruleset_buildings(struct conn_list *dest) sz_strlcpy(packet.graphic_str, b->graphic_str); sz_strlcpy(packet.graphic_alt, b->graphic_alt); sz_strlcpy(packet.graphic_alt2, b->graphic_alt2); - j = 0; - requirement_vector_iterate(&b->reqs, preq) { - packet.reqs[j++] = *preq; - } requirement_vector_iterate_end; - packet.reqs_count = j; - j = 0; - requirement_vector_iterate(&b->obsolete_by, pobs) { - packet.obs_reqs[j++] = *pobs; - } requirement_vector_iterate_end; - packet.obs_count = j; + + /* Shallow-copy (borrow) requirement vectors */ + packet.reqs = b->reqs; + packet.obs_reqs = b->obsolete_by; + packet.build_cost = b->build_cost; packet.upkeep = b->upkeep; packet.sabotage = b->sabotage; @@ -8487,31 +8480,17 @@ static void send_ruleset_extras(struct conn_list *dest) sz_strlcpy(packet.graphic_str, e->graphic_str); sz_strlcpy(packet.graphic_alt, e->graphic_alt); - j = 0; - requirement_vector_iterate(&e->reqs, preq) { - packet.reqs[j++] = *preq; - } requirement_vector_iterate_end; - packet.reqs_count = j; - - j = 0; - requirement_vector_iterate(&e->rmreqs, preq) { - packet.rmreqs[j++] = *preq; - } requirement_vector_iterate_end; - packet.rmreqs_count = j; + /* Shallow-copy (borrow) requirement vectors */ + packet.reqs = e->reqs; + packet.rmreqs = e->rmreqs; packet.appearance_chance = e->appearance_chance; - j = 0; - requirement_vector_iterate(&e->appearance_reqs, preq) { - packet.appearance_reqs[j++] = *preq; - } requirement_vector_iterate_end; - packet.appearance_reqs_count = j; + /* Shallow-copy (borrow) requirement vector */ + packet.appearance_reqs = e->appearance_reqs; packet.disappearance_chance = e->disappearance_chance; - j = 0; - requirement_vector_iterate(&e->disappearance_reqs, preq) { - packet.disappearance_reqs[j++] = *preq; - } requirement_vector_iterate_end; - packet.disappearance_reqs_count = j; + /* Shallow-copy (borrow) requirement vector */ + packet.disappearance_reqs = e->disappearance_reqs; packet.visibility_req = e->visibility_req; packet.buildable = e->buildable; @@ -8570,17 +8549,13 @@ static void send_ruleset_roads(struct conn_list *dest) extra_type_by_cause_iterate(EC_ROAD, pextra) { struct road_type *r = extra_road_get(pextra); - int j; packet.id = road_number(r); packet.gui_type = r->gui_type; - j = 0; - requirement_vector_iterate(&r->first_reqs, preq) { - packet.first_reqs[j++] = *preq; - } requirement_vector_iterate_end; - packet.first_reqs_count = j; + /* Shallow-copy (borrow) requirement vector */ + packet.first_reqs = r->first_reqs; packet.move_cost = r->move_cost; packet.move_mode = r->move_mode; @@ -8609,17 +8584,12 @@ static void send_ruleset_goods(struct conn_list *dest) struct packet_ruleset_goods packet; goods_type_iterate(g) { - int j; - packet.id = goods_number(g); sz_strlcpy(packet.name, untranslated_name(&g->name)); sz_strlcpy(packet.rule_name, rule_name_get(&g->name)); - j = 0; - requirement_vector_iterate(&g->reqs, preq) { - packet.reqs[j++] = *preq; - } requirement_vector_iterate_end; - packet.reqs_count = j; + /* Shallow-copy (borrow) requirement vector */ + packet.reqs = g->reqs; packet.from_pct = g->from_pct; packet.to_pct = g->to_pct; @@ -8641,18 +8611,13 @@ static void send_ruleset_disasters(struct conn_list *dest) struct packet_ruleset_disaster packet; disaster_type_iterate(d) { - int j; - packet.id = disaster_number(d); sz_strlcpy(packet.name, untranslated_name(&d->name)); sz_strlcpy(packet.rule_name, rule_name_get(&d->name)); - j = 0; - requirement_vector_iterate(&d->reqs, preq) { - packet.reqs[j++] = *preq; - } requirement_vector_iterate_end; - packet.reqs_count = j; + /* Shallow-copy (borrow) requirement vector */ + packet.reqs = d->reqs; packet.frequency = d->frequency; @@ -8719,23 +8684,14 @@ static void send_ruleset_actions(struct conn_list *dest) **************************************************************************/ static void send_ruleset_action_enablers(struct conn_list *dest) { - int counter; struct packet_ruleset_action_enabler packet; action_enablers_iterate(enabler) { packet.enabled_action = enabler_get_action_id(enabler); - counter = 0; - requirement_vector_iterate(&enabler->actor_reqs, req) { - packet.actor_reqs[counter++] = *req; - } requirement_vector_iterate_end; - packet.actor_reqs_count = counter; - - counter = 0; - requirement_vector_iterate(&enabler->target_reqs, req) { - packet.target_reqs[counter++] = *req; - } requirement_vector_iterate_end; - packet.target_reqs_count = counter; + /* Shallow-copy (borrow) requirement vectors */ + packet.actor_reqs = enabler->actor_reqs; + packet.target_reqs = enabler->target_reqs; lsend_packet_ruleset_action_enabler(dest, &packet); } action_enablers_iterate_end; @@ -8757,11 +8713,8 @@ static void send_ruleset_action_auto_performers(struct conn_list *dest) packet.cause = aperf->cause; - counter = 0; - requirement_vector_iterate(&aperf->reqs, req) { - packet.reqs[counter++] = *req; - } requirement_vector_iterate_end; - packet.reqs_count = counter; + /* Shallow-copy (borrow) requirement vector */ + packet.reqs = aperf->reqs; for (counter = 0; /* Can't list more actions than all actions. */ @@ -8806,17 +8759,13 @@ static void send_ruleset_governments(struct conn_list *dest) { struct packet_ruleset_government gov; struct packet_ruleset_government_ruler_title title; - int j; governments_iterate(g) { /* send one packet_government */ gov.id = government_number(g); - j = 0; - requirement_vector_iterate(&g->reqs, preq) { - gov.reqs[j++] = *preq; - } requirement_vector_iterate_end; - gov.reqs_count = j; + /* Shallow-copy (borrow) requirement vector */ + gov.reqs = g->reqs; sz_strlcpy(gov.name, untranslated_name(&g->name)); sz_strlcpy(gov.rule_name, rule_name_get(&g->name)); @@ -8978,28 +8927,14 @@ static void send_ruleset_clauses(struct conn_list *dest) for (i = 0; i < CLAUSE_COUNT; i++) { struct clause_info *info = clause_info_get(i); - int j; packet.type = i; packet.enabled = info->enabled; - j = 0; - requirement_vector_iterate(&info->giver_reqs, preq) { - packet.giver_reqs[j++] = *preq; - } requirement_vector_iterate_end; - packet.giver_reqs_count = j; - - j = 0; - requirement_vector_iterate(&info->receiver_reqs, preq) { - packet.receiver_reqs[j++] = *preq; - } requirement_vector_iterate_end; - packet.receiver_reqs_count = j; - - j = 0; - requirement_vector_iterate(&info->either_reqs, preq) { - packet.either_reqs[j++] = *preq; - } requirement_vector_iterate_end; - packet.either_reqs_count = j; + /* Shallow-copy (borrow) requirement vectors */ + packet.giver_reqs = info->giver_reqs; + packet.receiver_reqs = info->receiver_reqs; + packet.either_reqs = info->either_reqs; lsend_packet_ruleset_clause(dest, &packet); } @@ -9012,7 +8947,6 @@ static void send_ruleset_clauses(struct conn_list *dest) static void send_ruleset_multipliers(struct conn_list *dest) { multipliers_iterate(pmul) { - int j; struct packet_ruleset_multiplier packet; packet.id = multiplier_number(pmul); @@ -9027,11 +8961,8 @@ static void send_ruleset_multipliers(struct conn_list *dest) sz_strlcpy(packet.name, untranslated_name(&pmul->name)); sz_strlcpy(packet.rule_name, rule_name_get(&pmul->name)); - j = 0; - requirement_vector_iterate(&pmul->reqs, preq) { - packet.reqs[j++] = *preq; - } requirement_vector_iterate_end; - packet.reqs_count = j; + /* Shallow-copy (borrow) requirement vector */ + packet.reqs = pmul->reqs; PACKET_STRVEC_INSERT(packet.helptext, pmul->helptext); @@ -9046,16 +8977,13 @@ static void send_ruleset_multipliers(struct conn_list *dest) static void send_ruleset_cities(struct conn_list *dest) { struct packet_ruleset_city city_p; - int k, j; + int k; for (k = 0; k < game.control.num_city_styles; k++) { city_p.style_id = k; - j = 0; - requirement_vector_iterate(&city_styles[k].reqs, preq) { - city_p.reqs[j++] = *preq; - } requirement_vector_iterate_end; - city_p.reqs_count = j; + /* Shallow-copy (borrow) requirement vector */ + city_p.reqs = city_styles[k].reqs; sz_strlcpy(city_p.name, untranslated_name(&city_styles[k].name)); sz_strlcpy(city_p.rule_name, rule_name_get(&city_styles[k].name)); @@ -9076,18 +9004,13 @@ static void send_ruleset_musics(struct conn_list *dest) struct packet_ruleset_music packet; music_styles_iterate(pmus) { - int j; - packet.id = pmus->id; sz_strlcpy(packet.music_peaceful, pmus->music_peaceful); sz_strlcpy(packet.music_combat, pmus->music_combat); - j = 0; - requirement_vector_iterate(&(pmus->reqs), preq) { - packet.reqs[j++] = *preq; - } requirement_vector_iterate_end; - packet.reqs_count = j; + /* Shallow-copy (borrow) requirement vector */ + packet.reqs = pmus->reqs; lsend_packet_ruleset_music(dest, &packet); } music_styles_iterate_end; -- 2.34.1