diff client/civclient.c client/civclient.c --- client/civclient.c Tue Aug 22 05:48:39 2000 +++ client/civclient.c Tue Aug 22 05:54:44 2000 @@ -237,6 +237,10 @@ handle_city_info((struct packet_city_info *)packet); break; + case PACKET_SHORT_CITY: + handle_short_city((struct packet_short_city *)packet); + break; + case PACKET_REMOVE_UNIT: handle_remove_unit((struct packet_generic_integer *)packet); break; diff client/packhand.c client/packhand.c --- client/packhand.c Tue Aug 22 05:48:39 2000 +++ client/packhand.c Tue Aug 22 05:54:44 2000 @@ -66,6 +66,9 @@ extern char name[512]; +static void handle_city_packet_common(struct city *pcity, int is_new, + int popup); + /************************************************************************** ... **************************************************************************/ @@ -225,6 +228,7 @@ { int i, x, y, city_is_new; struct city *pcity; + int popup; pcity=find_city_by_id(packet->id); @@ -317,12 +321,26 @@ for(i=0; iimprovements[i]=(packet->improvements[i]=='1') ? 1 : 0; - - if(city_is_new) { + + popup = (city_is_new && get_client_state()==CLIENT_GAME_RUNNING_STATE && + pcity->owner==game.player_idx) || packet->diplomat_investigate; + + handle_city_packet_common(pcity, city_is_new, popup); +} + +/************************************************************************** + ... +**************************************************************************/ +static void handle_city_packet_common(struct city *pcity, int is_new, + int popup) +{ + int i; + + if(is_new) { unit_list_init(&pcity->units_supported); unit_list_init(&pcity->info_units_supported); unit_list_init(&pcity->info_units_present); - city_list_insert(&game.players[packet->owner].cities, pcity); + city_list_insert(&game.players[pcity->owner].cities, pcity); map_set_city(pcity->x, pcity->y, pcity); if(pcity->owner==game.player_idx) city_report_dialog_update(); @@ -336,7 +354,7 @@ } if(draw_map_grid && - city_is_new && get_client_state()==CLIENT_GAME_RUNNING_STATE) { + is_new && get_client_state()==CLIENT_GAME_RUNNING_STATE) { /* just to update grid; slow, but doesn't happen very often --jjm */ int r=((CITY_MAP_SIZE+1)/2); int d=(2*r)+1; @@ -357,14 +375,13 @@ city_workers_display=NULL; } - if(((city_is_new && get_client_state()==CLIENT_GAME_RUNNING_STATE && - pcity->owner==game.player_idx) || packet->diplomat_investigate) && + if( popup && (!game.player_ptr->ai.control || ai_popup_windows)) { update_menus(); popup_city_dialog(pcity, 0); } - if(!city_is_new && pcity->owner==game.player_idx) { + if(!is_new && pcity->owner==game.player_idx) { struct unit *punit = get_unit_in_focus(); if (punit && (punit->x == pcity->x) && (punit->y == pcity->y)) { update_menus(); @@ -372,11 +389,112 @@ refresh_city_dialog(pcity); } - if(city_is_new) { + if(is_new) { freelog(LOG_DEBUG, "New %s city %s id %d (%d %d)", get_nation_name(city_owner(pcity)->nation), pcity->name, pcity->id, pcity->x, pcity->y); } +} + +/************************************************************************** +... +**************************************************************************/ +void handle_short_city(struct packet_short_city *packet) +{ + struct city *pcity; + int city_is_new; + + pcity=find_city_by_id(packet->id); + + if (pcity && (pcity->owner != packet->owner)) { + /* With current server, this shouldn't happen: when city changes + * owner it is re-created with a new id. Unclear what to do here; + * try to cope... + */ + freelog(LOG_ERROR, + "Got existing city id (%d %s) with wrong owner (%d %s, old %d %s)", + packet->id, pcity->name, packet->owner, + get_player(packet->owner)->name, pcity->owner, + get_player(pcity->owner)->name); + client_remove_city(pcity); + pcity = 0; + } + + if(!pcity) { + city_is_new=1; + pcity=fc_malloc(sizeof(struct city)); + pcity->id=packet->id; + idex_register_city(pcity); + } + else { + city_is_new=0; + assert(pcity->id == packet->id); + } + + pcity->owner=packet->owner; + pcity->x=packet->x; + pcity->y=packet->y; + sz_strlcpy(pcity->name, packet->name); + + pcity->size=packet->size; + + if (packet->happy) { + pcity->ppl_happy[4] = pcity->size; + pcity->ppl_unhappy[4] = 0; + } else { + pcity->ppl_unhappy[4] = pcity->size; + pcity->ppl_happy[4] = 0; + } + + pcity->improvements[B_PALACE] = packet->capital; + pcity->improvements[B_CITY] = packet->walls; + + if (city_is_new) + pcity->worklist = create_worklist(); + + /* This sets dumb values for everything else. This is not really required, + but just want to be at the safe side. */ + { + int i; + int x, y; + + pcity->ppl_elvis = pcity->size; + pcity->ppl_scientist = 0; + pcity->ppl_taxman = 0; + for (i=0;i<4;i++) { + pcity->trade[i]=0; + pcity->trade_value[i] = 0; + } + pcity->food_prod = 0; + pcity->food_surplus = 0; + pcity->shield_prod = 0; + pcity->shield_surplus = 0; + pcity->trade_prod = 0; + pcity->corruption = 0; + pcity->luxury_total = 0; + pcity->tax_total = 0; + pcity->science_total = 0; + pcity->food_stock = 0; + pcity->shield_stock = 0; + pcity->pollution = 0; + pcity->city_options = 0; + pcity->is_building_unit = 0; + pcity->currently_building = 0; + init_worklist(pcity->worklist); + pcity->airlift = 0; + pcity->did_buy = 0; + pcity->did_sell = 0; + pcity->was_happy = 0; + for(i=0; iimprovements[i] = 0; + } + for(y=0; ycity_map[x][y] = C_TILE_EMPTY; + } /* Dumb values */ + + handle_city_packet_common(pcity, city_is_new, 0); } /************************************************************************** diff client/packhand.h client/packhand.h --- client/packhand.h Tue Aug 22 05:48:39 2000 +++ client/packhand.h Tue Aug 22 05:54:44 2000 @@ -37,6 +37,7 @@ void handle_move_unit(struct packet_move_unit *packet); void handle_new_year(struct packet_new_year *ppacket); void handle_city_info(struct packet_city_info *packet); +void handle_short_city(struct packet_short_city *packet); void handle_unit_combat(struct packet_unit_combat *packet); void handle_game_state(struct packet_generic_integer *packet); void handle_nuke_tile(struct packet_nuke_tile *packet); diff common/capstr.c common/capstr.c --- common/capstr.c Tue Aug 22 05:48:39 2000 +++ common/capstr.c Tue Aug 22 05:54:44 2000 @@ -72,7 +72,7 @@ #define CAPABILITY "+1.11 diplomat_investigate_fix production_change_fix" \ " game_ruleset nuclear_fallout land_channel_requirement event_wonder_obsolete" \ -" event00_fix conn_info gen_impr_oversights" +" event00_fix conn_info gen_impr_oversights packet_short_city" /* "+1.11" is protocol for 1.11.0 stable release. @@ -107,6 +107,9 @@ "gen_impr_oversights" extends the protocol to include information which addresses a few oversights in the original design. + + "packet_short_city" is smaller packet often sent instead of + packet_city_info. */ void init_our_capability(void) diff common/packets.c common/packets.c --- common/packets.c Tue Aug 22 05:48:40 2000 +++ common/packets.c Tue Aug 22 05:55:12 2000 @@ -209,9 +209,12 @@ case PACKET_UNIT_INFO: return receive_packet_unit_info(pc); - case PACKET_CITY_INFO: + case PACKET_CITY_INFO: return receive_packet_city_info(pc); + case PACKET_SHORT_CITY: + return receive_packet_short_city(pc); + case PACKET_MOVE_UNIT: return receive_packet_move_unit(pc); @@ -2257,6 +2260,130 @@ iget_uint8(&iter, &packet->trade_value[data]); } for(;data<4;data++) packet->trade_value[data]=packet->trade[data]=0; + + pack_iter_end(&iter, pc); + remove_packet_from_buffer(pc->buffer); + return packet; +} + +/************************************************************************* +... +**************************************************************************/ +int send_packet_short_city(struct connection *pc, struct packet_short_city *req) +{ + unsigned char buffer[MAX_LEN_PACKET], *cptr; + int i; + + + if (pc && !has_capability("packet_short_city", pc->capability)) { + + /* Send packet_city_info instead. */ + struct packet_city_info old; + char *p; + int x, y; + + old.id = req->id; + old.owner = req->owner; + old.x = req->x; + old.y = req->y; + sz_strlcpy(old.name, req->name); + old.size = req->size; + old.ppl_happy = 0; + if (req->happy) { + old.ppl_content = req->size; + old.ppl_unhappy = 0; + } else { + old.ppl_content = 0; + old.ppl_unhappy = req->size; + } + old.ppl_elvis = req->size; + old.ppl_scientist = 0; + old.ppl_taxman = 0; + for (i=0;i<4;i++) { + old.trade[i]=0; + old.trade_value[i] = 0; + } + old.food_prod = 0; + old.food_surplus = 0; + old.shield_prod = 0; + old.shield_surplus = 0; + old.trade_prod = 0; + old.corruption = 0; + old.luxury_total = 0; + old.tax_total = 0; + old.science_total = 0; + old.food_stock = 0; + old.shield_stock = 0; + old.pollution = 0; + old.city_options = 0; + old.is_building_unit = 0; + old.currently_building = 0; + init_worklist(&old.worklist); + old.diplomat_investigate = 0; + old.airlift = 0; + old.did_buy = 0; + old.did_sell = 0; + old.was_happy = 0; + + p=old.improvements; + for(i=0; icapital) + old.improvements[B_PALACE] = '1'; + if (req->walls) + old.improvements[B_CITY] = '1'; + + p=old.city_map; + for(y=0; yid); + cptr=put_uint8(cptr, req->owner); + cptr=put_uint8(cptr, req->x); + cptr=put_uint8(cptr, req->y); + cptr=put_string(cptr, req->name); + + cptr=put_uint8(cptr, req->size); + cptr=put_uint8(cptr, req->happy); + cptr=put_uint8(cptr, req->capital); + cptr=put_uint8(cptr, req->walls); + + put_uint16(buffer, cptr-buffer); + + return send_connection_data(pc, buffer, cptr-buffer); +} + + +/************************************************************************* +... +**************************************************************************/ +struct packet_short_city * +receive_packet_short_city(struct connection *pc) +{ + struct pack_iter iter; + struct packet_short_city *packet= + fc_malloc(sizeof(struct packet_short_city)); + + pack_iter_init(&iter, pc); + + iget_uint16(&iter, &packet->id); + iget_uint8(&iter, &packet->owner); + iget_uint8(&iter, &packet->x); + iget_uint8(&iter, &packet->y); + iget_string(&iter, packet->name, sizeof(packet->name)); + + iget_uint8(&iter, &packet->size); + iget_uint8(&iter, &packet->happy); + iget_uint8(&iter, &packet->capital); + iget_uint8(&iter, &packet->walls); pack_iter_end(&iter, pc); remove_packet_from_buffer(pc->buffer); diff common/packets.h common/packets.h --- common/packets.h Tue Aug 22 05:48:40 2000 +++ common/packets.h Tue Aug 22 05:54:44 2000 @@ -111,6 +111,7 @@ PACKET_ADVANCE_FOCUS, PACKET_RULESET_GAME, PACKET_CONN_INFO, + PACKET_SHORT_CITY, PACKET_LAST /* leave this last */ }; @@ -356,6 +357,17 @@ }; +struct packet_short_city { + int id; + int owner; + int x, y; + char name[MAX_LEN_NAME]; + int size; + int happy; + int capital; + int walls; +}; + /********************************************************* this packet is the very first packet send by the client. @@ -917,6 +929,9 @@ int send_packet_city_info(struct connection *pc,struct packet_city_info *req); struct packet_city_info *receive_packet_city_info(struct connection *pc); + +int send_packet_short_city(struct connection *pc,struct packet_short_city *req); +struct packet_short_city *receive_packet_short_city(struct connection *pc); int send_packet_city_request(struct connection *pc, struct packet_city_request *packet, diff common/packets_lsend.c common/packets_lsend.c --- common/packets_lsend.c Tue Aug 22 05:48:40 2000 +++ common/packets_lsend.c Tue Aug 22 05:54:44 2000 @@ -168,6 +168,13 @@ conn_list_iterate_end; } +void lsend_packet_short_city(struct conn_list *dest,struct packet_short_city *req) +{ + conn_list_iterate(*dest, pconn) + send_packet_short_city(pconn, req); + conn_list_iterate_end; +} + void lsend_packet_city_request(struct conn_list *dest, struct packet_city_request *packet, enum packet_type req_type) diff common/packets_lsend.h common/packets_lsend.h --- common/packets_lsend.h Tue Aug 22 05:48:40 2000 +++ common/packets_lsend.h Tue Aug 22 05:54:44 2000 @@ -53,6 +53,7 @@ void lsend_packet_generic_integer(struct conn_list *dest, int type, struct packet_generic_integer *packet); void lsend_packet_city_info(struct conn_list *dest,struct packet_city_info *req); +void lsend_packet_short_city(struct conn_list *dest,struct packet_short_city *req); void lsend_packet_city_request(struct conn_list *dest, struct packet_city_request *packet, enum packet_type req_type); diff server/cityhand.c server/cityhand.c --- server/cityhand.c Tue Aug 22 05:48:40 2000 +++ server/cityhand.c Tue Aug 22 05:54:44 2000 @@ -51,7 +51,7 @@ #include "cityhand.h" static void package_dumb_city(struct player* pplayer, int x, int y, - struct packet_city_info *packet); + struct packet_short_city *packet); static void remove_trade_route(int c1, int c2); /************************************************************************** @@ -768,6 +768,7 @@ int o; struct player *powner = city_owner(pcity); struct packet_city_info packet; + struct packet_short_city sc_pack; /* nocity_send is used to inhibit sending cities to the owner between * turn updates @@ -784,8 +785,8 @@ if(pcity->owner==o) continue; /* already sent above */ if(map_get_known_and_seen(pcity->x, pcity->y, o)) { update_dumb_city(pplayer, pcity); - package_dumb_city(pplayer, pcity->x, pcity->y, &packet); - lsend_packet_city_info(&pplayer->connections, &packet); + package_dumb_city(pplayer, pcity->x, pcity->y, &sc_pack); + lsend_packet_short_city(&pplayer->connections, &sc_pack); } } /* send to non-player observers: @@ -840,6 +841,7 @@ { struct player *powner = NULL; struct packet_city_info packet; + struct packet_short_city sc_pack; struct dumb_city *pdcity; if (pcity==NULL) @@ -869,14 +871,14 @@ } else if (map_get_known_and_seen(x, y, pviewer->player_no)) { if (pcity) { /* it's there and we see it; update and send */ update_dumb_city(pviewer, pcity); - package_dumb_city(pviewer, x, y, &packet); - lsend_packet_city_info(dest, &packet); + package_dumb_city(pviewer, x, y, &sc_pack); + lsend_packet_short_city(dest, &sc_pack); } } else { /* not seen; send old info */ pdcity = map_get_player_tile(x, y, pviewer->player_no)->city; if (pdcity) { - package_dumb_city(pviewer, x, y, &packet); - lsend_packet_city_info(dest, &packet); + package_dumb_city(pviewer, x, y, &sc_pack); + lsend_packet_short_city(dest, &sc_pack); } } } @@ -1069,14 +1071,10 @@ /************************************************************************** This fills out a package from a players dumb_city. -FIXME: we should make a new package and let the client fill in the dummy -info itself **************************************************************************/ static void package_dumb_city(struct player* pplayer, int x, int y, - struct packet_city_info *packet) + struct packet_short_city *packet) { - int i; - char *p; struct dumb_city *pdcity = map_get_player_tile(x, y, pplayer->player_no)->city; struct city *pcity; packet->id=pdcity->id; @@ -1086,76 +1084,26 @@ sz_strlcpy(packet->name, pdcity->name); packet->size=pdcity->size; - packet->ppl_happy=0; if (map_get_known_and_seen(x, y, pplayer->player_no)) { /* Since the tile is visible the player can see the tile, and if it didn't actually have a city pdcity would be NULL */ pcity = map_get_tile(x,y)->city; if (pcity->ppl_happy[4]>=pcity->ppl_unhappy[4]) { - packet->ppl_content=pdcity->size; - packet->ppl_unhappy=0; + packet->happy=1; } else { - packet->ppl_content=0; - packet->ppl_unhappy=pdcity->size; + packet->happy=0; } } else { - packet->ppl_content=pdcity->size; - packet->ppl_unhappy=0; - } - packet->ppl_elvis=pdcity->size; - packet->ppl_scientist=0; - packet->ppl_taxman=0; - for (i=0;i<4;i++) { - packet->trade[i]=0; - packet->trade_value[i]=0; + packet->happy=1; } - packet->food_prod=0; - packet->food_surplus=0; - packet->shield_prod=0; - packet->shield_surplus=0; - packet->trade_prod=0; - packet->corruption=0; - - packet->luxury_total=0; - packet->tax_total=0; - packet->science_total=0; - - packet->food_stock=0; - packet->shield_stock=0; - packet->pollution=0; - - packet->city_options=0; - - packet->is_building_unit=0; - packet->currently_building=0; - init_worklist(&packet->worklist); - packet->diplomat_investigate=0; - - packet->airlift=0; - packet->did_buy=0; - packet->did_sell=0; - packet->was_happy=0; - - p=packet->improvements; - - for(i=0; iid == pdcity->id && city_got_building(pcity, B_PALACE)) - packet->improvements[B_PALACE] = '1'; - - if (pdcity->has_walls) - packet->improvements[B_CITY] = '1'; - - *p='\0'; + packet->capital=1; + else + packet->capital=0; - p=packet->city_map; - for(y=0; ywalls = pdcity->has_walls; } /**************************************************************************