Complete.Org: Mailing Lists: Archives: freeciv-dev: September 2003:
[Freeciv-Dev] Re: (PR#6305) New server command: debug
Home

[Freeciv-Dev] Re: (PR#6305) New server command: debug

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients: ;
Subject: [Freeciv-Dev] Re: (PR#6305) New server command: debug
From: "Per I. Mathisen" <per@xxxxxxxxxxx>
Date: Sun, 28 Sep 2003 02:29:12 -0700
Reply-to: rt@xxxxxxxxxxxxxx

Another version of debug1 and debug2.

debug2b: Contained some cruft, removed (thanks, Greg).

debug1e: Unified & fixed usage string. Free arg[] after we are done
(thanks, Mike).

I noticed that team_command() also does not free its arg[]. Not fixed in
this patch.

I think these two patches are ready to go in. Greg, will you?

  - Per

Index: ai/ailog.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/ailog.c,v
retrieving revision 1.7
diff -u -r1.7 ailog.c
--- ai/ailog.c  17 Jul 2003 18:56:50 -0000      1.7
+++ ai/ailog.c  27 Sep 2003 23:09:11 -0000
@@ -96,44 +100,6 @@
 }
 
 /**************************************************************************
-  Log goto message if the goto fails. They will appear like this
-    2: a's Explorer[105] on GOTO (3,25)->(5,23) failed : exploring territory
-**************************************************************************/
-void GOTO_LOG(int level, struct unit *punit, enum goto_result result, 
-              const char *msg, ...)
-{
-  int minlevel = MIN(LOGLEVEL_GOTO, level);
-
-  if (minlevel <= fc_log_level && (result == GR_FAILED || result == 
GR_FOUGHT)) {
-    char buffer[500];
-    char buffer2[500];
-    va_list ap;
-    int gx, gy;
-
-    if (is_goto_dest_set(punit)) {
-      gx = goto_dest_x(punit);
-      gy = goto_dest_y(punit);
-    } else {
-      gx = gy = -1;
-    }
-
-    my_snprintf(buffer, sizeof(buffer),
-                "%s's %s[%d] on GOTO (%d,%d)->(%d,%d) %s : ",
-                unit_owner(punit)->name, unit_type(punit)->name,
-                punit->id, punit->x, punit->y,
-               gx, gy,
-               (result == GR_FAILED) ? "failed" : "fought");
-
-    va_start(ap, msg);
-    my_vsnprintf(buffer2, sizeof(buffer2), msg, ap);
-    va_end(ap);
-
-    cat_snprintf(buffer, sizeof(buffer), buffer2);
-    freelog(minlevel, buffer);
-  }
-}
-
-/**************************************************************************
   Log message for bodyguards. They will appear like this
     2: ai4's bodyguard Mech. Inf.[485] (38,22){Riflemen:574@37,23} was ...
   note that these messages are likely to wrap if long.
Index: ai/ailog.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/ailog.h,v
retrieving revision 1.3
diff -u -r1.3 ailog.h
--- ai/ailog.h  15 Nov 2002 22:15:01 -0000      1.3
+++ ai/ailog.h  27 Sep 2003 23:09:11 -0000
@@ -30,8 +30,6 @@
 
 void CITY_LOG(int level, struct city *pcity, const char *msg, ...);
 void UNIT_LOG(int level, struct unit *punit, const char *msg, ...);
-void GOTO_LOG(int level, struct unit *punit, enum goto_result result,
-              const char *msg, ...);
 void BODYGUARD_LOG(int level, struct unit *punit, const char *msg);
 
 #endif  /* FC__AILOG_H */
Index: ai/ailog.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/ailog.c,v
retrieving revision 1.7
diff -u -r1.7 ailog.c
--- ai/ailog.c  17 Jul 2003 18:56:50 -0000      1.7
+++ ai/ailog.c  28 Sep 2003 09:23:38 -0000
@@ -40,7 +40,9 @@
   va_list ap;
   int minlevel = MIN(LOGLEVEL_CITY, level);
 
-  if (minlevel > fc_log_level) {
+  if (pcity->debug) {
+    minlevel = LOG_NORMAL;
+  } else if (minlevel > fc_log_level) {
     return;
   }
 
@@ -60,7 +62,9 @@
 
 /**************************************************************************
   Log unit messages, they will appear like this
-    2: c's Archers[139] (5,35)->(0,0){0} stays to defend city
+    2: c's Archers[139] (5,35)->(0,0){0,0} stays to defend city
+  where [] is unit id, ()->() are coordinates present and goto, and
+  {,} contains bodyguard and ferryboat ids.
 **************************************************************************/
 void UNIT_LOG(int level, struct unit *punit, const char *msg, ...)
 {
@@ -70,7 +74,9 @@
   int minlevel = MIN(LOGLEVEL_UNIT, level);
   int gx, gy;
 
-  if (minlevel > fc_log_level) {
+  if (punit->debug) {
+    minlevel = LOG_NORMAL;
+  } else if (minlevel > fc_log_level) {
     return;
   }
 
@@ -81,11 +87,11 @@
     gx = gy = -1;
   }
   
-  my_snprintf(buffer, sizeof(buffer), "%s's %s[%d] (%d,%d)->(%d,%d){%d} ",
+  my_snprintf(buffer, sizeof(buffer), "%s's %s[%d] (%d,%d)->(%d,%d){%d,%d} ",
               unit_owner(punit)->name, unit_type(punit)->name,
               punit->id, punit->x, punit->y,
              gx, gy,
-              punit->ai.bodyguard);
+              punit->ai.bodyguard, punit->ai.ferryboat);
 
   va_start(ap, msg);
   my_vsnprintf(buffer2, sizeof(buffer2), msg, ap);
@@ -147,7 +153,9 @@
   int x = -1, y = -1, id = -1;
   const char *s = "none";
 
-  if (minlevel > fc_log_level) {
+  if (punit->debug) {
+    minlevel = LOG_NORMAL;
+  } else if (minlevel > fc_log_level) {
     return;
   }
 
Index: common/city.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/city.c,v
retrieving revision 1.197
diff -u -r1.197 city.c
--- common/city.c       21 Sep 2003 08:49:40 -0000      1.197
+++ common/city.c       28 Sep 2003 09:23:40 -0000
@@ -2544,6 +2544,7 @@
   pcity->science_bonus = 100;
 
   unit_list_init(&pcity->units_supported);
+  pcity->debug = FALSE;
 
   return pcity;
 }
Index: common/city.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/city.h,v
retrieving revision 1.135
diff -u -r1.135 city.h
--- common/city.h       14 Aug 2003 21:34:43 -0000      1.135
+++ common/city.h       28 Sep 2003 09:23:40 -0000
@@ -287,6 +287,7 @@
   struct unit_list info_units_present;
 
   struct ai_city ai;
+  bool debug;
 };
 
 /* city drawing styles */
Index: common/player.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/player.c,v
retrieving revision 1.126
diff -u -r1.126 player.c
--- common/player.c     22 Sep 2003 16:54:09 -0000      1.126
+++ common/player.c     28 Sep 2003 09:23:40 -0000
@@ -148,6 +148,7 @@
 
   plr->attribute_block.data = NULL;
   plr->attribute_block.length = 0;
+  plr->debug = FALSE;
 }
 
 /***************************************************************
Index: common/player.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/player.h,v
retrieving revision 1.106
diff -u -r1.106 player.h
--- common/player.h     19 Aug 2003 16:33:19 -0000      1.106
+++ common/player.h     28 Sep 2003 09:23:40 -0000
@@ -212,6 +212,7 @@
     int length;
     void *data;
   } attribute_block;
+  bool debug;
 };
 
 void player_init(struct player *plr);
Index: common/unit.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/unit.c,v
retrieving revision 1.183
diff -u -r1.183 unit.c
--- common/unit.c       22 Sep 2003 16:54:09 -0000      1.183
+++ common/unit.c       28 Sep 2003 09:23:42 -0000
@@ -1459,6 +1459,7 @@
   punit->unhappiness = 0;
   /* A unit new and fresh ... */
   punit->foul = FALSE;
+  punit->debug = FALSE;
   punit->fuel = unit_type(punit)->fuel;
   punit->hp = unit_type(punit)->hp;
   punit->moves_left = unit_move_rate(punit);
Index: common/unit.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/unit.h,v
retrieving revision 1.100
diff -u -r1.100 unit.h
--- common/unit.h       22 Sep 2003 16:54:09 -0000      1.100
+++ common/unit.h       28 Sep 2003 09:23:42 -0000
@@ -133,6 +133,7 @@
   /* ord_map and ord_city are the order index of this unit in tile.units
      and city.units_supported; they are only used for save/reload */
   bool foul;
+  bool debug;
   bool moved;
   bool paradropped;
   bool connecting;
Index: server/stdinhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/stdinhand.c,v
retrieving revision 1.294
diff -u -r1.294 stdinhand.c
--- server/stdinhand.c  23 Sep 2003 22:01:41 -0000      1.294
+++ server/stdinhand.c  28 Sep 2003 09:23:44 -0000
@@ -60,6 +60,7 @@
 #include "srv_main.h"
 
 #include "advmilitary.h"       /* assess_danger_player() */
+#include "ailog.h"
 
 #include "stdinhand.h"
 
@@ -985,6 +986,7 @@
   CMD_WALL,
   
   /* mostly non-harmful: */
+  CMD_DEBUG,
   CMD_SET,
   CMD_TEAM,
   CMD_FIX,
@@ -1114,6 +1116,12 @@
    N_("For each connected client, pops up a window showing the message "
       "entered.")
   },
+  {"debug",    ALLOW_HACK,
+   N_("debug <player <player> | city <x> <y> | units <x> <y> | unit <id>>"),
+   N_("Turn on or off AI debugging of given entity."),
+   N_("Print AI debug information about given entity and turn continous "
+      "debugging output for this entity on or off."),
+  },
   {"set",      ALLOW_CTRL,
    N_("set <option-name> <value>"),
    N_("Set server option."), NULL
@@ -2877,6 +2885,139 @@
 /******************************************************************
   ...
 ******************************************************************/
+static void debug_command(struct connection *caller, char *str) 
+{
+  char buf[MAX_LEN_CONSOLE_LINE];
+  char *arg[3];
+  int ntokens = 0, i;
+  char *usage = _("Undefined arguments. Usage: debug <player "
+                  "<player> | city <x> <y> | units <x> <y> | unit <id>>.");
+
+  if (server_state != RUN_GAME_STATE) {
+    cmd_reply(CMD_DEBUG, caller, C_SYNTAX,
+              _("Can only use this command once game has begun."));
+    return;
+  }
+
+  if (str != NULL || strlen(str) > 0) {
+    sz_strlcpy(buf, str);
+    ntokens = get_tokens(buf, arg, 3, TOKEN_DELIMITERS);
+  }
+
+  if (strcmp(arg[0], "player") == 0) {
+    struct player *pplayer;
+    enum m_pre_result match_result;
+
+    if (ntokens != 2) {
+      cmd_reply(CMD_DEBUG, caller, C_SYNTAX, usage);
+      goto cleanup;
+    }
+    pplayer = find_player_by_name_prefix(arg[1], &match_result);
+    if (pplayer == NULL) {
+      cmd_reply_no_such_player(CMD_TEAM, caller, arg[1], match_result);
+      goto cleanup;
+    }
+    if (pplayer->debug) {
+      pplayer->debug = FALSE;
+      cmd_reply(CMD_DEBUG, caller, C_OK, _("%s no longer debugged"), 
+                pplayer->name);
+    } else {
+      pplayer->debug = TRUE;
+      cmd_reply(CMD_DEBUG, caller, C_OK, _("%s debugged"), pplayer->name);
+      /* TODO: print some info about the player here */
+    }
+  } else if (strcmp(arg[0], "city") == 0) {
+    int x, y;
+    struct city *pcity;
+
+    if (ntokens != 3) {
+      cmd_reply(CMD_DEBUG, caller, C_SYNTAX, usage);
+      goto cleanup;
+    }
+    if (sscanf(arg[1], "%d", &x) != 1 || sscanf(arg[2], "%d", &y) != 1) {
+      cmd_reply(CMD_DEBUG, caller, C_SYNTAX, _("Value 2 & 3 must be 
integer."));
+      goto cleanup;
+    }
+    if (!is_normal_map_pos(x, y)) {
+      cmd_reply(CMD_DEBUG, caller, C_SYNTAX, _("Bad map coordinates."));
+      goto cleanup;
+    }
+    pcity = map_get_city(x, y);
+    if (!pcity) {
+      cmd_reply(CMD_DEBUG, caller, C_SYNTAX, _("No city at this coordinate."));
+      goto cleanup;
+    }
+    if (pcity->debug) {
+      pcity->debug = FALSE;
+      cmd_reply(CMD_DEBUG, caller, C_OK, _("%s no longer debugged"),
+                pcity->name);
+    } else {
+      pcity->debug = TRUE;
+      CITY_LOG(LOG_NORMAL, pcity, "debugged");
+    }
+  } else if (strcmp(arg[0], "units") == 0) {
+    int x, y;
+
+    if (ntokens != 3) {
+      cmd_reply(CMD_DEBUG, caller, C_SYNTAX, usage);
+      goto cleanup;
+    }
+    if (sscanf(arg[1], "%d", &x) != 1 || sscanf(arg[2], "%d", &y) != 1) {
+      cmd_reply(CMD_DEBUG, caller, C_SYNTAX, _("Value 2 & 3 must be 
integer."));
+      goto cleanup;
+    }
+    if (!is_normal_map_pos(x, y)) {
+      cmd_reply(CMD_DEBUG, caller, C_SYNTAX, _("Bad map coordinates."));
+      goto cleanup;
+    }
+    unit_list_iterate(map_get_tile(x, y)->units, punit) {
+      if (punit->debug) {
+        punit->debug = FALSE;
+        cmd_reply(CMD_DEBUG, caller, C_OK, _("%s's %s no longer debugged."),
+                  unit_owner(punit)->name, unit_name(punit->type));
+      } else {
+        punit->debug = TRUE;
+        UNIT_LOG(LOG_NORMAL, punit, _("%s's %s debugged."),
+                 unit_owner(punit)->name, unit_name(punit->type));
+      }
+    } unit_list_iterate_end;
+  } else if (strcmp(arg[0], "unit") == 0) {
+    int id;
+    struct unit *punit;
+
+    if (ntokens != 2) {
+      cmd_reply(CMD_DEBUG, caller, C_SYNTAX, usage);
+      goto cleanup;
+    }
+    if (sscanf(arg[1], "%d", &id) != 1) {
+      cmd_reply(CMD_DEBUG, caller, C_SYNTAX, _("Value 2 must be integer."));
+      goto cleanup;
+    }
+    if (!(punit = find_unit_by_id(id))) {
+      cmd_reply(CMD_DEBUG, caller, C_SYNTAX, _("Unit %d does not exist."), id);
+      goto cleanup;
+    }
+    if (punit->debug) {
+      punit->debug = FALSE;
+      cmd_reply(CMD_DEBUG, caller, C_OK, _("%s's %s no longer debugged."),
+                unit_owner(punit)->name, unit_name(punit->type));
+    } else {
+      punit->debug = TRUE;
+      UNIT_LOG(LOG_NORMAL, punit, _("%s's %s debugged."),
+               unit_owner(punit)->name, unit_name(punit->type));
+    }
+  } else {
+    cmd_reply(CMD_DEBUG, caller, C_SYNTAX, usage);
+  }
+  cleanup:
+  for (i = 0; i < ntokens; i++) {
+    free(arg[i]);
+  }
+}
+
+/******************************************************************
+  ...
+******************************************************************/
 static void set_command(struct connection *caller, char *str) 
 {
   char command[MAX_LEN_CONSOLE_LINE], arg[MAX_LEN_CONSOLE_LINE], *cptr_s, 
*cptr_d;
@@ -3861,6 +4002,9 @@
     break;
   case CMD_EXPLAIN:
     explain_option(caller,arg);
+    break;
+  case CMD_DEBUG:
+    debug_command(caller,arg);
     break;
   case CMD_SET:
     set_command(caller,arg);

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