Complete.Org: Mailing Lists: Archives: freeciv-dev: January 2005:
[Freeciv-Dev] (PR#11816) Patch: ruleset listing and gtk2 setting
Home

[Freeciv-Dev] (PR#11816) Patch: ruleset listing and gtk2 setting

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [Freeciv-Dev] (PR#11816) Patch: ruleset listing and gtk2 setting
From: "Daniel L Speyer" <dspeyer@xxxxxxxxxxx>
Date: Wed, 5 Jan 2005 21:53:56 -0800
Reply-to: bugs@xxxxxxxxxxx

<URL: http://bugs.freeciv.org/Ticket/Display.html?id=11816 >

At present, just about everything can be done graphically from the gtk-2 
client except change ruleset.  Here is a patch to include that.  It uses a 
gtk_combo, so the user can select from a list or enter manually (though, 
if I understand the server correctly, the only reason to enter manually 
would be if a ruleset were added after game-start).  Non-gtk2 users can 
get the same functionality from the find_rulesets command.

The patch modifies packets, so remember to generate_packets.py after 
applying.

As always, I welcome, comments, suggestions, questions and flames.

--Daniel Speyer
PS. Yes, it's been a long time -- real life got very busy last semester -- 
but I should be around for a while now.

diff -ur freeciv-2.0.0-beta6/client/gui-ftwl/pages.c 
freeciv-2.0.0-beta6-mine/client/gui-ftwl/pages.c
--- freeciv-2.0.0-beta6/client/gui-ftwl/pages.c 2004-10-20 13:38:21.000000000 
-0400
+++ freeciv-2.0.0-beta6-mine/client/gui-ftwl/pages.c    2005-01-05 
23:08:36.000000000 -0500
@@ -26,3 +26,7 @@
   /* PORTME */
 }
 
+void gui_set_rulesets(char rulesets[][64], int ruleset_count)
+{
+  /* PORTME */
+}
diff -ur freeciv-2.0.0-beta6/client/gui-gtk/pages.c 
freeciv-2.0.0-beta6-mine/client/gui-gtk/pages.c
--- freeciv-2.0.0-beta6/client/gui-gtk/pages.c  2004-10-20 13:38:21.000000000 
-0400
+++ freeciv-2.0.0-beta6-mine/client/gui-gtk/pages.c     2005-01-05 
23:08:00.000000000 -0500
@@ -26,3 +26,7 @@
   /* PORTME */
 }
 
+void gui_set_rulesets(char rulesets[][64], int ruleset_count)
+{
+  /* PORTME */
+}
diff -ur freeciv-2.0.0-beta6/client/gui-gtk-2.0/pages.c 
freeciv-2.0.0-beta6-mine/client/gui-gtk-2.0/pages.c
--- freeciv-2.0.0-beta6/client/gui-gtk-2.0/pages.c      2004-11-23 
10:39:49.000000000 -0500
+++ freeciv-2.0.0-beta6-mine/client/gui-gtk-2.0/pages.c 2005-01-05 
23:07:29.000000000 -0500
@@ -66,6 +66,7 @@
 static GQueue *statusbar_queue;
 static guint statusbar_timer = 0;
 
+static GtkWidget *ruleset_combo;
 
 /**************************************************************************
   spawn a server, if there isn't one, using the default settings.
@@ -882,6 +883,20 @@
 }
 
 /**************************************************************************
+  Ruleset setting callback
+**************************************************************************/
+static void ruleset_callback(GtkWidget *w, gpointer data)
+{
+  const char *name;
+  char buf[512];
+
+  name = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(ruleset_combo)->entry));
+
+  my_snprintf(buf, sizeof(buf), "/ruleset %s", name);
+  send_chat(buf);
+}
+
+/**************************************************************************
   AI fill setting callback.
 **************************************************************************/
 static void ai_fill_callback(GtkWidget *w, gpointer data)
@@ -928,7 +943,7 @@
   vbox = gtk_vbox_new(FALSE, 2);
   gtk_container_add(GTK_CONTAINER(align), vbox);
 
-  table = gtk_table_new(2, 2, FALSE);
+  table = gtk_table_new(2, 3, FALSE);
   start_options_table = table;
   gtk_table_set_row_spacings(GTK_TABLE(table), 2);
   gtk_table_set_col_spacings(GTK_TABLE(table), 12);
@@ -977,6 +992,22 @@
                        NULL);
   gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2);
 
+  ruleset_combo = gtk_combo_new();
+  gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(ruleset_combo)->entry), "default");
+  g_signal_connect(GTK_COMBO(ruleset_combo)->entry, "changed",
+                  G_CALLBACK(ruleset_callback), GUINT_TO_POINTER(i));
+
+  gtk_table_attach_defaults(GTK_TABLE(table), ruleset_combo, 1, 2, 2, 3);
+
+  label = g_object_new(GTK_TYPE_LABEL,
+                      "use-underline", TRUE,
+                      "mnemonic-widget", GTK_COMBO(ruleset_combo)->entry,
+                       "label", _("_Ruleset:"),
+                       "xalign", 0.0,
+                       "yalign", 0.5,
+                       NULL);
+  gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 2, 3);
+
   align = gtk_alignment_new(0.5, 0.5, 0.0, 0.0);
   button = gtk_stockbutton_new(GTK_STOCK_PREFERENCES,
       _("More Game _Options..."));
@@ -1877,3 +1908,19 @@
   gtk_window_present(GTK_WINDOW(save_dialog_shell));
 }
 
+void gui_set_rulesets(char rulesets[][64], int ruleset_count)
+{
+  int i;
+  int has_default=0;
+  GList *opts = NULL;
+  for (i=0; i<ruleset_count; i++){
+    if (!strcmp(rulesets[i],"default"))
+      has_default=1;
+    opts=g_list_append(opts, rulesets[i]);
+  }
+  gtk_combo_set_popdown_strings(GTK_COMBO(ruleset_combo), opts);
+  if (has_default)
+    gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(ruleset_combo)->entry), "default");
+  g_list_free(opts);
+}
+
diff -ur freeciv-2.0.0-beta6/client/gui-mui/connectdlg.c 
freeciv-2.0.0-beta6-mine/client/gui-mui/connectdlg.c
--- freeciv-2.0.0-beta6/client/gui-mui/connectdlg.c     2004-11-20 
16:03:18.000000000 -0500
+++ freeciv-2.0.0-beta6-mine/client/gui-mui/connectdlg.c        2005-01-05 
23:09:17.000000000 -0500
@@ -322,3 +322,7 @@
   try_to_autoconnect();
 }
 
+void gui_set_rulesets(char rulesets[][64], int ruleset_count)
+{
+  /* PORTME */
+}
diff -ur freeciv-2.0.0-beta6/client/gui-stub/pages.c 
freeciv-2.0.0-beta6-mine/client/gui-stub/pages.c
--- freeciv-2.0.0-beta6/client/gui-stub/pages.c 2004-10-20 13:38:21.000000000 
-0400
+++ freeciv-2.0.0-beta6-mine/client/gui-stub/pages.c    2005-01-05 
23:09:32.000000000 -0500
@@ -26,3 +26,7 @@
   /* PORTME */
 }
 
+void gui_set_rulesets(char rulesets[][64], int ruleset_count)
+{
+  /* PORTME */
+}
diff -ur freeciv-2.0.0-beta6/client/include/connectdlg_g.h 
freeciv-2.0.0-beta6-mine/client/include/connectdlg_g.h
--- freeciv-2.0.0-beta6/client/include/connectdlg_g.h   2004-04-09 
23:47:49.000000000 -0400
+++ freeciv-2.0.0-beta6-mine/client/include/connectdlg_g.h      2005-01-05 
23:20:03.099173560 -0500
@@ -19,4 +19,6 @@
 void gui_server_connect(void);
 void server_autoconnect(void);
 
+void gui_set_rulesets(char rulesets[][64], int ruleset_count);
+
 #endif  /* FC__CONNECTDLG_G_H */
diff -ur freeciv-2.0.0-beta6/client/packhand.c 
freeciv-2.0.0-beta6-mine/client/packhand.c
--- freeciv-2.0.0-beta6/client/packhand.c       2004-12-14 19:13:24.000000000 
-0500
+++ freeciv-2.0.0-beta6-mine/client/packhand.c  2005-01-05 21:34:36.000000000 
-0500
@@ -161,29 +161,27 @@
 /**************************************************************************
 ...
 **************************************************************************/
-void handle_server_join_reply(bool you_can_join, char *message,
-                              char *capability, char *challenge_file,
-                              int conn_id)
+void handle_server_join_reply(struct packet_server_join_reply *packet)
 {
   char msg[MAX_LEN_MSG];
   char *s_capability = aconnection.capability;
 
-  sz_strlcpy(aconnection.capability, capability);
+  sz_strlcpy(aconnection.capability, packet->capability);
   close_connection_dialog();
 
-  if (you_can_join) {
-    freelog(LOG_VERBOSE, "join game accept:%s", message);
+  if (packet->you_can_join) {
+    freelog(LOG_VERBOSE, "join game accept:%s", packet->message);
     aconnection.established = TRUE;
-    aconnection.id = conn_id;
+    aconnection.id = packet->conn_id;
     agents_game_joined();
     update_menus();
     set_client_page(PAGE_START);
-
+    gui_set_rulesets(packet->rulesets, packet->ruleset_count);
     /* we could always use hack, verify we're local */ 
-    send_client_wants_hack(challenge_file);
+    send_client_wants_hack(packet->challenge_file);
   } else {
     my_snprintf(msg, sizeof(msg),
-               _("You were rejected from the game: %s"), message);
+               _("You were rejected from the game: %s"), packet->message);
     append_output_window(msg);
     aconnection.id = 0;
     if (auto_connect) {
diff -ur freeciv-2.0.0-beta6/common/packets.def 
freeciv-2.0.0-beta6-mine/common/packets.def
--- freeciv-2.0.0-beta6/common/packets.def      2004-12-10 18:12:08.000000000 
-0500
+++ freeciv-2.0.0-beta6-mine/common/packets.def 2005-01-05 20:59:27.000000000 
-0500
@@ -83,6 +83,8 @@
 
      handle-via-packet: force the packet type of the handle
      function. Otherwise the fields are passed to the handle function.
+     This is invoked automatically for packets with more than 5 fields
+     or packets whose names are of the form foo_ruleset.
 
      handle-per-conn: normally the first parameter of the handle
      function is the player. handle-per-conn changes this to the
@@ -258,6 +260,8 @@
   STRING challenge_file[MAX_LEN_PATH];
   # clients conn id as known in server
   CONNECTION conn_id;
+  UINT8 ruleset_count;
+  STRING rulesets[16:ruleset_count][64];
 end
 
 PACKET_AUTHENTICATION_REQ=6;sc,handle-per-conn,dsend
diff -ur freeciv-2.0.0-beta6/server/commands.c 
freeciv-2.0.0-beta6-mine/server/commands.c
--- freeciv-2.0.0-beta6/server/commands.c       2004-12-24 04:29:48.000000000 
-0500
+++ freeciv-2.0.0-beta6-mine/server/commands.c  2005-01-05 16:21:59.000000000 
-0500
@@ -140,6 +140,11 @@
       "vision and embassies, and fight together to achieve team victory "
       "with averaged individual scores.")
   },
+  {"findrulesetdir", ALLOW_CTRL,
+   N_("findrulesetdir"),
+   N_("List available ruleset directories and modpacks."),
+   NULL
+  },
   {"rulesetdir", ALLOW_CTRL,
    N_("rulesetdir <directory>"),
    N_("Choose new ruleset directory or modpack."),
diff -ur freeciv-2.0.0-beta6/server/commands.h 
freeciv-2.0.0-beta6-mine/server/commands.h
--- freeciv-2.0.0-beta6/server/commands.h       2004-12-24 04:29:48.000000000 
-0500
+++ freeciv-2.0.0-beta6-mine/server/commands.h  2005-01-05 16:20:45.000000000 
-0500
@@ -47,6 +47,7 @@
   CMD_DEBUG,
   CMD_SET,
   CMD_TEAM,
+  CMD_FIND_RULESETDIR,
   CMD_RULESETDIR,
   CMD_METAMESSAGE,
   CMD_METATOPIC,
diff -ur freeciv-2.0.0-beta6/server/connecthand.c 
freeciv-2.0.0-beta6-mine/server/connecthand.c
--- freeciv-2.0.0-beta6/server/connecthand.c    2004-12-09 11:37:32.000000000 
-0500
+++ freeciv-2.0.0-beta6-mine/server/connecthand.c       2005-01-05 
20:46:30.000000000 -0500
@@ -74,6 +74,7 @@
   struct player *pplayer;
   struct packet_server_join_reply packet;
   char hostname[512];
+  char **rulesets;
 
   /* zero out the password */
   memset(pconn->server.password, 0, sizeof(pconn->server.password));
@@ -85,6 +86,10 @@
               pconn->username);
   sz_strlcpy(packet.challenge_file, new_challenge_filename(pconn));
   packet.conn_id = pconn->id;
+  rulesets = find_rulesetdirs();
+  for (packet.ruleset_count=0; rulesets[packet.ruleset_count][0]; 
packet.ruleset_count++) {
+    strcpy(packet.rulesets[packet.ruleset_count], 
rulesets[packet.ruleset_count]);
+  }
   send_packet_server_join_reply(pconn, &packet);
 
   /* "establish" the connection */
@@ -197,6 +202,7 @@
   sz_strlcpy(packet.message, msg);
   packet.challenge_file[0] = '\0';
   packet.conn_id = -1;
+  packet.ruleset_count = 0;
   send_packet_server_join_reply(pconn, &packet);
   freelog(LOG_NORMAL, _("Client rejected: %s."), conn_description(pconn));
   flush_connection_send_buffer_all(pconn);
diff -ur freeciv-2.0.0-beta6/server/stdinhand.c 
freeciv-2.0.0-beta6-mine/server/stdinhand.c
--- freeciv-2.0.0-beta6/server/stdinhand.c      2005-01-01 18:31:15.000000000 
-0500
+++ freeciv-2.0.0-beta6-mine/server/stdinhand.c 2005-01-05 20:18:30.000000000 
-0500
@@ -16,6 +16,7 @@
 #endif
 
 #include <assert.h>
+#include <dirent.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -94,6 +95,7 @@
 static bool detach_command(struct connection *caller, char *name, bool check);
 static bool start_command(struct connection *caller, char *name, bool check);
 static bool end_command(struct connection *caller, char *str, bool check);
+static bool cmd_find_rulesetdir(struct connection *caller);
 
 enum vote_type {
   VOTE_NONE, VOTE_UNUSED, VOTE_YES, VOTE_NO
@@ -3172,6 +3174,100 @@
   return TRUE;
 }
 
+char ** find_rulesetdirs()
+{
+  const char **path = get_data_dirs(NULL);
+  static char *out[32] = {0};
+  static int nout = -1;
+  int i, j;
+
+  if (nout > -1) {
+    return out;
+  }
+  nout=0;
+
+  for (i=0; i<32; i++) {
+    out[i]=malloc(64*sizeof(char));
+  }
+  nout=0;
+  out[0][0]=0;
+
+
+  for(;*path;path++) {
+    DIR *dir;
+    struct dirent *possib;
+    dir=opendir(*path);
+    if (!dir)
+      continue;
+    while( (possib=readdir(dir)) ) {
+      char possibpath[128];
+      char possibname[64];
+      DIR *posdir;
+      struct dirent *ruleset;
+      strcpy(possibpath, *path);
+      strcat(possibpath, "/");
+      strcat(possibpath, possib->d_name);
+      strcpy(possibname, possib->d_name);
+      posdir=opendir(possibpath);
+      if (!posdir)
+       continue;
+      while( (ruleset=readdir(posdir)) ){
+       if (!strcmp(ruleset->d_name+strlen(ruleset->d_name)-8, ".ruleset")){
+         FILE *rsf;
+         char rsp[128], line[64];
+         strcpy(rsp,possibpath);
+         strcat(rsp,"/");
+         strcat(rsp,ruleset->d_name);
+         rsf=fopen(rsp,"r");
+         fread(line, sizeof(char), 64, rsf);
+         fclose(rsf);
+         if (!strchr(line,'[') || strncmp(strchr(line,'['), "[nation",7)){
+           strcpy(out[nout++],possibname);
+           out[nout][0]=0;
+           break;
+         }
+       } 
+      }
+    }
+  }
+  qsort(out, nout, sizeof(char*), compare_strings_ptrs);
+
+  i = j = 0;
+  while (j < nout) {
+    char *this = out[j];
+
+    for (j++; j < nout && strcmp(this, out[j]) == 0; j++) {
+      out[j][0]=0;
+    }
+
+    out[i] = this;
+
+    i++;
+  }
+
+  nout=i;
+  out[nout][0]=0;
+
+  return out;
+}
+
+static bool cmd_find_rulesetdir(struct connection *caller)
+{
+  char **paths=find_rulesetdirs();
+  if (!**paths){
+    cmd_reply(CMD_FIND_RULESETDIR, caller, C_FAIL,
+             _("No Rulesets found"));
+    return FALSE;
+  }
+  cmd_reply(CMD_FIND_RULESETDIR, caller, C_OK,
+           _("Available rulesets are"));
+  for (;**paths;paths++){
+    cmd_reply(CMD_FIND_RULESETDIR, caller, C_OK,
+             _("  %s"), *paths);
+  }
+  return TRUE;
+}
+
 /**************************************************************************
   ...
 **************************************************************************/
@@ -3433,6 +3529,8 @@
     return set_command(caller, arg, check);
   case CMD_TEAM:
     return team_command(caller, arg, check);
+  case CMD_FIND_RULESETDIR:
+    return cmd_find_rulesetdir(caller);
   case CMD_RULESETDIR:
     return set_rulesetdir(caller, arg, check);
   case CMD_SCORE:
diff -ur freeciv-2.0.0-beta6/server/stdinhand.h 
freeciv-2.0.0-beta6-mine/server/stdinhand.h
--- freeciv-2.0.0-beta6/server/stdinhand.h      2004-12-09 11:37:33.000000000 
-0500
+++ freeciv-2.0.0-beta6-mine/server/stdinhand.h 2005-01-05 20:46:00.000000000 
-0500
@@ -52,4 +52,6 @@
 #endif
 #endif
 
+char ** find_rulesetdirs();
+
 #endif /* FC__STDINHAND_H */
diff -ur freeciv-2.0.0-beta6/utility/shared.c 
freeciv-2.0.0-beta6-mine/utility/shared.c
--- freeciv-2.0.0-beta6/utility/shared.c        2005-01-01 16:05:57.000000000 
-0500
+++ freeciv-2.0.0-beta6-mine/utility/shared.c   2005-01-05 16:27:14.000000000 
-0500
@@ -795,7 +795,7 @@
 
   num_dirs, if not NULL, will be set to the number of entries in the list.
 ***************************************************************************/
-static const char **get_data_dirs(int *num_dirs)
+const char **get_data_dirs(int *num_dirs)
 {
   const char *path;
   char *path2, *tok;
diff -ur freeciv-2.0.0-beta6/utility/shared.h 
freeciv-2.0.0-beta6-mine/utility/shared.h
--- freeciv-2.0.0-beta6/utility/shared.h        2004-12-08 18:12:53.000000000 
-0500
+++ freeciv-2.0.0-beta6-mine/utility/shared.h   2005-01-05 16:27:16.000000000 
-0500
@@ -282,5 +282,8 @@
 
 bool make_dir(const char *pathname);
 bool path_is_absolute(const char *filename);
+
+const char **get_data_dirs(int *num_dirs);
+
 #endif  /* FC__SHARED_H */
 

[Prev in Thread] Current Thread [Next in Thread]