<URL: http://bugs.freeciv.org/Ticket/Display.html?id=40084 >
Some of the preliminary steps toward the PR#40080 long-term goal. This patch mostly clears the decks for shorter-term crashing bug fixes. It includes some code already in 2.1 (PR#39980), used for initializing the game_identifier. Moved from game to server structure (it is server-only), and renamed to help distinguish from other "id".... Modified PR#40079, moving (and renaming) IDENTITY_NUMBER_ZERO to fc_types.h, instead of "0" initializing city and unit ids. Added access functions city_tile() and unit_tile(), renaming conflicting variable names.
Index: utility/shared.c =================================================================== --- utility/shared.c (revision 14385) +++ utility/shared.c (working copy) @@ -47,6 +47,7 @@ #include "fcintl.h" #include "log.h" #include "mem.h" +#include "rand.h" #include "support.h" #include "shared.h" @@ -79,6 +80,10 @@ static char *grouping = NULL; static char *grouping_sep = NULL; +static const char base64url[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; + + /*************************************************************** Take a string containing multiple lines and create a copy where each line is padded to the length of the longest line and centered. @@ -390,22 +395,15 @@ ****************************************************************************/ bool is_safe_filename(const char *name) { - int i; + int i = 0; /* must not be NULL or empty */ if (!name || *name == '\0') { return FALSE; } - /* Accept only alphanumerics and '-', '_', '.' The exception is if - * part of PARENT_DIR_OPERATOR is one of these, which is prohibited */ - for (i = 0; name[i]; i++) { - if (!((name[i] <= 'z' && name[i] >= 'a') - || (name[i] <= 'Z' && name[i] >= 'A') - || (name[i] <= '9' && name[i] >= '0') - || name[i] == '-' - || name[i] == '_' - || name[i] == '.')) { + for (; '\0' != name[i]; i++) { + if ('.' != name[i] && NULL == strchr(base64url, name[i])) { return FALSE; } } @@ -457,6 +455,45 @@ return TRUE; } +/************************************************************************* + Check for valid base64url. +*************************************************************************/ +bool is_base64url(const char *s) +{ + size_t i = 0; + + /* must not be NULL or empty */ + if (NULL == s || '\0' == *s) { + return FALSE; + } + + for (; '\0' != s[i]; i++) { + if (NULL == strchr(base64url, s[i])) { + return FALSE; + } + } + return TRUE; +} + +/************************************************************************* + generate a random string meeting criteria such as is_ascii_name(), + is_base64url(), and is_safe_filename(). +*************************************************************************/ +void randomize_base64url_string(char *s, size_t n) +{ + size_t i = 0; + + /* must not be NULL or too short */ + if (NULL == s || 1 > n) { + return; + } + + for (; i < (n - 1); i++) { + s[i] = base64url[myrand(sizeof(base64url) - 1)]; + } + s[i] = '\0'; +} + /*************************************************************** Produce a statically allocated textual representation of the given year. Index: utility/shared.h =================================================================== --- utility/shared.h (revision 14385) +++ utility/shared.h (working copy) @@ -25,8 +25,9 @@ #endif #endif +/* Changing these will break network compatability! */ #define MAX_LEN_ADDR 256 /* see also MAXHOSTNAMELEN and RFC 1123 2.1 */ -#define MAX_LEN_PATH 4095 +#define MAX_LEN_PATH 4095 /* Use FC_INFINITY to denote that a certain event will never occur or another unreachable condition. */ @@ -144,8 +145,11 @@ const char *int_to_text(unsigned int number); bool is_ascii_name(const char *name); +bool is_base64url(const char *s); bool is_safe_filename(const char *name); +void randomize_base64url_string(char *s, size_t n); const char *textyear(int year); + int compare_strings(const void *first, const void *second); int compare_strings_ptrs(const void *first, const void *second); Index: server/score.c =================================================================== --- server/score.c (revision 14385) +++ server/score.c (working copy) @@ -399,7 +399,7 @@ return; } - fprintf(fp, "P3\n# version:2\n# gameid: %s\n", game.id); + fprintf(fp, "P3\n# version:2\n# gameid: %s\n", server.game_identifier); fprintf(fp, "# An intermediate map from saved Freeciv game %s%+05d\n", game.save_name, game.info.year); Index: server/srv_main.c =================================================================== --- server/srv_main.c (revision 14385) +++ server/srv_main.c (working copy) @@ -1096,7 +1096,7 @@ } /************************************************************************** - Truncation of unsigned short wraps at 65K, skipping VISION_SITE_NONE (0) + Truncation of unsigned short wraps at 65K, skipping IDENTITY_NUMBER_ZERO Setup in server_game_init() **************************************************************************/ int identity_number(void) @@ -2140,10 +2140,10 @@ { /* was redundantly in game_load() */ server.nbarbarians = 0; - server.identity_number = IDENTITY_NUMBER_START; + server.identity_number = IDENTITY_NUMBER_SKIP; memset(identity_numbers_used, 0, sizeof(identity_numbers_used)); - identity_number_reserve(VISION_SITE_NONE); + identity_number_reserve(IDENTITY_NUMBER_ZERO); game_init(); } Index: server/srv_main.h =================================================================== --- server/srv_main.h (revision 14385) +++ server/srv_main.h (working copy) @@ -63,11 +63,13 @@ int nbarbarians; /* this counter creates all the city and unit numbers used. - * arbitrarily starts at 100, but at 65K wraps to 1. + * arbitrarily starts at 101, but at 65K wraps to 1. * use identity_number() */ -#define IDENTITY_NUMBER_START (100) +#define IDENTITY_NUMBER_SKIP (100) unsigned short identity_number; + + char game_identifier[MAX_LEN_GAME_IDENTIFIER]; } server; Index: server/report.c =================================================================== --- server/report.c (revision 14385) +++ server/report.c (working copy) @@ -38,6 +38,7 @@ #include "citytools.h" #include "report.h" #include "score.h" +#include "srv_main.h" static void page_conn_etype(struct conn_list *dest, const char *caption, const char *headline, const char *lines, @@ -854,10 +855,10 @@ freelog(LOG_ERROR, "Multiple ID entries!"); return FALSE; } - mystrlcpy(id, line + strlen("id "), MAX_ID_LEN); - if (strcmp(id, game.id) != 0) { + mystrlcpy(id, line + strlen("id "), MAX_LEN_GAME_IDENTIFIER); + if (strcmp(id, server.game_identifier) != 0) { freelog(LOG_ERROR, "IDs don't match! game='%s' scorelog='%s'", - game.id, id); + server.game_identifier, id); return FALSE; } } @@ -970,7 +971,7 @@ enum { SL_CREATE, SL_APPEND, SL_UNSPEC } oper = SL_UNSPEC; int i; - char id[MAX_ID_LEN]; + char id[MAX_LEN_GAME_IDENTIFIER]; if (!player_name_ptrs[0]) { int i; @@ -1017,7 +1018,7 @@ "# <http://svn.gna.org/viewcvs/freeciv/trunk/doc/README.scorelog?view=auto>.\n" "\n"); - fprintf(fp, "id %s\n", game.id); + fprintf(fp, "id %s\n", server.game_identifier); for (i = 0; i<ARRAY_SIZE(score_tags); i++) { fprintf(fp, "tag %d %s\n", i, score_tags[i].name); } Index: server/gamehand.c =================================================================== --- server/gamehand.c (revision 14385) +++ server/gamehand.c (working copy) @@ -44,21 +44,6 @@ /**************************************************************************** - Initialize the game.id variable to a random string of characters. -****************************************************************************/ -static void init_game_id(void) -{ - static const char chars[] = - "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - int i; - - for (i = 0; i < ARRAY_SIZE(game.id) - 1; i++) { - game.id[i] = chars[myrand(sizeof(chars) - 1)]; - } - game.id[i] = '\0'; -} - -/**************************************************************************** Get unit_type for given role character ****************************************************************************/ struct unit_type *crole_to_unit_type(char crole,struct player *pplayer) @@ -211,7 +196,8 @@ bool pos_used[map.num_start_positions]; int i, num_used = 0; - init_game_id(); + randomize_base64url_string(server.game_identifier, + sizeof(server.game_identifier)); /* Shuffle starting positions around so that they match up with the * desired players. */ Index: server/maphand.c =================================================================== --- server/maphand.c (revision 14385) +++ server/maphand.c (working copy) @@ -1204,7 +1204,7 @@ struct vision_site *psite = map_get_player_site(ptile, pplayer); if (NULL != psite && ptile == psite->location - && VISION_SITE_NONE < psite->identity) { + && IDENTITY_NUMBER_ZERO < psite->identity) { return psite; } return NULL; @@ -1814,13 +1814,13 @@ /* no borders */ return; } - if (VISION_SITE_NONE == psite->identity) { + if (IDENTITY_NUMBER_ZERO == psite->identity) { /* should never be called! */ freelog(LOG_ERROR, "Warning: border source (%d,%d) is unknown!", TILE_XY(ptile)); return; } - if (VISION_SITE_NONE < psite->identity) { + if (IDENTITY_NUMBER_ZERO < psite->identity) { /* city expansion */ range = MIN(psite->size + 1, game.info.borders); if (psite->size > game.info.borders) { @@ -1844,7 +1844,7 @@ int r = sq_map_distance(dsite->location, dtile); /* border tile claimed by another */ - if (VISION_SITE_NONE == dsite->identity) { + if (IDENTITY_NUMBER_ZERO == dsite->identity) { /* ruins don't keep their borders */ dsite->owner = powner; tile_set_owner(dtile, powner); Index: server/unittools.c =================================================================== --- server/unittools.c (revision 14385) +++ server/unittools.c (working copy) @@ -1377,12 +1377,12 @@ **************************************************************************/ static void server_remove_unit(struct unit *punit) { - struct city *pcity = tile_city(punit->tile); + struct tile *ptile = punit->tile; + struct city *pcity = tile_city(ptile); struct city *phomecity = game_find_city_by_number(punit->homecity); - struct tile *unit_tile = punit->tile; #ifndef NDEBUG - unit_list_iterate(punit->tile->units, pcargo) { + unit_list_iterate(ptile->units, pcargo) { assert(pcargo->transported_by != punit->id); } unit_list_iterate_end; #endif @@ -1399,7 +1399,7 @@ conn_list_iterate(game.est_connections, pconn) { if ((!pconn->player && pconn->observer) || (pconn->player - && map_is_known_and_seen(punit->tile, pconn->player, V_MAIN))) { + && map_is_known_and_seen(ptile, pconn->player, V_MAIN))) { /* FIXME: this sends the remove packet to all players, even those who * can't see the unit. This potentially allows some limited cheating. * However fixing it requires changes elsewhere since sometimes the @@ -1421,11 +1421,11 @@ /* check if this unit had F_GAMELOSS flag */ if (unit_has_type_flag(punit, F_GAMELOSS) && unit_owner(punit)->is_alive) { - notify_conn(game.est_connections, punit->tile, E_UNIT_LOST, + notify_conn(game.est_connections, ptile, E_UNIT_LOST, _("Unable to defend %s, %s has lost the game."), unit_name_translation(punit), player_name(unit_owner(punit))); - notify_player(unit_owner(punit), punit->tile, E_GAME_END, + notify_player(unit_owner(punit), ptile, E_GAME_END, _("Losing %s meant losing the game! " "Be more careful next time!"), unit_name_translation(punit)); @@ -1436,10 +1436,10 @@ punit = NULL; /* This unit may have blocked tiles of adjacent cities. Update them. */ - map_city_radius_iterate(unit_tile, ptile1) { + map_city_radius_iterate(ptile, ptile1) { struct city *pcity = tile_city(ptile1); if (pcity) { - update_city_tile_status_map(pcity, unit_tile); + update_city_tile_status_map(pcity, ptile); } } map_city_radius_iterate_end; sync_cities(); @@ -1452,7 +1452,7 @@ city_refresh(pcity); send_city_info(city_owner(pcity), pcity); } - if (pcity && unit_list_size(unit_tile->units) == 0) { + if (pcity && unit_list_size(ptile->units) == 0) { /* The last unit in the city was killed: update the occupied flag. */ send_city_info(NULL, pcity); } Index: server/savegame.c =================================================================== --- server/savegame.c (revision 14385) +++ server/savegame.c (working copy) @@ -2739,7 +2739,7 @@ struct vision_site *pdcity = fc_calloc(1, sizeof(*pdcity)); pdcity->identity = secfile_lookup_int(file, "player%d.dc%d.id", plrno, j); - if (VISION_SITE_NONE >= pdcity->identity) { + if (IDENTITY_NUMBER_ZERO >= pdcity->identity) { freelog(LOG_ERROR, "[player%d] dc%d has invalid id (%d); skipping.", plrno, j, pdcity->identity); free(pdcity); @@ -3776,8 +3776,14 @@ game.scorelog = secfile_lookup_bool_default(file, FALSE, "game.scorelog"); game.scoreturn = secfile_lookup_int_default(file, game.info.turn + GAME_DEFAULT_SCORETURN, - "game.scoreturn"); - sz_strlcpy(game.id, secfile_lookup_str_default(file, "", "game.id")); + "game.scoreturn"); + sz_strlcpy(server.game_identifier, + secfile_lookup_str_default(file, "", "game.id")); + if (0 == strlen(server.game_identifier) + || !is_base64url(server.game_identifier)) { + randomize_base64url_string(server.game_identifier, + sizeof(server.game_identifier)); + } game.info.fogofwar = secfile_lookup_bool_default(file, FALSE, "game.fogofwar"); game.fogofwar_old = game.info.fogofwar; @@ -4392,7 +4398,8 @@ secfile_insert_int(file, game.info.aifill, "game.aifill"); secfile_insert_bool(file, game.scorelog, "game.scorelog"); secfile_insert_int(file, game.scoreturn, "game.scoreturn"); - secfile_insert_str(file, game.id, "game.id"); + secfile_insert_str(file, server.game_identifier, "game.id"); + secfile_insert_bool(file, game.info.fogofwar, "game.fogofwar"); secfile_insert_bool(file, game.info.spacerace, "game.spacerace"); secfile_insert_bool(file, game.info.auto_ai_toggle, "game.auto_ai_toggle"); Index: common/unit.c =================================================================== --- common/unit.c (revision 14385) +++ common/unit.c (working copy) @@ -1120,14 +1120,26 @@ } /************************************************************************** - Return the unit's owner. + Return the owner of the unit. **************************************************************************/ struct player *unit_owner(const struct unit *punit) { + assert(NULL != punit); + assert(NULL != punit->owner); return punit->owner; } /************************************************************************** + Return the tile location of the unit. + Not (yet) always used, mostly for debugging. +**************************************************************************/ +struct tile *unit_tile(const struct unit *punit) +{ + assert(NULL != punit); + return punit->tile; +} + +/************************************************************************** Returns true if the tile contains an allied unit and only allied units. (ie, if your nation A is allied with B, and B is allied with C, a tile containing units from B and C will return false) @@ -1305,16 +1317,21 @@ { struct unit *punit = fc_calloc(1, sizeof(*punit)); + /* It does not register the unit so the id is set to 0. */ + punit->id = IDENTITY_NUMBER_ZERO; + CHECK_UNIT_TYPE(punittype); /* No untyped units! */ punit->utype = punittype; + assert(pplayer != NULL); /* No unowned units! */ punit->owner = pplayer; + if (pcity) { punit->tile = pcity->tile; punit->homecity = pcity->id; } else { punit->tile = NULL; - punit->homecity = 0; + punit->homecity = IDENTITY_NUMBER_ZERO; } punit->goto_tile = NULL; punit->veteran = veteran_level; Index: common/unit.h =================================================================== --- common/unit.h (revision 14385) +++ common/unit.h (working copy) @@ -137,7 +137,7 @@ }; struct unit { - struct unit_type *utype; + struct unit_type *utype; /* Cannot be NULL. */ struct tile *tile; struct player *owner; /* Cannot be NULL. */ int id; @@ -292,6 +292,7 @@ int get_transporter_capacity(const struct unit *punit); struct player *unit_owner(const struct unit *punit); +struct tile *unit_tile(const struct unit *punit); struct unit *is_allied_unit_tile(const struct tile *ptile, const struct player *pplayer); Index: common/city.c =================================================================== --- common/city.c (revision 14385) +++ common/city.c (working copy) @@ -95,10 +95,10 @@ center. Returns whether the map position is inside of the city map. **************************************************************************/ bool base_map_to_city_map(int *city_map_x, int *city_map_y, - const struct tile *city_tile, + const struct tile *city_center, const struct tile *map_tile) { - map_distance_vector(city_map_x, city_map_y, city_tile, map_tile); + map_distance_vector(city_map_x, city_map_y, city_center, map_tile); *city_map_x += CITY_MAP_RADIUS; *city_map_y += CITY_MAP_RADIUS; return is_valid_city_coords(*city_map_x, *city_map_y); @@ -119,14 +119,14 @@ Finds the map position for a given city map coordinate of a certain city. Returns true if the map position found is real. **************************************************************************/ -struct tile *base_city_map_to_map(const struct tile *city_tile, +struct tile *base_city_map_to_map(const struct tile *city_center, int city_map_x, int city_map_y) { int x, y; assert(is_valid_city_coords(city_map_x, city_map_y)); - x = city_tile->x + city_map_x - CITY_MAP_SIZE / 2; - y = city_tile->y + city_map_y - CITY_MAP_SIZE / 2; + x = city_center->x + city_map_x - CITY_MAP_SIZE / 2; + y = city_center->y + city_map_y - CITY_MAP_SIZE / 2; return map_pos_to_tile(x, y); } @@ -642,7 +642,7 @@ **************************************************************************/ const char *city_name(const struct city *pcity) { - assert(NULL != pcity && NULL != pcity->name); + assert(NULL != pcity); return pcity->name; } @@ -651,11 +651,22 @@ **************************************************************************/ struct player *city_owner(const struct city *pcity) { - assert(NULL != pcity && NULL != pcity->owner); + assert(NULL != pcity); + assert(NULL != pcity->owner); return pcity->owner; } /************************************************************************** + Return the tile location of the city. + Not (yet) always used, mostly for debugging. +**************************************************************************/ +struct tile *city_tile(const struct city *pcity) +{ + assert(NULL != pcity); + return pcity->tile; +} + +/************************************************************************** Returns how many thousand citizen live in this city. **************************************************************************/ int city_population(const struct city *pcity) @@ -2423,8 +2434,8 @@ } /************************************************************************** - Create virtual skeleton for a city. It does not register the city so - the id is set to 0. All other values are more or less sane defaults. + Create virtual skeleton for a city. + Values are mostly sane defaults. **************************************************************************/ struct city *create_city_virtual(struct player *pplayer, struct tile *ptile, const char *name) @@ -2432,12 +2443,16 @@ int i; struct city *pcity = fc_calloc(1, sizeof(*pcity)); - pcity->id = 0; + /* It does not register the city so the id is set to 0. */ + pcity->id = IDENTITY_NUMBER_ZERO; + assert(pplayer != NULL); /* No unowned cities! */ pcity->original = pplayer; pcity->owner = pplayer; + pcity->tile = ptile; sz_strlcpy(pcity->name, name); + #ifdef ZERO_VARIABLES_FOR_SEARCHING memset(pcity->feel, 0, sizeof(pcity->feel)); memset(pcity->specialists, 0, sizeof(pcity->specialists)); Index: common/city.h =================================================================== --- common/city.h (revision 14385) +++ common/city.h (working copy) @@ -110,9 +110,9 @@ * elements of [0,CITY_MAP_SIZE). mx and my will form the map position * (mx,my). */ -#define city_map_checked_iterate(city_tile, cx, cy, _tile) { \ +#define city_map_checked_iterate(_city_tile, cx, cy, _tile) { \ city_map_iterate_outwards(cx, cy) { \ - struct tile *_tile = base_city_map_to_map(city_tile, cx, cy); \ + struct tile *_tile = base_city_map_to_map(_city_tile, cx, cy); \ if (NULL != _tile) { #define city_map_checked_iterate_end \ @@ -122,9 +122,9 @@ /* Does the same thing as city_map_checked_iterate, but keeps the city * coordinates hidden. */ -#define map_city_radius_iterate(city_tile, _tile) \ +#define map_city_radius_iterate(_city_tile, _tile) \ { \ - city_map_checked_iterate(city_tile, _tile##_x, _tile##_y, _tile) { + city_map_checked_iterate(_city_tile, _tile##_x, _tile##_y, _tile) { #define map_city_radius_iterate_end \ } city_map_checked_iterate_end; \ @@ -408,6 +408,8 @@ const char *city_name(const struct city *pcity); struct player *city_owner(const struct city *pcity); +struct tile *city_tile(const struct city *pcity); + int city_population(const struct city *pcity); int city_unit_unhappiness(struct unit *punit, int *free_happy); void city_unit_upkeep(struct unit *punit, int *outputs, int *free_upkeep); @@ -482,10 +484,10 @@ const struct city *const pcity, const struct tile *ptile); bool base_map_to_city_map(int *city_map_x, int *city_map_y, - const struct tile *city_tile, + const struct tile *city_center, const struct tile *map_tile); -struct tile *base_city_map_to_map(const struct tile *city_center_tile, +struct tile *base_city_map_to_map(const struct tile *city_center, int city_map_x, int city_map_y); struct tile *city_map_to_map(const struct city *const pcity, int city_map_x, int city_map_y); Index: common/fc_types.h =================================================================== --- common/fc_types.h (revision 14385) +++ common/fc_types.h (working copy) @@ -38,10 +38,13 @@ #define MAX_LEN_NAME 32 #define MAX_LEN_DEMOGRAPHY 16 #define MAX_LEN_ALLOW_TAKE 16 -#define MAX_ID_LEN 33 +#define MAX_LEN_GAME_IDENTIFIER 33 #define MAX_GRANARY_INIS 24 #define MAX_LEN_STARTUNIT (20+1) +/* symbol to flag missing numbers for better debugging */ +#define IDENTITY_NUMBER_ZERO (0) + /* Server setting types. Changing these will break network compatability. */ enum sset_type { SSET_BOOL, SSET_INT, SSET_STRING Index: common/vision.h =================================================================== --- common/vision.h (revision 14385) +++ common/vision.h (working copy) @@ -108,8 +108,6 @@ /* This is copied in maphand.c really_give_tile_info_from_player_to_player(), * so be careful with pointers! */ -#define VISION_SITE_NONE (0) - struct vision_site { char name[MAX_LEN_NAME]; struct tile *location; /* Cannot be NULL */ Index: common/game.h =================================================================== --- common/game.h (revision 14385) +++ common/game.h (working copy) @@ -46,7 +46,6 @@ struct packet_ruleset_control control; bool debug[DEBUG_LAST]; int version; - char id[MAX_ID_LEN]; /* server only */ int timeoutint; /* increase timeout every N turns... */ int timeoutinc; /* ... by this amount ... */ int timeoutincmult; /* ... and multiply timeoutinc by this amount ... */ Index: ai/aidata.h =================================================================== --- ai/aidata.h (revision 14385) +++ ai/aidata.h (working copy) @@ -14,7 +14,7 @@ #define FC__AIDATA_H /* max size of a short */ -#define MAX_NUM_ID 32767 +#define MAX_NUM_ID (1+MAX_UINT16) #include "shared.h" /* bool type */ Index: client/gui-gtk-2.0/helpdlg.c =================================================================== --- client/gui-gtk-2.0/helpdlg.c (revision 14385) +++ client/gui-gtk-2.0/helpdlg.c (working copy) @@ -60,7 +60,7 @@ static GtkTextBuffer *help_text; static GtkWidget *help_text_sw; static GtkWidget *help_vbox; -static GtkWidget *unit_tile; +static GtkWidget *help_tile; static GtkWidget *help_box; static GtkWidget *help_itable; static GtkWidget *help_wtable; @@ -340,14 +340,14 @@ { gtk_widget_hide(help_box); - gtk_widget_hide(unit_tile); + gtk_widget_hide(help_tile); gtk_widget_hide(help_itable); gtk_widget_hide(help_wtable); gtk_widget_hide(help_utable); gtk_widget_hide(help_ttable); - gtk_widget_hide(unit_tile); + gtk_widget_hide(help_tile); /* FIXME: twice? */ gtk_widget_hide(help_vbox); gtk_widget_hide(help_text_sw); @@ -509,8 +509,8 @@ help_box = gtk_vbox_new(FALSE, 5); gtk_container_add(GTK_CONTAINER(help_frame), help_box); - unit_tile = gtk_pixcomm_new(tileset_full_tile_width(tileset), tileset_full_tile_height(tileset)); - gtk_box_pack_start(GTK_BOX(help_box), unit_tile, FALSE, FALSE, 0); + help_tile = gtk_pixcomm_new(tileset_full_tile_width(tileset), tileset_full_tile_height(tileset)); + gtk_box_pack_start(GTK_BOX(help_box), help_tile, FALSE, FALSE, 0); help_itable = gtk_table_new(1, 6, FALSE); gtk_box_pack_start(GTK_BOX(help_box), help_itable, FALSE, FALSE, 0); @@ -823,16 +823,16 @@ gtk_text_buffer_set_text(help_text, buf, -1); gtk_widget_show(help_text_sw); - gtk_pixcomm_freeze(GTK_PIXCOMM(unit_tile)); + gtk_pixcomm_freeze(GTK_PIXCOMM(help_tile)); { struct canvas store; store.type = CANVAS_PIXCOMM; - store.v.pixcomm = GTK_PIXCOMM(unit_tile); + store.v.pixcomm = GTK_PIXCOMM(help_tile); create_overlay_unit(&store, utype); } - gtk_pixcomm_thaw(GTK_PIXCOMM(unit_tile)); - gtk_widget_show(unit_tile); + gtk_pixcomm_thaw(GTK_PIXCOMM(help_tile)); + gtk_widget_show(help_tile); } else { gtk_label_set_text(GTK_LABEL(help_ulabel[0][1]), "0");
_______________________________________________ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev