[Freeciv-Dev] Re: (PR#2278) Ping version 12
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: |
undisclosed-recipients:; |
Subject: |
[Freeciv-Dev] Re: (PR#2278) Ping version 12 |
From: |
"Raimar Falke via RT" <rt@xxxxxxxxxxxxxx> |
Date: |
Sat, 9 Nov 2002 04:43:17 -0800 |
Reply-to: |
rt@xxxxxxxxxxxxxx |
On Sat, Nov 09, 2002 at 02:44:55AM -0800, Raimar Falke via RT wrote:
>
>
> This is an updated version of the ping patch from Thomas. Changes:
> - cleanup of the packets
> - remove the timing.[ch] changes
> - adding the pingtime server option
> - a lot of other cleanups
Version 12:
- proper initialization of ping_time
- check for ping_time==-1
- send the ping_info packet only every game.ping_time seconds
- move ping_text construction into plrdlg_common
Raimar
--
email: rf13@xxxxxxxxxxxxxxxxx
"Programming today is a race between software engineers striving to
build bigger and better idiot-proof programs, and the Universe trying
to produce bigger and better idiots. So far, the Universe is winning."
-- Rich Cook
Index: client/civclient.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/civclient.c,v
retrieving revision 1.149
diff -u -r1.149 civclient.c
--- client/civclient.c 9 Oct 2002 13:39:47 -0000 1.149
+++ client/civclient.c 9 Nov 2002 12:38:52 -0000
@@ -456,6 +456,10 @@
handle_thaw_hint();
break;
+ case PACKET_PING_INFO:
+ handle_ping_info((struct packet_ping_info *) packet);
+ break;
+
default:
freelog(LOG_ERROR, "Received unknown packet (type %d) from server!", type);
/* Old clients (<= some 1.11.5-devel, capstr +1.11) used to exit()
Index: client/packhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/packhand.c,v
retrieving revision 1.259
diff -u -r1.259 packhand.c
--- client/packhand.c 7 Nov 2002 18:55:24 -0000 1.259
+++ client/packhand.c 9 Nov 2002 12:38:57 -0000
@@ -1291,6 +1291,7 @@
pconn = fc_calloc(1, sizeof(struct connection));
pconn->buffer = NULL;
pconn->send_buffer = NULL;
+ pconn->ping_time = -1.0;
if (pplayer) {
conn_list_insert_back(&pplayer->connections, pconn);
}
@@ -1317,6 +1318,27 @@
sz_strlcpy(pconn->name, pinfo->name);
sz_strlcpy(pconn->addr, pinfo->addr);
sz_strlcpy(pconn->capability, pinfo->capability);
+ }
+ update_players_dialog();
+}
+
+/*************************************************************************
+...
+**************************************************************************/
+void handle_ping_info(struct packet_ping_info *packet)
+{
+ int i;
+
+ for (i = 0; i < packet->connections; i++) {
+ struct connection *pconn = find_conn_by_id(packet->conn_id[i]);
+
+ if (!pconn) {
+ continue;
+ }
+
+ pconn->ping_time = packet->ping_time[i];
+ freelog(LOG_DEBUG, "conn-id=%d, ping=%fs", pconn->id,
+ pconn->ping_time);
}
update_players_dialog();
}
Index: client/packhand.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/packhand.h,v
retrieving revision 1.29
diff -u -r1.29 packhand.h
--- client/packhand.h 10 Sep 2002 14:01:06 -0000 1.29
+++ client/packhand.h 9 Nov 2002 12:38:57 -0000
@@ -20,6 +20,7 @@
void handle_tile_info(struct packet_tile_info *packet);
void handle_player_info(struct packet_player_info *pinfo);
void handle_conn_info(struct packet_conn_info *pinfo);
+void handle_ping_info(struct packet_ping_info *packet);
void handle_game_info(struct packet_game_info *pinfo);
void handle_map_info(struct packet_map_info *pinfo);
void handle_select_nation(struct packet_nations_used *packet);
Index: client/plrdlg_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/plrdlg_common.c,v
retrieving revision 1.1
diff -u -r1.1 plrdlg_common.c
--- client/plrdlg_common.c 27 Jun 2002 01:00:49 -0000 1.1
+++ client/plrdlg_common.c 9 Nov 2002 12:38:58 -0000
@@ -10,9 +10,17 @@
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
***********************************************************************/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
#include <assert.h>
+#include "connection.h"
+#include "fcintl.h"
+#include "game.h"
+#include "support.h"
+
#include "plrdlg_g.h"
#include "plrdlg_common.h"
@@ -54,4 +62,25 @@
bool is_plrdlg_frozen(void)
{
return frozen_level > 0;
+}
+
+/******************************************************************
+ ...
+*******************************************************************/
+const char *get_ping_time_text(struct player *pplayer)
+{
+ static char buffer[32];
+
+ if (conn_list_size(&pplayer->connections) > 0
+ && conn_list_get(&pplayer->connections, 0)->ping_time != -1.0) {
+ double ping_time_in_ms =
+ 1000 * conn_list_get(&pplayer->connections, 0)->ping_time;
+
+ my_snprintf(buffer, sizeof(buffer), _("%6d.%02d ms"),
+ (int) ping_time_in_ms,
+ ((int) (ping_time_in_ms * 100.0)) % 100);
+ } else {
+ buffer[0] = '\0';
+ }
+ return buffer;
}
Index: client/plrdlg_common.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/plrdlg_common.h,v
retrieving revision 1.1
diff -u -r1.1 plrdlg_common.h
--- client/plrdlg_common.h 27 Jun 2002 01:00:49 -0000 1.1
+++ client/plrdlg_common.h 9 Nov 2002 12:38:58 -0000
@@ -13,11 +13,14 @@
#ifndef FC__PLRDLG_COMMON_H
#define FC__PLRDLG_COMMON_H
+struct player;
+
#include "shared.h" /* bool type */
void plrdlg_freeze(void);
void plrdlg_thaw(void);
void plrdlg_force_thaw(void);
bool is_plrdlg_frozen(void);
+const char *get_ping_time_text(struct player *pplayer);
#endif /* FC__PLRDLG_COMMON_H */
Index: client/gui-gtk/plrdlg.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk/plrdlg.c,v
retrieving revision 1.39
diff -u -r1.39 plrdlg.c
--- client/gui-gtk/plrdlg.c 7 Nov 2002 18:55:25 -0000 1.39
+++ client/gui-gtk/plrdlg.c 9 Nov 2002 12:38:59 -0000
@@ -70,7 +70,7 @@
static void players_list_ucallback(GtkWidget *w, gint row, gint column);
static void players_sship_callback(GtkWidget *w, gpointer data);
-#define NUM_COLUMNS 12 /* number of columns in total */
+#define NUM_COLUMNS 13 /* number of columns in total */
#define DEF_SORT_COLUMN 2 /* default sort column (1 = nation) */
/****************************************************************
@@ -122,7 +122,7 @@
static const char *titles_[NUM_COLUMNS] =
{ N_("Name"), N_("Flag"), N_("Nation"), N_("Team"), N_("Ai"),
N_("Embassy"), N_("Dipl.State"), N_("Vision"), N_("Reputation"),
- N_("State"), N_("Host"), N_("Idle")
+ N_("State"), N_("Host"), N_("Idle"), N_("Ping")
};
static gchar **titles;
int i;
@@ -326,6 +326,7 @@
row[9] = statebuf;
row[10] = (char *) player_addr_hack(&game.players[i]); /* Fixme */
row[11] = idlebuf;
+ row[12] = get_ping_time_text(&game.players[i]);
}
#define MIN_DIMENSION 5
Index: common/connection.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/connection.h,v
retrieving revision 1.23
diff -u -r1.23 connection.h
--- common/connection.h 30 Oct 2002 22:34:03 -0000 1.23
+++ common/connection.h 9 Nov 2002 12:39:01 -0000
@@ -96,8 +96,9 @@
struct socket_packet_buffer *buffer;
struct socket_packet_buffer *send_buffer;
time_t last_write;
- bool ponged; /* have received a PACKET_CONN_PONG? */
+ double ping_time;
+
struct conn_list self; /* list with this connection as single element
*/
char name[MAX_LEN_NAME];
char addr[MAX_LEN_ADDR];
@@ -149,6 +150,10 @@
* Will increase for every received packet.
*/
int last_request_id_seen;
+
+ /* How many PACKET_CONN_PING haven't received a PACKET_CONN_PONG? */
+ int open_pings;
+ struct timer *ping_timer;
} server;
/*
Index: common/game.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/game.c,v
retrieving revision 1.150
diff -u -r1.150 game.c
--- common/game.c 2 Nov 2002 13:33:53 -0000 1.150
+++ common/game.c 9 Nov 2002 12:39:03 -0000
@@ -655,6 +655,7 @@
game.netwait = GAME_DEFAULT_NETWAIT;
game.last_ping = 0;
game.pingtimeout = GAME_DEFAULT_PINGTIMEOUT;
+ game.pingtime = GAME_DEFAULT_PINGTIME;
game.end_year = GAME_DEFAULT_END_YEAR;
game.year = GAME_START_YEAR;
game.turn = 0;
Index: common/game.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/game.h,v
retrieving revision 1.115
diff -u -r1.115 game.h
--- common/game.h 7 Nov 2002 15:32:39 -0000 1.115
+++ common/game.h 9 Nov 2002 12:39:04 -0000
@@ -72,6 +72,7 @@
int netwait;
time_t last_ping;
int pingtimeout;
+ int pingtime;
time_t turn_start;
int end_year;
int year;
@@ -398,6 +399,10 @@
#define GAME_DEFAULT_NETWAIT 4
#define GAME_MIN_NETWAIT 0
#define GAME_MAX_NETWAIT 20
+
+#define GAME_DEFAULT_PINGTIME 20
+#define GAME_MIN_PINGTIME 1
+#define GAME_MAX_PINGTIME 1800
#define GAME_DEFAULT_PINGTIMEOUT 60
#define GAME_MIN_PINGTIMEOUT 60
Index: common/packets.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/packets.c,v
retrieving revision 1.224
diff -u -r1.224 packets.c
--- common/packets.c 7 Nov 2002 18:55:25 -0000 1.224
+++ common/packets.c 9 Nov 2002 12:39:11 -0000
@@ -447,6 +447,9 @@
case PACKET_ATTRIBUTE_CHUNK:
return receive_packet_attribute_chunk(pc);
+ case PACKET_PING_INFO:
+ return receive_packet_ping_info(pc);
+
default:
freelog(LOG_ERROR, "unknown packet type %d received from %s",
type, conn_description(pc));
@@ -805,6 +808,45 @@
dio_get_string(&din, preq->name, sizeof(preq->name));
RECEIVE_PACKET_END(preq);
+}
+
+/*************************************************************************
+This is the ping packet
+**************************************************************************/
+int send_packet_ping_info(struct connection *pc,
+ const struct packet_ping_info *packet)
+{
+ int i;
+ SEND_PACKET_START(PACKET_PING_INFO);
+
+ dio_put_uint8(&dout, packet->connections);
+
+ for (i = 0; i < packet->connections; i++) {
+ dio_put_uint8(&dout, packet->conn_id[i]);
+ dio_put_uint32(&dout, (int) (packet->ping_time[i] * 1e6));
+ }
+
+ SEND_PACKET_END;
+}
+
+/*************************************************************************
+...
+**************************************************************************/
+struct packet_ping_info *receive_packet_ping_info(struct connection *pc)
+{
+ int i;
+ RECEIVE_PACKET_START(packet_ping_info, packet);
+
+ dio_get_uint8(&din, &packet->connections);
+ for (i = 0; i < packet->connections; i++) {
+ int tmp;
+
+ dio_get_uint8(&din, &packet->conn_id[i]);
+ dio_get_uint32(&din, &tmp);
+ packet->ping_time[i] = tmp / 1e6;
+ }
+
+ RECEIVE_PACKET_END(packet);
}
/*************************************************************************
Index: common/packets.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/packets.h,v
retrieving revision 1.128
diff -u -r1.128 packets.h
--- common/packets.h 7 Nov 2002 18:55:25 -0000 1.128
+++ common/packets.h 9 Nov 2002 12:39:13 -0000
@@ -128,6 +128,7 @@
PACKET_SELECT_NATION_OK,
PACKET_FREEZE_HINT,
PACKET_THAW_HINT,
+ PACKET_PING_INFO,
PACKET_LAST /* leave this last */
};
@@ -505,6 +506,15 @@
char capability[MAX_LEN_CAPSTR];
};
+/***************
+ Ping packet
+***************/
+struct packet_ping_info {
+ int connections;
+ int conn_id[MAX_NUM_PLAYERS];
+ double ping_time[MAX_NUM_PLAYERS];
+};
+
/*********************************************************
The server tells the client all about a spaceship:
*********************************************************/
@@ -940,6 +950,9 @@
const struct packet_game_info *pinfo);
struct packet_game_info *receive_packet_game_info(struct connection *pc);
+int send_packet_ping_info(struct connection *pc,
+ const struct packet_ping_info *packet);
+struct packet_ping_info *receive_packet_ping_info(struct connection *pc);
struct packet_player_info *receive_packet_player_info(struct connection *pc);
int send_packet_player_info(struct connection *pc,
Index: common/packets_lsend.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/packets_lsend.c,v
retrieving revision 1.12
diff -u -r1.12 packets_lsend.c
--- common/packets_lsend.c 25 Aug 2002 11:20:59 -0000 1.12
+++ common/packets_lsend.c 9 Nov 2002 12:39:13 -0000
@@ -81,6 +81,14 @@
conn_list_iterate_end;
}
+void lsend_packet_ping_info(struct conn_list *dest,
+ const struct packet_ping_info *packet)
+{
+ conn_list_iterate(*dest, pconn)
+ send_packet_ping_info(pconn, packet);
+ conn_list_iterate_end;
+}
+
void lsend_packet_player_info(struct conn_list *dest,
const struct packet_player_info *pinfo)
{
Index: common/packets_lsend.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/packets_lsend.h,v
retrieving revision 1.11
diff -u -r1.11 packets_lsend.h
--- common/packets_lsend.h 25 Aug 2002 11:20:59 -0000 1.11
+++ common/packets_lsend.h 9 Nov 2002 12:39:14 -0000
@@ -32,6 +32,8 @@
const struct packet_map_info *pinfo);
void lsend_packet_game_info(struct conn_list *dest,
const struct packet_game_info *pinfo);
+void lsend_packet_ping_info(struct conn_list *dest,
+ const struct packet_ping_info *packet);
void lsend_packet_player_info(struct conn_list *dest,
const struct packet_player_info *pinfo);
void lsend_packet_conn_info(struct conn_list *dest,
Index: po/POTFILES.in
===================================================================
RCS file: /home/freeciv/CVS/freeciv/po/POTFILES.in,v
retrieving revision 1.56
diff -u -r1.56 POTFILES.in
--- po/POTFILES.in 16 Oct 2002 23:03:19 -0000 1.56
+++ po/POTFILES.in 9 Nov 2002 12:39:15 -0000
@@ -50,6 +50,7 @@
client/helpdata.c
client/options.c
client/packhand.c
+client/plrdlg_common.c
client/tilespec.c
client/agents/cma_core.c
client/agents/cma_fec.c
Index: server/sernet.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/sernet.c,v
retrieving revision 1.97
diff -u -r1.97 sernet.c
--- server/sernet.c 7 Nov 2002 16:04:55 -0000 1.97
+++ server/sernet.c 9 Nov 2002 12:39:17 -0000
@@ -75,6 +75,7 @@
#include "meta.h"
#include "srv_main.h"
#include "stdinhand.h"
+#include "timing.h"
#include "sernet.h"
@@ -111,6 +112,8 @@
static void start_processing_request(struct connection *pconn,
int request_id);
static void finish_processing_request(struct connection *pconn);
+static void ping_connection(struct connection *pconn);
+static void send_ping_times_to_all(void);
static bool no_input = FALSE;
@@ -392,22 +395,35 @@
}
}
- /* send PACKET_CONN_PING & cut mute players */
- if ((time(NULL)>game.last_ping + game.pingtimeout)) {
- for(i=0; i<MAX_NUM_CONNECTIONS; i++) {
- struct connection *pconn = &connections[i];
- if (pconn->used) {
- send_packet_generic_empty(pconn, PACKET_CONN_PING);
+ /* Pinging around for statistics*/
+ if (time(NULL) > (game.last_ping + game.pingtime)) {
+ int open_pings_to_cut = game.pingtimeout / game.pingtime;
- if (pconn->ponged) {
- pconn->ponged = FALSE;
- } else {
- freelog(LOG_NORMAL, "cut connection %s due to ping timeout",
- conn_description(pconn));
- close_socket_callback(pconn);
- }
- }
+ if (open_pings_to_cut == 0) {
+ open_pings_to_cut = 1;
}
+
+ /* send data about the previous run */
+ send_ping_times_to_all();
+
+ conn_list_iterate(game.game_connections, pconn) {
+ if (!pconn->used) {
+ continue;
+ }
+
+ /* lazy init of ping timer */
+ if (!pconn->server.ping_timer) {
+ pconn->server.ping_timer = new_timer_start(TIMER_USER, TIMER_ACTIVE);
+ }
+
+ if (pconn->server.open_pings >= open_pings_to_cut) {
+ /* cut mute players */
+ freelog(LOG_NORMAL, "cut connection %s due to ping timeout",
+ conn_description(pconn));
+ close_socket_callback(pconn);
+ }
+ ping_connection(pconn);
+ } conn_list_iterate_end;
game.last_ping = time(NULL);
}
@@ -699,7 +715,6 @@
pconn->buffer = new_socket_packet_buffer();
pconn->send_buffer = new_socket_packet_buffer();
pconn->last_write = 0;
- pconn->ponged = TRUE;
pconn->first_packet = TRUE;
pconn->byte_swap = FALSE;
pconn->capability[0] = '\0';
@@ -708,6 +723,9 @@
pconn->notify_of_writable_data = NULL;
pconn->server.currently_processed_request_id = 0;
pconn->server.last_request_id_seen = 0;
+ pconn->server.open_pings = 0;
+ pconn->server.ping_timer = NULL;
+ pconn->ping_time = -1.0;
pconn->incoming_packet_notify = NULL;
pconn->outgoing_packet_notify = NULL;
@@ -818,4 +836,54 @@
pconn->server.currently_processed_request_id, pconn->id);
send_packet_generic_empty(pconn, PACKET_PROCESSING_FINISHED);
pconn->server.currently_processed_request_id = 0;
+}
+
+/**************************************************************************
+This is the ping function
+**************************************************************************/
+static void ping_connection(struct connection *pconn)
+{
+ pconn->server.open_pings++;
+ clear_timer_start(pconn->server.ping_timer);
+ send_packet_generic_empty(pconn, PACKET_CONN_PING);
+}
+
+/**************************************************************************
+This is the pong function
+**************************************************************************/
+void handle_conn_pong(struct connection *pconn)
+{
+ pconn->server.open_pings--;
+ stop_timer(pconn->server.ping_timer);
+ pconn->ping_time = read_timer_seconds(pconn->server.ping_timer);
+}
+
+/**************************************************************************
+...
+**************************************************************************/
+static void send_ping_times_to_all(void)
+{
+ struct packet_ping_info packet;
+ int i;
+
+ i = 0;
+ conn_list_iterate(game.game_connections, pconn) {
+ if (!pconn->used) {
+ continue;
+ }
+ i++;
+ } conn_list_iterate_end;
+
+ packet.connections = i;
+
+ i = 0;
+ conn_list_iterate(game.game_connections, pconn) {
+ if (!pconn->used) {
+ continue;
+ }
+ packet.conn_id[i] = pconn->id;
+ packet.ping_time[i] = pconn->ping_time;
+ i++;
+ } conn_list_iterate_end;
+ lsend_packet_ping_info(&game.est_connections, &packet);
}
Index: server/sernet.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/sernet.h,v
retrieving revision 1.7
diff -u -r1.7 sernet.h
--- server/sernet.h 18 Sep 2000 20:36:15 -0000 1.7
+++ server/sernet.h 9 Nov 2002 12:39:17 -0000
@@ -25,5 +25,6 @@
void close_connections_and_socket(void);
void init_connections(void);
void close_connection(struct connection *pconn);
+void handle_conn_pong(struct connection *pconn);
#endif /* FC__SERNET_H */
Index: server/srv_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/srv_main.c,v
retrieving revision 1.102
diff -u -r1.102 srv_main.c
--- server/srv_main.c 7 Nov 2002 18:55:26 -0000 1.102
+++ server/srv_main.c 9 Nov 2002 12:39:21 -0000
@@ -913,7 +913,7 @@
handle_patrol_route(pplayer, (struct packet_goto_route *)packet);
break;
case PACKET_CONN_PONG:
- pconn->ponged = TRUE;
+ handle_conn_pong(pconn);
break;
case PACKET_UNIT_AIRLIFT:
handle_unit_airlift(pplayer, (struct packet_unit_request *)packet);
Index: server/stdinhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/stdinhand.c,v
retrieving revision 1.261
diff -u -r1.261 stdinhand.c
--- server/stdinhand.c 7 Nov 2002 18:55:26 -0000 1.261
+++ server/stdinhand.c 9 Nov 2002 12:39:30 -0000
@@ -726,11 +726,15 @@
"wait at all."), NULL,
GAME_MIN_NETWAIT, GAME_MAX_NETWAIT, GAME_DEFAULT_NETWAIT)
- GEN_INT("pingtimeout", game.pingtimeout, SSET_META, SSET_TO_CLIENT,
- N_("Maximum seconds between PINGs"),
+ GEN_INT("pingtime", game.pingtime, SSET_META, SSET_TO_CLIENT,
+ N_("Seconds between PINGs"),
N_("The civserver will poll the clients with a PING request "
- "each time this period elapses. If a client doesn't reply "
- "with a PONG before the next server PING request the "
+ "each time this period elapses."), NULL,
+ GAME_MIN_PINGTIME, GAME_MAX_PINGTIME, GAME_DEFAULT_PINGTIME)
+
+ GEN_INT("pingtimeout", game.pingtimeout, SSET_META, SSET_TO_CLIENT,
+ N_("Time to cut a client"),
+ N_("If a client doesn't reply to a PONG in this time the "
"client is disconnected."), NULL,
GAME_MIN_PINGTIMEOUT, GAME_MAX_PINGTIMEOUT, GAME_DEFAULT_PINGTIMEOUT)
Message not available
- [Freeciv-Dev] Re: (PR#2278) Ping version 12,
Raimar Falke via RT <=
- Message not available
- [Freeciv-Dev] Re: (PR#2278) Ping version 12, Thomas Strub via RT, 2002/11/09
- Message not available
- [Freeciv-Dev] Re: (PR#2278) Ping version 13, Raimar Falke via RT, 2002/11/10
- [Freeciv-Dev] Re: (PR#2278) Ping version 13, Thomas Strub, 2002/11/10
- Message not available
- [Freeciv-Dev] Re: (PR#2278) Ping version 13, Thomas Strub via RT, 2002/11/10
- [Freeciv-Dev] Re: (PR#2278) Ping version 13, Raimar Falke, 2002/11/10
- Message not available
- [Freeciv-Dev] Re: (PR#2278) Ping version 13, Raimar Falke via RT, 2002/11/10
- [Freeciv-Dev] Re: (PR#2278) Ping version 13, Thomas Strub, 2002/11/10
- Message not available
- [Freeciv-Dev] Re: (PR#2278) Ping version 13, Thomas Strub via RT, 2002/11/10
- Message not available
- [Freeciv-Dev] Re: (PR#2278) Ping version 13, Raimar Falke via RT, 2002/11/10
- [Freeciv-Dev] Re: (PR#2278) Ping version 13, Thomas Strub, 2002/11/10
|
|