diff -ruN -Xfreeciv/diff_ignore freeciv/client/clinet.c freeciv_build/client/clinet.c --- freeciv/client/clinet.c Tue Sep 19 18:06:55 2000 +++ freeciv_build/client/clinet.c Mon Sep 25 18:25:55 2000 @@ -238,6 +238,8 @@ The result must be free'd with delete_server_list() when no longer used **************************************************************************/ +#define MAXSERVERS 100 + struct server_list *create_server_list(char *errbuf, int n_errbuf) { struct server_list *server_list; @@ -251,6 +253,8 @@ char *server; int port; char str[512]; + char *servers[MAXSERVERS]; + int numservers=0; if ((proxy_url = getenv("http_proxy"))) { if (strncmp(proxy_url,"http://",strlen("http://"))) { @@ -356,33 +360,49 @@ server_list = fc_malloc(sizeof(struct server_list)); server_list_init(server_list); - while(fgets(str, 512, f) != NULL) { - if((0 == strncmp(str, "'); if(p==NULL) continue; - name=++p; - p=strstr(p,""); if(p==NULL) continue; - *p++='\0'; - - GET_FIELD(port); - GET_FIELD(version); - GET_FIELD(status); - GET_FIELD(players); - GET_FIELD(metastring); - - pserver->name = mystrdup(name); - pserver->port = mystrdup(port); - pserver->version = mystrdup(version); - pserver->status = mystrdup(status); - pserver->players = mystrdup(players); - pserver->metastring = mystrdup(metastring); - - server_list_insert(server_list, pserver); - } + while(fgets(str, 512, f) != NULL && numservers=0; numservers--) { + char *name,*port,*version,*status,*players,*metastring, *lastturn, *joinas; + char *p; + int minutes; + struct server *pserver = (struct server*)fc_malloc(sizeof(struct server)); + + strcpy(str, servers[numservers]); + free(servers[numservers]); + + p=strstr(str,"'); if(p==NULL) continue; + name=++p; + p=strstr(p,""); if(p==NULL) continue; + *p++='\0'; + + GET_FIELD(port); + GET_FIELD(version); + GET_FIELD(status); + GET_FIELD(players); + GET_FIELD(metastring); + GET_FIELD(lastturn); + GET_FIELD(joinas); + + if (!strcmp(joinas,"-")) + joinas=""; + + minutes=200; + if (strchr(lastturn,'m')) minutes=atoi(lastturn); + if (strchr(lastturn,'h')) minutes=atoi(lastturn)*60; + + pserver->name = mystrdup(name); + pserver->port = mystrdup(port); + pserver->version = mystrdup(version); + pserver->status = mystrdup(status); + pserver->players = mystrdup(players); + pserver->metastring = mystrdup(metastring); + pserver->lastturn = minutes; + pserver->joinas = mystrdup(joinas); + server_list_insert(server_list, pserver); } fclose(f); @@ -410,3 +430,13 @@ free(server_list); } +/************************************************************************** +... +**************************************************************************/ +void server_command(char *str) +{ + struct packet_generic_message apacket; + + mystrlcpy(apacket.message, str, MAX_LEN_MSG-MAX_LEN_USERNAME+1); + send_packet_generic_message(&aconnection, PACKET_CHAT_MSG, &apacket); +} diff -ruN -Xfreeciv/diff_ignore freeciv/client/clinet.h freeciv_build/client/clinet.h --- freeciv/client/clinet.h Sun Jan 2 13:55:22 2000 +++ freeciv_build/client/clinet.h Mon Sep 25 18:25:55 2000 @@ -34,6 +34,8 @@ char *status; char *players; char *metastring; + int lastturn; + char *joinas; }; #define SPECLIST_TAG server @@ -46,5 +48,6 @@ struct server_list *create_server_list(char *errbuf, int n_errbuf); void delete_server_list(struct server_list *server_list); +void server_command(char *str); #endif /* FC__CLINET_H */ diff -ruN -Xfreeciv/diff_ignore freeciv/client/gui-gtk/connectdlg.c freeciv_build/client/gui-gtk/connectdlg.c --- freeciv/client/gui-gtk/connectdlg.c Sun Jul 23 13:55:06 2000 +++ freeciv_build/client/gui-gtk/connectdlg.c Mon Sep 25 19:57:21 2000 @@ -16,9 +16,14 @@ #include #include +#include #include +#ifdef HAVE_UNISTD_H +#include +#endif + #include "fcintl.h" #include "support.h" #include "version.h" @@ -30,12 +35,18 @@ #include "gui_stuff.h" #include "connectdlg.h" +#include "helpdlg_g.h" + +#define AUTOSTART_SERVER _("localhost (autostarted)") /* in civclient.c; FIXME hardcoded sizes */ extern char name[]; extern char server_host[]; extern int server_port; +static int server_game_running; +static int server_autostart; + static GtkWidget *iname, *ihost, *iport; static GtkWidget *connw, *quitw; @@ -51,24 +62,239 @@ static int get_meta_list(GtkWidget *list, char *errbuf, int n_errbuf); +static int group_vals[20]; /* The values of Options radio buttons */ + +static int option_suggest_name=TRUE, option_hide_inactive=TRUE; + + /************************************************************************** ... **************************************************************************/ -static void connect_callback(GtkWidget *w, gpointer data) +static void start_localgame(void) { - char errbuf [512]; + char buf[200]; + int aifill[] ={2+1, 4+1, 8+1}; + int xsize[] ={50, 60, 80}; + int ysize[] ={40, 50, 50}; + char *difficulty[]={"easy", "normal", "hard"}; + int gen [] ={1,2}; + + sprintf(buf, "/set aifill %d", aifill[group_vals[0]]); + server_command(buf); + sprintf(buf, "/set xsize %d", xsize[group_vals[1]]); + server_command(buf); + sprintf(buf, "/set ysize %d", ysize[group_vals[1]]); + server_command(buf); + sprintf(buf, "/%s", difficulty[group_vals[2]]); + server_command(buf); + sprintf(buf, "/set generator %d", gen[group_vals[3]]); + server_command(buf); + server_command("/start"); +} - mystrlcpy(name, gtk_entry_get_text(GTK_ENTRY(iname)), 512); - mystrlcpy(server_host, gtk_entry_get_text(GTK_ENTRY(ihost)), 512); - server_port=atoi(gtk_entry_get_text(GTK_ENTRY(iport))); - - if(connect_to_server(name, server_host, server_port, - errbuf, sizeof(errbuf))!=-1) { +/************************************************************************** +... +**************************************************************************/ +int start_server(int port) +{ + char buf[200]; + + sprintf(buf,"(civserver -b -p %d &) >/dev/null", port); + return system(buf); +#if 0 + /* does not work */ + if ((server_pid=fork())<0) { + append_output_window(_("Lost connection to server!")); + return 1; + } else if (server_pid==0) { /* child */ + sprintf(buf,"%d",port); + freopen("/dev/null", "w", stdout); + execlp("civserver", "civserver", "-b", "-p", buf); + exit(0); + } + sleep(2); + return 0; +#endif +} +/************************************************************************** +... +**************************************************************************/ +static GtkWidget *input_dialog; + +static void sel_name_dialog_destroy(GtkWidget *button) +{ + GtkWidget *parent; + + parent=gtk_object_get_data(GTK_OBJECT(button->parent->parent->parent), + "parent"); + + gtk_widget_set_sensitive(parent, TRUE); + + gtk_widget_destroy(button->parent->parent->parent); +} + + +static gint sel_name_del_callback(GtkWidget *widget, GdkEvent *event, + gpointer data) +{ + gtk_widget_set_sensitive( (GtkWidget *)data, TRUE ); + return FALSE; +} + +/**************************************************************** +... +*****************************************************************/ +static void connection_attempt(char *tempname, int fromlist); +static char joinas_name[128]; + +static void select_name_callback(GtkWidget *w, gpointer data) +{ + sel_name_dialog_destroy(w); + + if(data) + connection_attempt(joinas_name, TRUE); +} + +void sel_name_radio_callback( GtkWidget *w, gpointer data ) +{ + sz_strlcpy(joinas_name, data); +} + +static void gui_select_name(char *joinas) +{ + GtkWidget *shell, *frame, *ok, *cancel, *parent=dialog, *button, *vbox; + GSList *namegroup=0; + static char namebuf[1024]; + char *r, *w, *name; + + gtk_widget_set_sensitive(parent, FALSE); + + shell=gtk_dialog_new(); + gtk_signal_connect(GTK_OBJECT(shell),"delete_event", + GTK_SIGNAL_FUNC(sel_name_del_callback), parent); + + gtk_window_set_title(GTK_WINDOW(shell), _("Select player name")); + + gtk_container_border_width(GTK_CONTAINER(GTK_DIALOG(shell)->vbox), 5); + + frame=gtk_frame_new("Select player name"); + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(shell)->vbox), frame, TRUE, TRUE, 0); + + vbox = gtk_vbox_new(0,TRUE); + r=joinas; + w=namebuf; + do { + if (*r==';') + break; + + name=w; + for ( ; *r && *r!=',' && *r!=';'; r++) + *w++ = *r; + *w++=0; + for ( ; *r && strchr(" ,",*r); r++) ; + + if (name==namebuf) + sz_strlcpy(joinas_name, name); + + button=gtk_radio_button_new_with_label(namegroup, name); + namegroup = gtk_radio_button_group( GTK_RADIO_BUTTON( button ) ); + gtk_signal_connect(GTK_OBJECT(button), "toggled", + GTK_SIGNAL_FUNC(sel_name_radio_callback), name); + gtk_box_pack_start( GTK_BOX( vbox ), button, TRUE, FALSE, 0 ); + gtk_widget_show (button); + } while(*r); + gtk_container_add(GTK_CONTAINER(frame), vbox); + + + ok=gtk_button_new_with_label(_("Ok")); + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(shell)->action_area), + ok, TRUE, TRUE, 0); + gtk_signal_connect(GTK_OBJECT(ok), "clicked", + GTK_SIGNAL_FUNC(select_name_callback), (gpointer)1); + + cancel=gtk_button_new_with_label(_("Cancel")); + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(shell)->action_area), + cancel, TRUE, TRUE, 0); + gtk_signal_connect(GTK_OBJECT(cancel), "clicked", + GTK_SIGNAL_FUNC(select_name_callback), 0); + + gtk_set_relative_position(parent, shell, 10, 10); + + gtk_object_set_data(GTK_OBJECT(shell), "parent",parent); + + gtk_widget_show_all(GTK_DIALOG(shell)->vbox); + gtk_widget_show_all(GTK_DIALOG(shell)->action_area); + gtk_widget_show(shell); + + input_dialog=shell; +} + + +/************************************************************************** +... +**************************************************************************/ +static void rules_callback(GtkWidget *w, gpointer data) +{ + popup_help_dialog_string(HELP_ESSENTIALS_ITEM); +} + + +/************************************************************************** +... +**************************************************************************/ +static char *joinas_names; + +static void connection_attempt(char *tempname, int fromlist) +{ + char errbuf [512], ok, attempts=0; + + if (*server_host=='-') /* An error message */ + return; + + server_autostart= !strcmp(server_host, AUTOSTART_SERVER); + + if (server_autostart) { + mystrlcpy(server_host, "localhost", 512); + server_port=5555; + + if (start_server(server_port)) + append_output_window(_("Failed to start server")); + } + + if (option_suggest_name && !fromlist && server_game_running + && joinas_names && *joinas_names) { + gui_select_name(joinas_names); + return; + } + + do { + ok=connect_to_server(tempname, server_host, server_port, + errbuf, sizeof(errbuf)) != -1; + if (server_autostart && !ok) + sleep(1); + } while (server_autostart && !ok && ++attempts<=5); + + if (ok) { gtk_widget_destroy(dialog); gtk_widget_set_sensitive(toplevel,TRUE); + + if (server_autostart) + start_localgame(); } - else + else { append_output_window(errbuf); + if (server_autostart) + append_output_window("Make sure the latest civserver is first in path\n"); + } +} + +static void connect_callback(GtkWidget *w, gpointer data) +{ + mystrlcpy(name, gtk_entry_get_text(GTK_ENTRY(iname)), 512); + mystrlcpy(server_host, gtk_entry_get_text(GTK_ENTRY(ihost)), 512); + server_port=atoi(gtk_entry_get_text(GTK_ENTRY(iport))); + + connection_attempt(name, FALSE); } /************************************************************************** @@ -97,14 +323,25 @@ /************************************************************************** ... **************************************************************************/ +#define MAXSERVERS 100 +static char *joinas_list[MAXSERVERS]; + void meta_list_callback(GtkWidget *w, gint row, gint column) { - gchar *name, *port; + gchar *name, *port, *status; gtk_clist_get_text(GTK_CLIST(w), row, 0, &name); gtk_entry_set_text(GTK_ENTRY(ihost), name); + mystrlcpy(server_host, name, 512); + gtk_clist_get_text(GTK_CLIST(w), row, 1, &port); gtk_entry_set_text(GTK_ENTRY(iport), port); + server_port=atoi(port); + + gtk_clist_get_text(GTK_CLIST(w), row, 3, &status); + server_game_running=!strcmp(status,"Running"); + + joinas_names = joinas_list[row]; } /************************************************************************** @@ -127,36 +364,52 @@ /************************************************************************** ... **************************************************************************/ -void gui_server_connect(void) -{ - GtkWidget *label, *table, *book, *scrolled, *list, *vbox, *update; - static char *titles_[6]= {N_("Server Name"), N_("Port"), N_("Version"), - N_("Status"), N_("Players"), N_("Comment")}; - static char **titles; - char buf [256]; - int i; - - if (!titles) titles = intl_slist(6, titles_); +static int button_group_num, button_num; - gtk_widget_set_sensitive(turn_done_button, FALSE); - gtk_widget_set_sensitive(toplevel, FALSE); - - dialog=gtk_dialog_new(); - gtk_signal_connect(GTK_OBJECT(dialog),"delete_event", - GTK_SIGNAL_FUNC(connect_deleted_callback), NULL); - - gtk_window_set_title(GTK_WINDOW(dialog), _(" Connect to Freeciv Server")); +static void buttons_callback( GtkWidget *w, gpointer data ) +{ + group_vals[(int)data/16]= (int)data%16; +} - book = gtk_notebook_new (); - gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), book, TRUE, TRUE, 0); +static void +button_in_table(int groupnum, char *label, int active, + GtkWidget *table, int x, int y) +{ + static GSList *group; + int xx= x>=0?x+1:-x+2, yy=y>=0?y+1:-y+2; + GtkWidget *button; + + x=x>=0?x:-x; y=y>=0?y:-y; + + if (button_group_num != groupnum) + group=0, button_num=0, button_group_num=groupnum; + + button = gtk_radio_button_new_with_label (group, label); + group = gtk_radio_button_group( GTK_RADIO_BUTTON( button ) ); + gtk_table_attach (GTK_TABLE(table), button, x, xx, y, yy, GTK_FILL,0,0,0); + gtk_signal_connect(GTK_OBJECT(button), "toggled", + GTK_SIGNAL_FUNC(buttons_callback), (gpointer)(groupnum*16 + button_num++)); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), active); + gtk_widget_show (button); +} +/************************************************************************** +The "Options" tab of the connect dialog +**************************************************************************/ +static int create_local_entry(GtkWidget *list); - label=gtk_label_new(_("Freeciv Server Selection")); +static GtkWidget *gui_name_selection(void) +{ + GtkWidget *vbox, *label, *table, *update, *list, *scrolled; + int i; + static char **titles; + static char *titles_[6]= {N_("Server Name"), N_("Port"), N_("Version"), + N_("Status"), N_("Players"), N_("Comment")}; vbox=gtk_vbox_new(FALSE, 2); - gtk_notebook_append_page (GTK_NOTEBOOK (book), vbox, label); - table = gtk_table_new (4, 2, FALSE); + /*--------------Name: field---------------*/ + table = gtk_table_new (1, 4, FALSE); gtk_table_set_row_spacings (GTK_TABLE (table), 2); gtk_table_set_col_spacings (GTK_TABLE (table), 5); gtk_container_border_width (GTK_CONTAINER (table), 5); @@ -168,25 +421,7 @@ iname=gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(iname), name); - gtk_table_attach_defaults (GTK_TABLE (table), iname, 1, 2, 0, 1); - - label=gtk_label_new(_("Host:")); - gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, 0, 0, 0, 0); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - - ihost=gtk_entry_new(); - gtk_entry_set_text(GTK_ENTRY(ihost), server_host); - gtk_table_attach_defaults (GTK_TABLE (table), ihost, 1, 2, 1, 2); - - label=gtk_label_new(_("Port:")); - gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3, 0, 0, 0, 0); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - - my_snprintf(buf, sizeof(buf), "%d", server_port); - - iport=gtk_entry_new(); - gtk_entry_set_text(GTK_ENTRY(iport), buf); - gtk_table_attach_defaults (GTK_TABLE (table), iport, 1, 2, 2, 3); + gtk_table_attach_defaults (GTK_TABLE (table), iname, 1, 3, 0, 1); #if IS_BETA_VERSION { @@ -202,10 +437,8 @@ } #endif - label=gtk_label_new(_("Metaserver")); - - vbox=gtk_vbox_new(FALSE, 2); - gtk_notebook_append_page (GTK_NOTEBOOK (book), vbox, label); + /*--------------Server list---------------*/ + if (!titles) titles = intl_slist(6, titles_); list=gtk_clist_new_with_titles(6, titles); gtk_clist_column_titles_passive(GTK_CLIST(list)); @@ -213,28 +446,243 @@ for(i=0; i<6; i++) gtk_clist_set_column_auto_resize(GTK_CLIST(list), i, TRUE); + create_local_entry(list); + scrolled=gtk_scrolled_window_new(NULL,NULL); gtk_container_add(GTK_CONTAINER(scrolled), list); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); gtk_box_pack_start(GTK_BOX(vbox), scrolled, TRUE, TRUE, 0); - update=gtk_button_new_with_label(_("Update")); + + /*--------------Update button---------------*/ + update=gtk_button_new_with_label(_("Find online games")); gtk_box_pack_start(GTK_BOX(vbox), update, FALSE, FALSE, 2); + + /*--------------Signals---------------------*/ gtk_signal_connect(GTK_OBJECT(list), "select_row", GTK_SIGNAL_FUNC(meta_list_callback), NULL); gtk_signal_connect(GTK_OBJECT(list), "button_press_event", GTK_SIGNAL_FUNC(meta_click_callback), NULL); gtk_signal_connect(GTK_OBJECT(update), "clicked", GTK_SIGNAL_FUNC(meta_update_callback), (gpointer)list); + gtk_clist_select_row(GTK_CLIST(list),0,0); + + gtk_signal_connect(GTK_OBJECT(iname), "activate", + GTK_SIGNAL_FUNC(connect_callback), NULL); + + return vbox; +} + + +/************************************************************************** +The "Options" tab of the connect dialog +**************************************************************************/ + +static GtkWidget *gui_options(void) +{ + GtkWidget *vbox, *label, *frame, *table; + + vbox=gtk_vbox_new(FALSE, 2); + frame=gtk_frame_new("Autostart server options"); + gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0); + + /* Create and attach table */ + table = gtk_table_new (4, 5, FALSE); + gtk_table_set_row_spacings (GTK_TABLE (table), 2); + gtk_table_set_col_spacings (GTK_TABLE (table), 5); + gtk_container_border_width (GTK_CONTAINER (table), 5); + gtk_container_add(GTK_CONTAINER(frame), table); + + /*-------------------number of opponents------------------*/ + button_group_num=-1; + label=gtk_label_new(_("AI Opponents:")); + gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); + gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, GTK_FILL,0,0,0); + button_in_table(0, "2", FALSE, table, 1, 0); + button_in_table(0, "4", TRUE, table, 2, 0); + button_in_table(0, "8", FALSE, table, 3, 0); + + /*-------------------mapsize------------------------------*/ + label=gtk_label_new(_("Map size:")); + gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); + gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, GTK_FILL,0,0,0); + button_in_table(1, "50x40", FALSE, table, 1, 1); + button_in_table(1, "60x50", TRUE, table, 2, 1); + button_in_table(1, "80x50", FALSE, table, 3, 1); + + /*-------------------difficulty---------------------------*/ + label=gtk_label_new(_("Difficulty:")); + gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); + gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3, GTK_FILL,0,0,0); + button_in_table(2, _("easy"), TRUE, table, 1, 2); + button_in_table(2, _("normal"), FALSE, table, 2, 2); + button_in_table(2, _("hard"), FALSE, table, 3, 2); + + /*-------------------islands------------------------------*/ + label=gtk_label_new(_("Islands:")); + gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); + gtk_table_attach (GTK_TABLE (table), label, 0, 1, 3, 4, GTK_FILL,0,0,0); + button_in_table(3, _("random"), TRUE, table, 1, 3); + button_in_table(3, _("one per player"), FALSE, table, -2, 3); + + return vbox; +} + + + + +/************************************************************************** +The "Advanced" tab of the connect dialog +**************************************************************************/ +static GtkWidget *options_toggle1, *options_toggle2; +static void options_toggle_callback( GtkWidget *w, gpointer data ) +{ + option_suggest_name= GTK_TOGGLE_BUTTON(options_toggle1)->active; + option_hide_inactive=GTK_TOGGLE_BUTTON(options_toggle2)->active; +} + +static GtkWidget *gui_advanced(void) +{ + GtkWidget *vbox, *vbox2, *label, *frame, *table; + char buf[10]; + + vbox=gtk_vbox_new(FALSE, 2); + + /*====================server list options=======================*/ + frame=gtk_frame_new(_("Server list options")); + gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0); + + table = gtk_table_new (2, 1, FALSE); + gtk_table_set_row_spacings (GTK_TABLE (table), 2); + gtk_table_set_col_spacings (GTK_TABLE (table), 5); + gtk_container_border_width (GTK_CONTAINER (table), 5); + gtk_container_add(GTK_CONTAINER(frame), table); + + /*-------------------suggest names------------------------------*/ + options_toggle1= gtk_check_button_new_with_label( + _("Suggest names when joining running game")); + gtk_table_attach(GTK_TABLE (table), options_toggle1,0,1,0,1, GTK_FILL,0,0,0); + gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(options_toggle1), + option_suggest_name); + gtk_signal_connect(GTK_OBJECT(options_toggle1), "toggled", + GTK_SIGNAL_FUNC(options_toggle_callback), NULL); + + /*-------------------hide servers------------------------------*/ + options_toggle2= gtk_check_button_new_with_label( + _("Hide inactive and full servers")); + gtk_table_attach(GTK_TABLE (table), options_toggle2,0,1,1,2, GTK_FILL,0,0,0); + gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(options_toggle2), + option_hide_inactive); + gtk_signal_connect(GTK_OBJECT(options_toggle2), "toggled", + GTK_SIGNAL_FUNC(options_toggle_callback), NULL); + + + /*====================manual server selection=======================*/ + frame=gtk_frame_new(_("Manual server specification")); + gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0); + + vbox2=gtk_vbox_new(FALSE, 2); + gtk_container_add(GTK_CONTAINER(frame), vbox2); + + /*--------------------server name----------------------------*/ + table = gtk_table_new (2, 2, FALSE); + gtk_table_set_row_spacings (GTK_TABLE (table), 2); + gtk_table_set_col_spacings (GTK_TABLE (table), 5); + gtk_container_border_width (GTK_CONTAINER (table), 5); + gtk_box_pack_start(GTK_BOX(vbox2), table, FALSE, TRUE, 0); + + + /*--------------------server host----------------------------*/ + label=gtk_label_new(_("Host:")); + gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); + gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, 0,0,0,0); + + ihost=gtk_entry_new(); + gtk_entry_set_text(GTK_ENTRY(ihost), server_host); + gtk_table_attach_defaults (GTK_TABLE (table), ihost, 1, 2, 0, 1); + + /*--------------------server port----------------------------*/ + label=gtk_label_new(_("Port:")); + gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); + gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, 0,0,0,0); + + sprintf(buf, "%d", server_port); + iport=gtk_entry_new(); + gtk_entry_set_text(GTK_ENTRY(iport), buf); + gtk_table_attach_defaults (GTK_TABLE (table), iport, 1, 2, 1, 2); + + gtk_signal_connect(GTK_OBJECT(ihost), "activate", + GTK_SIGNAL_FUNC(connect_callback), NULL); + gtk_signal_connect(GTK_OBJECT(iport), "activate", + GTK_SIGNAL_FUNC(connect_callback), NULL); + + return vbox; +} + + +/************************************************************************** +... +**************************************************************************/ + +void gui_server_connect(void) +{ + GtkWidget *label, *book, *vbox, *vbox2, *vbox3, *rulesw; + GdkGeometry gdkGeometry; + + mystrlcpy(server_host, "localhost", 512); + server_port=5555; + server_game_running=0; + + memset(&gdkGeometry,0,sizeof(gdkGeometry)); + gdkGeometry.min_width=600; + gdkGeometry.min_height=300; + + gtk_widget_set_sensitive(turn_done_button, FALSE); + gtk_widget_set_sensitive(toplevel, FALSE); + + dialog=gtk_dialog_new(); + gtk_signal_connect(GTK_OBJECT(dialog),"delete_event", + GTK_SIGNAL_FUNC(connect_deleted_callback), NULL); + + gtk_window_set_title(GTK_WINDOW(dialog), _(" Connect to Freeciv Server")); + + gtk_window_set_geometry_hints(GTK_WINDOW(dialog), 0, &gdkGeometry, GDK_HINT_MIN_SIZE); + + book = gtk_notebook_new (); + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), book, TRUE, TRUE, 0); + + + /*===========================================================================*/ + vbox3=gui_advanced(); /* initializes ihost/iport */ + vbox2=gui_options(); + vbox=gui_name_selection(); /* uses ihost/iport */ + + /*===========================================================================*/ + + label=gtk_label_new(_("Game selection")); + gtk_notebook_append_page (GTK_NOTEBOOK (book), vbox, label); + + label=gtk_label_new(_("Options")); + gtk_notebook_append_page (GTK_NOTEBOOK (book), vbox2, label); + + label=gtk_label_new(_("Manual")); + gtk_notebook_append_page (GTK_NOTEBOOK (book), vbox3, label); + + /*======================= Action area =======================================*/ connw=gtk_button_new_with_label(_("Connect")); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), connw, TRUE, TRUE, 0); GTK_WIDGET_SET_FLAGS(connw, GTK_CAN_DEFAULT); gtk_widget_grab_default(connw); + rulesw=gtk_button_new_with_label(_("Help")); + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), rulesw, + TRUE, TRUE, 0); + GTK_WIDGET_SET_FLAGS(rulesw, GTK_CAN_DEFAULT); + quitw=gtk_button_new_with_label(_("Quit")); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), quitw, TRUE, TRUE, 0); @@ -242,14 +690,10 @@ gtk_widget_grab_focus (iname); - gtk_signal_connect(GTK_OBJECT(iname), "activate", - GTK_SIGNAL_FUNC(connect_callback), NULL); - gtk_signal_connect(GTK_OBJECT(ihost), "activate", - GTK_SIGNAL_FUNC(connect_callback), NULL); - gtk_signal_connect(GTK_OBJECT(iport), "activate", - GTK_SIGNAL_FUNC(connect_callback), NULL); gtk_signal_connect(GTK_OBJECT(connw), "clicked", GTK_SIGNAL_FUNC(connect_callback), NULL); + gtk_signal_connect(GTK_OBJECT(rulesw), "clicked", + GTK_SIGNAL_FUNC(rules_callback), NULL); gtk_signal_connect(GTK_OBJECT(quitw), "clicked", GTK_SIGNAL_FUNC(gtk_main_quit), NULL); @@ -264,21 +708,58 @@ /************************************************************************** Get the list of servers from the metaserver **************************************************************************/ -static int get_meta_list(GtkWidget *list, char *errbuf, int n_errbuf) + +static int create_local_entry(GtkWidget *list) { + char *row[6], buf[6][64]; int i; - char *row[6]; - char buf[6][64]; + + for (i=0; i<6; i++) + row[i]=buf[i]; + + gtk_clist_freeze(GTK_CLIST(list)); + sz_strlcpy( buf[0], AUTOSTART_SERVER); + sz_strlcpy( buf[1], "5555"); + sz_strlcpy( buf[2], ""); + sz_strlcpy( buf[3], ""); + sz_strlcpy( buf[4], ""); + sz_strlcpy( buf[5], _("Play against the computer")); + gtk_clist_append(GTK_CLIST(list), row); + gtk_clist_thaw(GTK_CLIST(list)); + + return 1; /* 1 entry created */ +} + + + +static int get_meta_list(GtkWidget *list, char *errbuf, int n_errbuf) +{ + int i, pos, bestpos=0, score, bestscore=0; + int numservers=0, numshown=0; + char *row[6], buf[6][64], *errmsg[6]; struct server_list *server_list = create_server_list(errbuf, n_errbuf); if(!server_list) return -1; gtk_clist_freeze(GTK_CLIST(list)); gtk_clist_clear(GTK_CLIST(list)); + pos=create_local_entry(list); + for (i=0; i<6; i++) - row[i]=buf[i]; + row[i]=buf[i], errmsg[i]=""; server_list_iterate(*server_list,pserver) { + numservers++; + if (option_hide_inactive) { + if (!strcmp(pserver->status, "Game over")) + continue; + + if (!strcmp(pserver->status, "Running") && + (pserver->lastturn>=10 || !*pserver->joinas)) + continue; + } + numshown++; + sz_strlcpy(buf[0], pserver->name); sz_strlcpy(buf[1], pserver->port); sz_strlcpy(buf[2], pserver->version); @@ -287,10 +768,37 @@ sz_strlcpy(buf[5], pserver->metastring); gtk_clist_append(GTK_CLIST(list), row); + + if (posjoinas)+1); + strcpy(joinas_list[pos],pserver->joinas); + } + + /*------------determine which one to highlight--------*/ + score=0; + if(!strcmp(pserver->status,"Pregame")) + score=100*atoi(pserver->players); + if(!strcmp(pserver->status,"Running") && pserver->lastturn<10 && *pserver->joinas) + score=atoi(pserver->players); + if (score>bestscore) + bestpos=pos, bestscore=score; + pos++; } server_list_iterate_end; + if (numshown==0) { + errmsg[0]="--------------"; + if (numservers==0) + errmsg[5]=_("(No servers found, try updating again)"); + else + errmsg[5]=_("(All servers hidden, use advanced options & update)"); + gtk_clist_append(GTK_CLIST(list), errmsg); + } + + + delete_server_list(server_list); + gtk_clist_select_row(GTK_CLIST(list),bestpos,0); gtk_clist_thaw(GTK_CLIST(list)); return 0; diff -ruN -Xfreeciv/diff_ignore freeciv/client/include/helpdlg_g.h freeciv_build/client/include/helpdlg_g.h --- freeciv/client/include/helpdlg_g.h Mon Dec 27 16:09:02 1999 +++ freeciv_build/client/include/helpdlg_g.h Mon Sep 25 18:42:51 2000 @@ -24,6 +24,7 @@ #define HELP_PLAYING_ITEM "Strategy and tactics" #define HELP_LANGUAGES_ITEM "Languages" +#define HELP_ESSENTIALS_ITEM "Essentials" #define HELP_CONNECTING_ITEM "Connecting" #define HELP_CHATLINE_ITEM "Chatline" #define HELP_CONTROLS_ITEM "Controls" diff -ruN -Xfreeciv/diff_ignore freeciv/data/helpdata.txt freeciv_build/data/helpdata.txt --- freeciv/data/helpdata.txt Mon Aug 14 18:58:09 2000 +++ freeciv_build/data/helpdata.txt Mon Sep 25 18:26:27 2000 @@ -396,6 +396,278 @@ freeciv-dev@xxxxxxxxxxx\ ") +[help_essentials] +name = _("Essentials") +text = _("\ +F R E E C I V E S S E N T I A L S\n\ +===================================\n\ +\n\ + (Check www.freeciv.org/civintro for a nicer looking version)\n\ +\n\ +HOW TO START\n\ +============\n\ +If you want to play against the computer, just hit the start \ +button, maybe after adjusting difficulty and other options on \ +the options tab. For multiplayer games, hit the 'Find games' \ +button and click a game in pregame state, possibly with nonzero \ +players.\ +"), _("\ +THE GOAL\n\ +========\n\ +The goal of Freeciv is to build cities, which in turn can build armies \ +to attack the other players. You get 2 settlers and 1 explorer. Using \ +the numeric keypad, move the settlers to a good location (see below) \ +and build a city by pressing b. You can move diagonally, by the way. \ +Freeciv is turn based; every unit can move once per turn. The turn ends \ +when everyone clicks 'Turn done' or when a timeout is over. \ +"), _("\ +CITIES\n\ +======\n\ +Cities extract resources from the square they're built on plus one \ +nearby square for each inhabitant; you start with 1 inhabitant. The \ +resources are: Food (to grow cities), Production (to build \ +settlers/armies) and Trade (for research and money). Click a city to \ +bring it up for management. Click on a used square on the small map to \ +remove your worker (and turn him into an entertainer, see below), then \ +click on an unused square to place your worker. However the default \ +placement is usually good.\ +"), _("\ + FOOD\n\ + All food from the used squares is added to the granary. Every\n\ + inhabitant uses two food per turn though, and settlers built by\n\ + this city require one or two also. When the granary reaches 20 \n\ + food, the city grows to size 2 and can use an additional nearby\n\ + square. Settlers can irrigate (press i) nearby squares if there\n\ + is water adjacent, which increases food by one for some square \n\ + types, see table below. The square under the city gets a free \n\ + irrigation.\ +"), _("\ + PRODUCTION\n\ + The production you get from a square can be used to produce \n\ + military units or settlers. Producing a settler reduces the city\n\ + size by 1 and can only be done in cities of size 2 and larger. \n\ + Some units require one production every turn (upkeep) for as \n\ + long as they're alive. You can change the unit or building to be\n\ + produced in the city report, or buy unfinished units. Settlers \n\ + can mine (press m) some square types, which increases their \n\ + production; see table below. The square the city is on gets one \n\ + production if otherwise zero.\ +"), _("\ + TRADE\n\ + Trade can be turned into tax, luxury or science. Science lets \n\ + you research new military unit types. Tax yields money, which \n\ + you can use to prematurely complete a cities production. Luxury\n\ + creates happy inhabitants. You can select the distribution of \n\ + your trade by pressing shift-R. Corruption reduces the amount \n\ + of trade that a city delivers; the further away from the capital,\n\ + the more corruption. Settlers can build roads (press r) which add\n\ + 1 trade to some square types, see table below, and allow for \n\ + faster movement. The square the city is on gets a free road.\ +"), _("\ +City inhabitants can be happy, content or unhappy (shown by different icons \ +in the city window). If there are more unhappy than happy inhabitants, \ +the city falls into disorder and stops producing anything. The first \ +four inhabitants of a city are content. Additional ones are unhappy and \ +must be made content either with temples in their cities, with wonders \ +(see below), with luxuries or with entertainers. \ +"), _("\ +RESEARCH\n\ +========\n\ +In the Reports menu you find the Science report. There you can decide \ +what to research. You can select an immediate thing to research and a \ +long term goal that the next immediate will be selected from. Most \ +research items require others to be discovered already. After discovery \ +of knowledge, you can build new types of military units, new wonders or \ +use new governments. This window pops up whenever research on one item \ +finishes.\ +"), _("\ +GOVERNMENT\n\ +==========\n\ +The type of government you have affects how many resources your cities \ +can extract from the land. You can change government by researching the \ +new government type and then starting a revolution (in Kingdom menu,\ +will take a few turns). The most important ones:\ +"), _("\ + DESPOTISM: This is your initial government type. Each square\n\ + that yields more than 2 of anything (food, production or trade)\n\ + has that yield reduced by one. Settlers use one food per turn for\n\ + upkeep, military units are free unless there are more built by a\n\ + city than the city has inhabitants. Science rate can only be\n\ + set to 60%. High corruption\ +"), _("\ + MONARCHY: No more resource reduction. Settlers use one food.\n\ + The first 3 military units per city are free of upkeep. Maximum\n\ + science rate is 70%. Corruption is small.\ +"), _("\ + REPUBLIC: Each square with trade gets another trade unit.\n\ + Settlers use two food, and one production. All military units\n\ + use one production. Only one military unit is tolerated abroad\n\ + (not in city), additional units create one unhappy inhabitant. \n\ + Corruption is small.\ +"), _("\ +WONDERS\n\ +=======\n\ +Each wonder of the world can only be built by one player and only in \ +one city. Other cities can build and send caravans (after you research\ +Trade) to help in building wonders. The most important wonders are: \n\ +\n\ + MAGELLAN'S EXPEDITION: Sea units can move 2 squares further per \n\ + turn. Requires Navigation\n\ + LEONARDOS WORKSHOP: 1 obsoloete military units gets upgraded.\n\ + Requires Invention.\n\ + MICHELANGELOS CHAPEL: 3 unhappy inhabitants become content in\n\ + every city. Requires Monotheism.\n\ + J.S.BACH'S CATHEDRAL: Makes 2 inhabitants happy in every city.\n\ + Requires Theology.\ +"), _("\ +SQUARE TYPES\n\ +============\n\ +These are the food, production and trade yields of all squares under \ +MONARCHY. To identify a square type, click map with middle button.\n\ +\n\ + F P T F P T F P T Irr Min Roa Defen\n\ + Ocean 1/0/2 +Fish 3/0/2 +Whale 2/2/3 - - - -\n\ +Grassland 2/0/0 +Resources 2/1/0 +Resources 2/1/0 F - T -\n\ + Plains 1/1/0 +Buffalo 1/3/0 +Wheat 3/1/0 F - T -\n\ + Desert 0/1/0 +Oasis 3/1/0 +Oil 0/4/0 F PP T -\n\ + Tundra 1/0/0 +Game 3/1/0 +Fur 2/0/3 F - - -\n\ + Forest 1/2/0 +Pheasant 3/2/0 +Silk 1/2/3 - - - +50%\n\ + Jungle 1/0/0 +Gems 1/0/4 +Fruit 4/0/1 - - - +50%\n\ + Hills 1/0/0 +Coal 1/2/0 +Wine 1/0/4 F PPP - +100%\n\ +Mountains 0/1/0 +Gold 0/1/6 +Iron 0/4/0 - P - +200%\n\ + Swamp 1/0/0 +Peat 1/4/0 +Spice 3/0/4 - - - +50%\n\ + Glacier 0/0/0 +Ivory 1/1/4 +Oil 0/4/0 - - - -\n\ +\n\ +These are the food, production and trade yields of all squares under \ +MONARCHY. Note that the fields in the second and third column \ +are rare. For the initial government type, reduce all numbers above 2 \ +by 1. For Republic, add 1 trade to each square with trade. \ +Irrigation/Mine/Road shows the increases in food, production, and trade \ +when those are improvements are performed by a settler. Defense is the \ +increase in defense power you get when attacked on such a field. Rivers \ +add 1 trade and 50% defense power; they also ease movement along them. \ +Squares with increased defense power are harder to walk fast (horses \ +get slowed down) except for explorers. \ +"), _("\ +MILITARY UNITS\n\ +==============\n\ +Most important military units:\n\ +\n\ + Name A D M Requires Remarks\n\ + Explorer - 1 3 Seafaring No slowdown by rought terrain\n\ + Settlers - 1 1 - Builds cities, improves land\n\ + Diplomat - - 2 Writing Can subvert cities & bribe units\n\ + Caravan - 1 1 Trade Carries production to wonders\n\ + Phalanx 1 2 1 Bronze working OK defense against land units\n\ + Horsemen 2 1 2 Horseback riding Good invader of emptied cities\n\ + Trireme 1 1 3 Map making Carries 2, turn must end at coast\n\ + Caravel 2 1 3 Navigation Carries 3 units\n\ + Ironclad 4 4 4 Steam engine Strong attacker of coastal cities\n\ + Destroyer 4 4 6 Electricity Like ironclad but faster\n\ + Cruiser 6 6 5 Steel Much stronger than destroyers\n\ +\n\ +Military units are characterized by three numbers: attack power, \ +defense power, and movement speed. Those three numbers plus the \ +production cost are what you see when changing production. When unit A \ +attacks unit B by moving onto B's square, A's attack power is \ +matched up against B's defense power. If A has attack power 2 and B has \ +defense power 1, then A has about a two-thirds chance of winning (more \ +info in the Freeciv manual). The survivor often becomes veteran, which \ +increases his attack and defense power by 50%. Being built in a city \ +with Barracks makes a unit veteran, too.\n\ +\n\ +Rivers and some terrain types increase the defense power of the \ +defender, see table below. Units in cities enjoy a 50% defense power \ +increase as well. Damaged units have red bars in the bottom left \ +corner, they move more slowly and have their attack power reduced. They \ +recover slowly (faster in cities or when fortified).\n\ +\n\ +Pressing f will fortify the unit, which increases defense power by 50%. \ +Pressing s will put the unit on sentry; they will wait until healed or \ +until an enemy unit moves to an adjacent field. Pressing g lets you \ +select a destination to go to. If an enemy is there, it will be \ +attacked. Military units can take enemy cities when there are no \ +defenders left. Defended cities have a little flag in their top left \ +corner. If you lose your capital, you get very high corruption and your \ +kingdom may split.\n\ +\n\ +If several military units are on one square, the strongest one defends. \ +If it is defeated, all units die (except in cities). Sea units can \ +attack land units but not vice versa. Some sea units can carry land \ +units, just move onto them at the coast. Loaded units have a + in \ +their bottom right corner.\n\ +\n\ +Diplomats are very powerful. They are easy to defeat but can incite \ +revolts in enemy cities (the city becomes yours), steal technologies or \ +bribe enemy units. Diplomat actions can be performed directly from a \ +ship. Defending diplomats in cities may prevent them.\ +"), _("\ +WINNING STRATEGY\n\ +================\n\ +Most multi-player games are played using '/set generator 2'. This \ +creates one island for every player plus some small empty additional \ +ones. Here's standard strategy to play these.\n\ +\n\ +1. Find good settling spots. A good settling spot must at least\n\ + yield 4 food (from the two squares used) and as much production\n\ + as possible. Don't look longer than, say, for 3-4 turns. Whales\n\ + and pheasants are the best resource to be close to. Grassland and\n\ + plains are good to settle on, wheat/oasis/buffalo even better.\n\ +2. Once you built the city, set its production to settlers. Bring up\n\ + the science report and set research to Alphabet and the goal to\n\ + The Republic.\n\ +3. As soon as any city reaches size two, click it and set all\n\ + workers on production fields using the little map. As soon as you\n\ + can afford it, buy the settler.\n\ +4. Keep producing nothing but settlers and have them build nearby\n\ + cities. There should only be 1-2 empty squares between the\n\ + cities. Don't build irrigation, mines or roads.\n\ +5. When The Republic is only one step away, set goal to Navigation.\n\ + When Republic is reached, set research to Map Making and \n\ + immediately start a revolution (from Kingdom menu). Once you're\n\ + a republic, build roads on used squares.\n\ +6. VARIANT: If you get discovered by an enemy, build ships as soon\n\ + as you can, and defending units like warriors and phalanxes if\n\ + necessary. You may choose to collaborate with neighbors, use\n\ + Players menu to find out who to talk to.\n\ +7. When Navigation is only one step away, set goal to Steam Engine.\n\ + When Navigation is reached, build a couple of caravels to explore\n\ + your neighborhood and settle nearby islands. VARIANT: It's often\n\ + useful to research Trade before Steam Engine so you can build\n\ + wonders.\n\ +8. Once most spots on your island are taken, start building roads,\n\ + preferably on grassland and plains. Use the roads to move faster\n\ + and gain trade.\n\ +9. As soon as Steam Engine is reached, build lots of ironclads.\n\ + Increase tax rate to buy them. Accompany them with horsemen on\n\ + caravels. Find neighbors, kill their city defenses with the\n\ + ironclads and invade their cities with the horsemen. Place\n\ + ironclads in conquered cities for initial defense.\n\ +10.After Steam Engine, you may want to research Electricity and\n\ + Steel to get even better ships, destroyers and cruisers. Once\n\ + you got Steel, set tax rate to maximum and put everything into\n\ + war.\n\ +"), _("\ +If you play on the default generator, there are three possibilities:\n\ +\n\ +1. If you have your own island, play like above.\n\ +2. If you have a shared island but your enemies are far away\n\ + or you can have peace with them (which usually is preferable),\n\ + you can play mostly like generator 2, just research horseback\n\ + riding and bronze working right after republic (gives horsemen\n\ + and phalanx).\n\ +3. If your neighbors are close and you can't have peace or alliance,\n\ + research horsemen, monarchy and feudalism to defend. Then play\n\ + like generator 2, only try to attack cities just after you got\n\ + the new offensive unit (horsemen, knights). Consider building\n\ + some Barracks.\n\ + VARIANT: Research horsemen and the republic. Now build diplomats\n\ + and bribe enemy cities of size 1-2 and attacking units. Also\n\ + research map making to allow for surprise attacks off the boat.\n\ + When your opponent is no urgent threat anymore, set your\n\ + science back to maximum and resarch gunpowder or navigation.\n\ +") + [help_connecting] name = _("Connecting") text = _("\ diff -ruN -Xfreeciv/diff_ignore freeciv/server/civserver.c freeciv_build/server/civserver.c --- freeciv/server/civserver.c Fri Sep 1 15:48:59 2000 +++ freeciv_build/server/civserver.c Mon Sep 25 18:25:18 2000 @@ -73,6 +73,9 @@ else if (is_option("--help", argv[inx])) { showhelp = 1; break; + } else if (is_option("--background", argv[inx])) { + srvarg.background = 1; + break; } else if ((option = get_option("--log", argv, &inx, argc)) != NULL) srvarg.log_filename = option; else if ((option = get_option("--gamelog", argv, &inx, argc)) != NULL) @@ -129,6 +132,7 @@ fprintf(stderr, _(" -m, --meta\t\tSend info to metaserver\n")); fprintf(stderr, _(" -M, --Metaserver ADDR\tSet ADDR as metaserver address\n")); fprintf(stderr, _(" -s, --server HOST\tList this server as host HOST\n")); + fprintf(stderr, _(" -b, --background\tStart noninteractively, enable client cmds\n")); #ifdef DEBUG fprintf(stderr, _(" -d, --debug NUM\tSet debug log level (0 to 4," " or 4:file1,min,max:...)\n")); diff -ruN -Xfreeciv/diff_ignore freeciv/server/meta.c freeciv_build/server/meta.c --- freeciv/server/meta.c Tue Aug 22 16:48:04 2000 +++ freeciv_build/server/meta.c Mon Sep 25 18:25:18 2000 @@ -373,8 +373,8 @@ /* Fixme: how should metaserver handle multi-connects? * Uses player_addr_hack() for now. */ - cat_snprintf(info, sizeof(info), "%2d %-20s %s\n", i, pplayer->name, - player_addr_hack(pplayer)); + cat_snprintf(info, sizeof(info), "%2d %-20s %s %s\n", i, pplayer->name, + player_addr_hack(pplayer), pplayer->is_alive?"":"(dead)"); } } diff -ruN -Xfreeciv/diff_ignore freeciv/server/sernet.c freeciv_build/server/sernet.c --- freeciv/server/sernet.c Tue Sep 19 18:06:56 2000 +++ freeciv_build/server/sernet.c Mon Sep 25 18:25:18 2000 @@ -331,7 +331,8 @@ MY_FD_ZERO(&writefs); MY_FD_ZERO(&exceptfs); #ifndef SOCKET_ZERO_ISNT_STDIN - FD_SET(0, &readfs); + if (!srvarg.background) + FD_SET(0, &readfs); #endif FD_SET(sock, &readfs); FD_SET(sock, &exceptfs); @@ -408,7 +409,7 @@ #else /* !HAVE_LIBREADLINE */ int didget; char buf[BUF_SIZE+1]; - + if((didget=read(0, buf, BUF_SIZE))==-1) { freelog(LOG_FATAL, "read from stdin failed"); exit(1); diff -ruN -Xfreeciv/diff_ignore freeciv/server/srv_main.c freeciv_build/server/srv_main.c --- freeciv/server/srv_main.c Tue Sep 19 18:06:56 2000 +++ freeciv_build/server/srv_main.c Mon Sep 25 18:25:18 2000 @@ -220,6 +220,9 @@ if (srvarg.script_filename) read_init_script(srvarg.script_filename); + if (srvarg.background) + handle_stdin_input((struct connection *)NULL, "cmdlevel ctrl"); + /* load a saved game */ if(srvarg.load_filename) { @@ -1703,6 +1706,19 @@ toggle_ai_player_direct(NULL, pplayer); } check_for_full_turn_done(); + } + + if (srvarg.background) { + int i, humans=0; + for(i=0; iconnections)) + humans++; + } + if (humans==0) { + close_connections_and_socket(); + exit(0); + } } } diff -ruN -Xfreeciv/diff_ignore freeciv/server/srv_main.h freeciv_build/server/srv_main.h --- freeciv/server/srv_main.h Tue Aug 22 16:48:06 2000 +++ freeciv_build/server/srv_main.h Mon Sep 25 18:25:18 2000 @@ -36,6 +36,7 @@ char *script_filename; /* server name for metaserver to use for us */ char metaserver_servername[64]; + int background; }; void srv_init(void);