Complete.Org: Mailing Lists: Archives: freeciv-dev: December 2005:
[Freeciv-Dev] (PR#14857) GGZ patch for freeciv development version
Home

[Freeciv-Dev] (PR#14857) GGZ patch for freeciv development version

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [Freeciv-Dev] (PR#14857) GGZ patch for freeciv development version
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Tue, 13 Dec 2005 13:53:50 -0800
Reply-to: bugs@xxxxxxxxxxx

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

This patch brings basic GGZ support to the Freeciv development version. 
  It allows you to play Freeciv on a GGZ server, using a GGZ client. 
Ranking and statistics are supported, though are not heavily tested (AI 
players are not ranked; this could change in future).  Better 
integration is possible in the future: for instance it's possible for 
the Freeciv client to fill the role of the GGZ client; however this 
would take a lot more GUI changes.

Basically what happens is GGZ server and client libraries are checked 
for at compile time.  At runtime, a --zone option is used to tell the 
server/client that GGZ mode is being used.  In this mode the network 
code works a little differently since connections are automatically 
established by the GGZ infrastructure.  Endgame is also treated a little 
differently, as it reports the results of the game back to the GGZ server.

To actually test this patch, you probably want to get the GGZ code from 
http://ggzgamingzone.org/.  The patch is against the latest (SVN) 
version of GGZ, but the latest release should work as well.  After you 
install libggz, ggz-client-libs, gtk-client, and ggzd modules you can 
compile Freeciv and it will have ggz support.  Start the GGZ server with 
"ggzd -F", and start the GGZ client with "ggz-gtk".  Connect to your 
localhost server.  Go to the Freeciv room.  Launch the game.

-jason

Index: m4/ggz.m4
===================================================================
--- m4/ggz.m4   (revision 0)
+++ m4/ggz.m4   (revision 0)
@@ -0,0 +1,795 @@
+dnl ======================================
+dnl GGZ Gaming Zone - Configuration Macros
+dnl ======================================
+dnl
+dnl Copyright (C) 2001 - 2004 Josef Spillner, josef@xxxxxxxxxxxxxxxxx
+dnl This file has heavily been inspired by KDE's acinclude :)
+dnl It is published under the conditions of the GNU General Public License.
+dnl
+dnl ======================================
+dnl
+dnl This file is common to most GGZ modules, and should be kept in sync
+dnl between them all.  The master copy resides with libggz.
+dnl Currently the following modules use it:
+dnl   kde-games, kde-client, gtk-games, gtk-client, utils, grubby,
+dnl   ggz-client-libs, ggzd, gnome-client, txt-client
+dnl See /docs/ggz-project/buildsystem for documentation.
+dnl
+dnl ======================================
+dnl
+dnl History:
+dnl   See the CVS log for a full history.
+dnl
+dnl ------------------------------------------------------------------------
+dnl Content of this file:
+dnl ------------------------------------------------------------------------
+dnl AC_GGZ_LIBGGZ - find the libggz headers and libraries
+dnl AC_GGZ_GGZCORE - find the ggzcore headers and libraries
+dnl AC_GGZ_CONFIG - find the ggz-config tool and set up configuration
+dnl AC_GGZ_GGZMOD - find the ggzmod library
+dnl AC_GGZ_GGZDMOD - find the ggzdmod library
+dnl AC_GGZ_SERVER - set up game and room path for ggzd game servers
+dnl AC_GGZ_INTL - ensure proper i18n tools installation
+dnl
+dnl Each macro takes two arguments:
+dnl   1.  Action-if-found (or empty for no action).
+dnl   2.  Action-if-not-found (or empty for error, or "ignore" to ignore).
+dnl ------------------------------------------------------------------------
+dnl Internal functions:
+dnl ------------------------------------------------------------------------
+dnl AC_GGZ_INIT - initialization
+dnl AC_GGZ_ERROR - user-friendly error messages
+dnl AC_GGZ_FIND_FILE - macro for convenience (thanks kde)
+dnl AC_GGZ_REMOVEDUPS - eliminate duplicate list elements
+dnl
+
+dnl ------------------------------------------------------------------------
+dnl Find a directory containing a single file
+dnl Synopsis: AC_GGZ_FIND_FILE(file, directorylist, <returnvar>)
+dnl ------------------------------------------------------------------------
+dnl
+AC_DEFUN([AC_GGZ_FIND_FILE],
+[
+$3=NO
+for i in $2;
+do
+  for j in $1;
+  do
+    echo "configure: __oline__: $i/$j" >&AC_FD_CC
+    if test -r "$i/$j"; then
+      echo "taking that" >&AC_FD_CC
+      $3=$i
+      break 2
+    fi
+  done
+done
+])
+
+dnl ------------------------------------------------------------------------
+dnl Remove duplicate entries in a list, and remove all NO's
+dnl Synopsis: AC_GGZ_REMOVEDUPS(list, <returnlist>)
+dnl ------------------------------------------------------------------------
+dnl
+AC_DEFUN([AC_GGZ_REMOVEDUPS],
+[
+ret=""
+for i in $1; do
+  add=yes
+  for j in $ret; do
+    if test "x$i" = "x$j"; then
+      add=no
+    fi
+  done
+  if test "x$i" = "xNO"; then
+    add=no
+  fi
+  if test "x$add" = "xyes"; then
+  ret="$ret $i"
+  fi
+done
+$2=$ret
+])
+
+dnl ------------------------------------------------------------------------
+dnl User-friendly error messages
+dnl Synopsis: AC_GGZ_ERROR(libraryname, headerdirlist, libdirlist)
+dnl ------------------------------------------------------------------------
+dnl
+AC_DEFUN([AC_GGZ_ERROR],
+[
+  AC_MSG_WARN([no
+  The library '$1' does not seem to be installed correctly.
+  Headers searched in: $2
+  Libraries searched in: $3
+  Please read QuickStart.GGZ in order to fix this.
+  ])
+  exit 1
+])
+
+dnl ------------------------------------------------------------------------
+dnl Initialization, common values and such
+dnl Synopsis: AC_GGZ_INIT([export], [defaults])
+dnl ------------------------------------------------------------------------
+dnl
+AC_DEFUN([AC_GGZ_INIT],
+[
+if test "x${prefix}" = "xNONE"; then
+   ac_ggz_prefix_incdir="${ac_default_prefix}/include"
+   ac_ggz_prefix_libdir="${ac_default_prefix}/lib"
+   ac_ggz_prefix_bindir="${ac_default_prefix}/bin"
+   ac_ggz_prefix_etcdir="${ac_default_prefix}/etc"
+else
+   ac_ggz_prefix_incdir="${prefix}/include"
+   ac_ggz_prefix_libdir="${prefix}/lib"
+   ac_ggz_prefix_bindir="${prefix}/bin"
+   ac_ggz_prefix_etcdir="${prefix}/etc"
+fi
+ac_ggz_stdinc="$ac_ggz_prefix_incdir"
+ac_ggz_stdlib="$ac_ggz_prefix_libdir"
+ac_ggz_stdbin="$ac_ggz_prefix_bindir"
+ac_ggz_stdetc="$ac_ggz_prefix_etcdir"
+if test "x$1" = "xdefaults" || test "x$2" = "xdefaults"; then
+  ac_ggz_stdinc="$ac_ggz_stdinc /usr/local/include /usr/include"
+  ac_ggz_stdlib="$ac_ggz_stdlib /usr/local/lib /usr/lib"
+  ac_ggz_stdbin="$ac_ggz_stdbin /usr/local/bin /usr/bin"
+  ac_ggz_stdetc="$ac_ggz_stdetc/ggzd /usr/local/etc/ggzd /etc/ggzd"
+fi
+if test "x$1" = "xexport" || test "x$2" = "xexport"; then
+  CPPFLAGS="$CPPFLAGS -isystem${ac_ggz_prefix_incdir}"
+  LDFLAGS="$LDFLAGS -L${ac_ggz_prefix_libdir}"
+fi
+
+save_cflags=$CFLAGS
+save_cxxflags=$CXXFLAGS
+CFLAGS="-Wall -Werror"
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
+       [[void signedness(void){char c;if(c==-1)c=0;}]])],
+       [],
+       [save_cflags="$save_cflags -fsigned-char"
+        save_cxxflags="$save_cxxflags -fsigned-char"])
+CFLAGS=$save_cflags
+CXXFLAGS=$save_cxxflags
+])
+
+dnl ------------------------------------------------------------------------
+dnl Try to find the libggz headers and libraries.
+dnl $(LIBGGZ_LDFLAGS) will be -L ... (if needed)
+dnl and $(LIBGGZ_INCLUDES) will be -I ... (if needed)
+dnl ------------------------------------------------------------------------
+dnl
+AC_DEFUN([AC_GGZ_LIBGGZ],
+[
+AC_MSG_CHECKING([for GGZ library: libggz])
+
+ac_libggz_includes=NO ac_libggz_libraries=NO
+libggz_libraries=""
+libggz_includes=""
+
+AC_ARG_WITH(libggz-dir,
+    AC_HELP_STRING([--with-libggz-dir=DIR],[libggz installation prefix]),
+    [  ac_libggz_includes="$withval"/include
+       ac_libggz_libraries="$withval"/lib
+    ])
+AC_ARG_WITH(libggz-includes,
+    AC_HELP_STRING([--with-libggz-includes=DIR],
+                   [where the libggz includes are]),
+    [  ac_libggz_includes="$withval"
+    ])
+AC_ARG_WITH(libggz-libraries,
+    AC_HELP_STRING([--with-libggz-libraries=DIR],[where the libggz libs are]),
+    [  ac_libggz_libraries="$withval"
+    ])
+
+AC_CACHE_VAL(ac_cv_have_libggz,
+[
+libggz_incdirs="$ac_libggz_includes $ac_ggz_stdinc"
+AC_GGZ_REMOVEDUPS($libggz_incdirs, libggz_incdirs)
+libggz_header=ggz.h
+
+AC_GGZ_FIND_FILE($libggz_header, $libggz_incdirs, libggz_incdir)
+ac_libggz_includes="$libggz_incdir"
+
+libggz_libdirs="$ac_libggz_libraries $ac_ggz_stdlib"
+AC_GGZ_REMOVEDUPS($libggz_libdirs, libggz_libdirs)
+
+libggz_libdir=NO
+for dir in $libggz_libdirs; do
+  try="ls -1 $dir/libggz.la $dir/libggz.so"
+  if test -n "`$try 2> /dev/null`"; then libggz_libdir=$dir; break; else echo 
"tried $dir" >&AC_FD_CC ; fi
+done
+
+ac_libggz_libraries="$libggz_libdir"
+
+if test "$ac_libggz_includes" = NO || test "$ac_libggz_libraries" = NO; then
+  ac_cv_have_libggz="have_libggz=no"
+  ac_libggz_notfound=""
+else
+  have_libggz="yes"
+fi
+])
+
+eval "$ac_cv_have_libggz"
+
+if test "$have_libggz" != yes; then
+  if test "x$2" = "xignore"; then
+    AC_MSG_RESULT([$have_libggz (ignored)])
+  else
+    AC_MSG_RESULT([$have_libggz])
+    if test "x$2" = "x"; then
+      AC_GGZ_ERROR(libggz, $libggz_incdirs, $libggz_libdirs)
+    fi
+
+    # perform actions given by argument 2.
+    $2
+  fi
+else
+  ac_cv_have_libggz="have_libggz=yes \
+    ac_libggz_includes=$ac_libggz_includes 
ac_libggz_libraries=$ac_libggz_libraries"
+  AC_MSG_RESULT([$have_libggz (libraries $ac_libggz_libraries, headers 
$ac_libggz_includes)])
+
+  libggz_libraries="$ac_libggz_libraries"
+  libggz_includes="$ac_libggz_includes"
+
+  AC_SUBST(libggz_libraries)
+  AC_SUBST(libggz_includes)
+
+  LIBGGZ_INCLUDES="-isystem $libggz_includes"
+  LIBGGZ_LDFLAGS="-L$libggz_libraries"
+
+  AC_SUBST(LIBGGZ_INCLUDES)
+  AC_SUBST(LIBGGZ_LDFLAGS)
+
+  LIB_GGZ='-lggz'
+  AC_SUBST(LIB_GGZ)
+
+  # perform actions given by argument 1.
+  $1
+fi
+
+])
+
+
+dnl ------------------------------------------------------------------------
+dnl Try to find the ggzcore headers and libraries.
+dnl $(GGZCORE_LDFLAGS) will be -L ... (if needed)
+dnl and $(GGZCORE_INCLUDES) will be -I ... (if needed)
+dnl ------------------------------------------------------------------------
+dnl
+AC_DEFUN([AC_GGZ_GGZCORE],
+[
+AC_MSG_CHECKING([for GGZ library: ggzcore])
+
+ac_ggzcore_includes=NO ac_ggzcore_libraries=NO
+ggzcore_libraries=""
+ggzcore_includes=""
+
+AC_ARG_WITH(ggzcore-dir,
+    AC_HELP_STRING([--with-ggzcore-dir=DIR],[ggzcore installation prefix]),
+    [  ac_ggzcore_includes="$withval"/include
+       ac_ggzcore_libraries="$withval"/lib
+    ])
+AC_ARG_WITH(ggzcore-includes,
+    AC_HELP_STRING([--with-ggzcore-includes=DIR],
+                   [where the ggzcore includes are]),
+    [  ac_ggzcore_includes="$withval"
+    ])
+AC_ARG_WITH(ggzcore-libraries,
+    AC_HELP_STRING([--with-ggzcore-libraries=DIR],
+                   [where the ggzcore libs are]),
+    [  ac_ggzcore_libraries="$withval"
+    ])
+
+AC_CACHE_VAL(ac_cv_have_ggzcore,
+[
+ggzcore_incdirs="$ac_ggzcore_includes $ac_ggz_stdinc"
+AC_GGZ_REMOVEDUPS($ggzcore_incdirs, ggzcore_incdirs)
+ggzcore_header=ggzcore.h
+
+AC_GGZ_FIND_FILE($ggzcore_header, $ggzcore_incdirs, ggzcore_incdir)
+ac_ggzcore_includes="$ggzcore_incdir"
+
+ggzcore_libdirs="$ac_ggzcore_libraries $ac_ggz_stdlib"
+AC_GGZ_REMOVEDUPS($ggzcore_libdirs, ggzcore_libdirs)
+
+ggzcore_libdir=NO
+for dir in $ggzcore_libdirs; do
+  try="ls -1 $dir/libggzcore.la $dir/libggzcore.so"
+  if test -n "`$try 2> /dev/null`"; then ggzcore_libdir=$dir; break; else echo 
"tried $dir" >&AC_FD_CC ; fi
+done
+
+ac_ggzcore_libraries="$ggzcore_libdir"
+
+if test "$ac_ggzcore_includes" = NO || test "$ac_ggzcore_libraries" = NO; then
+  ac_cv_have_ggzcore="have_ggzcore=no"
+  ac_ggzcore_notfound=""
+else
+  have_ggzcore="yes"
+fi
+])
+
+eval "$ac_cv_have_ggzcore"
+
+if test "$have_ggzcore" != yes; then
+  if test "x$2" = "xignore"; then
+    AC_MSG_RESULT([$have_ggzcore (intentionally ignored)])
+  else
+    AC_MSG_RESULT([$have_ggzcore])
+    if test "x$2" = "x"; then
+      AC_GGZ_ERROR(ggzcore, $ggzcore_incdirs, $ggzcore_libdirs)
+    fi
+
+    # Perform actions given by argument 2.
+    $2
+  fi
+else
+  ac_cv_have_ggzcore="have_ggzcore=yes \
+    ac_ggzcore_includes=$ac_ggzcore_includes 
ac_ggzcore_libraries=$ac_ggzcore_libraries"
+  AC_MSG_RESULT([$have_ggzcore (libraries $ac_ggzcore_libraries, headers 
$ac_ggzcore_includes)])
+
+  ggzcore_libraries="$ac_ggzcore_libraries"
+  ggzcore_includes="$ac_ggzcore_includes"
+
+  AC_SUBST(ggzcore_libraries)
+  AC_SUBST(ggzcore_includes)
+
+  GGZCORE_INCLUDES="-isystem $ggzcore_includes"
+  GGZCORE_LDFLAGS="-L$ggzcore_libraries"
+
+  AC_SUBST(GGZCORE_INCLUDES)
+  AC_SUBST(GGZCORE_LDFLAGS)
+
+  LIB_GGZCORE='-lggzcore'
+  AC_SUBST(LIB_GGZCORE)
+
+  # Perform actions given by argument 1.
+  $1
+fi
+
+])
+
+dnl ------------------------------------------------------------------------
+dnl Try to find the ggz-config binary.
+dnl Sets GGZ_CONFIG to the path/name of the program.
+dnl Sets also: ggz_gamedir, ggz_datadir etc.
+dnl ------------------------------------------------------------------------
+dnl
+AC_DEFUN([AC_GGZ_CONFIG],
+[
+AC_MSG_CHECKING([for GGZ configuration tool: ggz-config])
+
+ac_ggz_config=NO
+ggz_config=""
+
+AC_ARG_WITH(ggzconfig,
+    AC_HELP_STRING([--with-ggzconfig=DIR],[path to ggz-config]),
+    [  ac_ggz_config="$withval"
+    ])
+
+AC_CACHE_VAL(ac_cv_have_ggzconfig,
+[
+ggz_config_dirs="$ac_ggz_config $ac_ggz_stdbin"
+
+AC_GGZ_FIND_FILE(ggz-config, $ggz_config_dirs, ggz_config_dir)
+ac_ggz_config="$ggz_config_dir"
+
+if test "$ac_ggz_config" = NO; then
+  ac_cv_have_ggzcore="have_ggz_config=no"
+  ac_ggz_config_notfound=""
+  have_ggz_config="no"
+else
+  have_ggz_config="yes"
+fi
+])
+
+eval "$ac_cv_have_ggz_config"
+
+if test "$have_ggz_config" != yes; then
+  if test "x$2" = "xignore"; then
+    AC_MSG_RESULT([$have_ggz_config (intentionally ignored)])
+    GGZ_CONFIG="/bin/true"
+    AC_SUBST(GGZ_CONFIG)
+    ggzexecmoddir="\${prefix}/lib/ggz"
+    ggzdatadir="\${prefix}/share/ggz"
+    AC_DEFINE_UNQUOTED(GAMEDIR, "${prefix}/lib/ggz", [Path where to install 
the games])
+    AC_DEFINE_UNQUOTED(GGZDATADIR, "${prefix}/share/ggz", [Path where the 
games should look for their data files])
+  else
+    AC_MSG_RESULT([$have_ggz_config])
+    if test "x$2" = "x"; then
+      AC_MSG_ERROR([ggz-config not found. Please check your installation! ])
+    fi
+
+    # Perform actions given by argument 2.
+    $2
+  fi
+else
+  ac_cv_have_ggz_config="have_ggz_config=yes \
+    ac_ggz_config=$ac_ggz_config"
+  AC_MSG_RESULT([$ac_ggz_config/ggz-config])
+
+  ggz_config="$ac_ggz_config"
+
+  AC_SUBST(ggz_config)
+
+  GGZ_CONFIG="${ggz_config}/ggz-config"
+  AC_SUBST(GGZ_CONFIG)
+
+  ggzmoduleconfdir=`$GGZ_CONFIG --configdir`
+  AC_DEFINE_UNQUOTED(GGZMODULECONFDIR, "${ggzmoduleconfdir}", [Path where the 
game registry is located])
+  ggzexecmoddir=`$GGZ_CONFIG --gamedir`
+  AC_DEFINE_UNQUOTED(GAMEDIR, "${ggzexecmoddir}", [Path where to install the 
games])
+  ggzdatadir=`$GGZ_CONFIG --datadir`
+  AC_DEFINE_UNQUOTED(GGZDATADIR, "${ggzdatadir}", [Path where the games should 
look for their data files])
+  packagesrcdir=`cd $srcdir && pwd`
+  AC_DEFINE_UNQUOTED(PACKAGE_SOURCE_DIR, "${packagesrcdir}", [Path where the 
source is located])
+
+  AC_SUBST(ggzmoduleconfdir)
+  AC_SUBST(ggzexecmoddir)
+  AC_SUBST(ggzdatadir)
+  AC_SUBST(packagesrcdir)
+
+  # Perform actions given by argument 1.
+  $1
+fi
+
+])
+
+dnl ------------------------------------------------------------------------
+dnl Try to find the ggzmod headers and libraries.
+dnl $(GGZMOD_LDFLAGS) will be -L ... (if needed)
+dnl and $(GGZMOD_INCLUDES) will be -I ... (if needed)
+dnl ------------------------------------------------------------------------
+dnl
+AC_DEFUN([AC_GGZ_GGZMOD],
+[
+AC_MSG_CHECKING([for GGZ library: ggzmod])
+
+ac_ggzmod_includes=NO ac_ggzmod_libraries=NO
+ggzmod_libraries=""
+ggzmod_includes=""
+
+AC_ARG_WITH(ggzmod-dir,
+    AC_HELP_STRING([--with-ggzmod-dir=DIR],[ggzmod installation prefix]),
+    [  ac_ggzmod_includes="$withval"/include
+       ac_ggzmod_libraries="$withval"/lib
+    ])
+AC_ARG_WITH(ggzmod-includes,
+    AC_HELP_STRING([--with-ggzmod-includes=DIR],
+                   [where the ggzmod includes are]),
+    [  ac_ggzmod_includes="$withval"
+    ])
+AC_ARG_WITH(ggzmod-libraries,
+    AC_HELP_STRING([--with-ggzmod-libraries=DIR],
+                   [where the ggzmod libs are]),
+    [  ac_ggzmod_libraries="$withval"
+    ])
+
+AC_CACHE_VAL(ac_cv_have_ggzmod,
+[
+ggzmod_incdirs="$ac_ggzmod_includes $ac_ggz_stdinc"
+AC_GGZ_REMOVEDUPS($ggzmod_incdirs, ggzmod_incdirs)
+ggzmod_header=ggzmod.h
+
+AC_GGZ_FIND_FILE($ggzmod_header, $ggzmod_incdirs, ggzmod_incdir)
+ac_ggzmod_includes="$ggzmod_incdir"
+
+ggzmod_libdirs="$ac_ggzmod_libraries $ac_ggz_stdlib"
+AC_GGZ_REMOVEDUPS($ggzmod_libdirs, ggzmod_libdirs)
+
+ggzmod_libdir=NO
+for dir in $ggzmod_libdirs; do
+  try="ls -1 $dir/libggzmod.la $dir/libggzmod.so"
+  if test -n "`$try 2> /dev/null`"; then ggzmod_libdir=$dir; break; else echo 
"tried $dir" >&AC_FD_CC ; fi
+done
+
+ac_ggzmod_libraries="$ggzmod_libdir"
+
+if test "$ac_ggzmod_includes" = NO || test "$ac_ggzmod_libraries" = NO; then
+  ac_cv_have_ggzmod="have_ggzmod=no"
+  ac_ggzmod_notfound=""
+else
+  have_ggzmod="yes"
+fi
+])
+
+eval "$ac_cv_have_ggzmod"
+
+if test "$have_ggzmod" != yes; then
+  if test "x$2" = "xignore"; then
+    AC_MSG_RESULT([$have_ggzmod (intentionally ignored)])
+  else
+    AC_MSG_RESULT([$have_ggzmod])
+    if test "x$2" = "x"; then
+      AC_GGZ_ERROR(ggzmod, $ggzmod_incdirs, $ggzmod_libdirs)
+    fi
+
+    # Perform actions given by argument 2.
+    $2
+  fi
+else
+  ac_cv_have_ggzmod="have_ggzmod=yes \
+    ac_ggzmod_includes=$ac_ggzmod_includes 
ac_ggzmod_libraries=$ac_ggzmod_libraries"
+  AC_MSG_RESULT([$have_ggzmod (libraries $ac_ggzmod_libraries, headers 
$ac_ggzmod_includes)])
+
+  ggzmod_libraries="$ac_ggzmod_libraries"
+  ggzmod_includes="$ac_ggzmod_includes"
+
+  AC_SUBST(ggzmod_libraries)
+  AC_SUBST(ggzmod_includes)
+
+  GGZMOD_INCLUDES="-isystem $ggzmod_includes"
+  GGZMOD_LDFLAGS="-L$ggzmod_libraries"
+
+  AC_SUBST(GGZMOD_INCLUDES)
+  AC_SUBST(GGZMOD_LDFLAGS)
+
+  #HACK: ggzmod requires ggzcore; the dependency is added here.
+  LIB_GGZMOD='-lggzmod -lggzcore'
+  AC_SUBST(LIB_GGZMOD)
+
+  # Perform actions given by argument 1.
+  $1
+fi
+
+])
+
+dnl ------------------------------------------------------------------------
+dnl Try to find the ggzdmod headers and libraries.
+dnl $(GGZDMOD_LDFLAGS) will be -L ... (if needed)
+dnl and $(GGZDMOD_INCLUDES) will be -I ... (if needed)
+dnl ------------------------------------------------------------------------
+dnl
+AC_DEFUN([AC_GGZ_GGZDMOD],
+[
+AC_MSG_CHECKING([for GGZ library: ggzdmod])
+
+ac_ggzdmod_includes=NO ac_ggzdmod_libraries=NO
+ggzdmod_libraries=""
+ggzdmod_includes=""
+
+AC_ARG_WITH(ggzdmod-dir,
+    AC_HELP_STRING([--with-ggzdmod-dir=DIR], [ggzdmod installation prefix]),
+    [  ac_ggzdmod_includes="$withval"/include
+       ac_ggzdmod_libraries="$withval"/lib
+    ])
+AC_ARG_WITH(ggzdmod-includes,
+    AC_HELP_STRING([--with-ggzdmod-includes=DIR], 
+                   [where the ggzdmod includes are]),
+    [  ac_ggzdmod_includes="$withval"
+    ])
+AC_ARG_WITH(ggzdmod-libraries,
+    AC_HELP_STRING([--with-ggzdmod-libraries=DIR],
+                   [where the ggzdmod libs are]),
+    [  ac_ggzdmod_libraries="$withval"
+    ])
+
+AC_CACHE_VAL(ac_cv_have_ggzdmod,
+[
+ggzdmod_incdirs="$ac_ggzdmod_includes $ac_ggz_stdinc"
+AC_GGZ_REMOVEDUPS($ggzdmod_incdirs, ggzdmod_incdirs)
+ggzdmod_header=ggzdmod.h
+
+AC_GGZ_FIND_FILE($ggzdmod_header, $ggzdmod_incdirs, ggzdmod_incdir)
+ac_ggzdmod_includes="$ggzdmod_incdir"
+
+ggzdmod_libdirs="$ac_ggzdmod_libraries $ac_ggz_stdlib"
+AC_GGZ_REMOVEDUPS($ggzdmod_libdirs, ggzdmod_libdirs)
+
+ggzdmod_libdir=NO
+for dir in $ggzdmod_libdirs; do
+  try="ls -1 $dir/libggzdmod.la $dir/libggzdmod.so"
+  if test -n "`$try 2> /dev/null`"; then ggzdmod_libdir=$dir; break; else echo 
"tried $dir" >&AC_FD_CC ; fi
+done
+
+ac_ggzdmod_libraries="$ggzdmod_libdir"
+
+if test "$ac_ggzdmod_includes" = NO || test "$ac_ggzdmod_libraries" = NO; then
+  ac_cv_have_ggzdmod="have_ggzdmod=no"
+  ac_ggzdmod_notfound=""
+else
+  have_ggzdmod="yes"
+fi
+])
+
+eval "$ac_cv_have_ggzdmod"
+
+if test "$have_ggzdmod" != yes; then
+  if test "x$2" = "xignore"; then
+    AC_MSG_RESULT([$have_ggzdmod (intentionally ignored)])
+  else
+    AC_MSG_RESULT([$have_ggzdmod])
+    if test "x$2" = "x"; then
+      AC_GGZ_ERROR(ggzdmod, $ggzdmod_incdirs, $ggzdmod_libdirs)
+    fi
+
+    # Perform actions given by argument 2.
+    $2
+  fi
+else
+  ac_cv_have_ggzdmod="have_ggzdmod=yes \
+    ac_ggzdmod_includes=$ac_ggzdmod_includes 
ac_ggzdmod_libraries=$ac_ggzdmod_libraries"
+  AC_MSG_RESULT([$have_ggzdmod (libraries $ac_ggzdmod_libraries, headers 
$ac_ggzdmod_includes)])
+
+  ggzdmod_libraries="$ac_ggzdmod_libraries"
+  ggzdmod_includes="$ac_ggzdmod_includes"
+
+  AC_SUBST(ggzdmod_libraries)
+  AC_SUBST(ggzdmod_includes)
+
+  GGZDMOD_INCLUDES="-isystem $ggzdmod_includes"
+  GGZDMOD_LDFLAGS="-L$ggzdmod_libraries"
+
+  AC_SUBST(GGZDMOD_INCLUDES)
+  AC_SUBST(GGZDMOD_LDFLAGS)
+
+  LIB_GGZDMOD='-lggzdmod'
+  AC_SUBST(LIB_GGZDMOD)
+
+  # Perform actions given by argument 1.
+  $1
+fi
+
+])
+
+dnl ------------------------------------------------------------------------
+dnl Setup the game server configuration.
+dnl Sets ggzdconfdir (ggzd configuration).
+dnl Sets ggzddatadir (for game server data).
+dnl ------------------------------------------------------------------------
+dnl
+AC_DEFUN([AC_GGZ_SERVER],
+[
+AC_MSG_CHECKING([for GGZ server: ggzd])
+AC_ARG_WITH(ggzd-confdir,
+    AC_HELP_STRING([--with-ggzd-confdir=DIR], [directory for room/game data]),
+[ ac_ggzd_confdir="$withval"
+])
+
+AC_CACHE_VAL(ac_cv_have_ggzdconf,
+[
+       if test "x$1" = "xforce"; then
+               if test "x$ac_ggzd_confdir" = "x"; then
+                       ggzdconfdirs="$ac_ggz_stdetc"
+               else
+                       ggzdconfdirs="$ac_ggzd_confdir"
+               fi
+       else
+               ggzdconfdirs="$ac_ggzd_confdir $ac_ggz_stdetc"
+       fi
+
+       ggzdconfdir=NONE
+       for dir in $ggzdconfdirs; do
+               if test -n "`ls -d $dir/rooms 2> /dev/null`"; then
+                       if test -n "`ls -d $dir/rooms 2> /dev/null`"; then
+                               ggzdconfdir=$dir; break;
+                       else
+                               echo "tried $dir" >&AC_FD_CC;
+                       fi
+               else
+                       echo "tried $dir" >&AC_FD_CC;
+               fi
+       done
+
+       if test "x$ggzdconfdir" = "xNONE"; then
+               have_ggzdconf="no"
+       else
+               have_ggzdconf="yes"
+       fi
+])
+
+eval "$ac_cv_have_ggzdconf"
+
+if test "$have_ggzdconf" != yes; then
+       if test "x$2" = "xignore"; then
+         AC_MSG_RESULT([$have_ggzdconf (intentionally ignored)])
+       elif test "x$2" = "xforce"; then
+         if test "x$ac_ggzd_confdir" = "x"; then
+           ggzdconfdir="\${prefix}/etc/ggzd"
+         else
+           ggzdconfdir=$ac_ggzd_confdir
+         fi
+         AC_MSG_RESULT([$have_ggzdconf (but forced to ${ggzdconfdir})])
+       else
+         AC_MSG_RESULT([$have_ggzdconf])
+      if test "x$2" = "x"; then
+           AC_MSG_ERROR([GGZ server configuration not found. Please check your 
installation! ])
+      fi
+
+         # Perform actions given by argument 2.
+         $2
+       fi
+else
+       prefixed=0
+       if test "x${prefix}" != "xNONE" && test "x${prefix}" != 
"x${ac_default_prefix}"; then
+               prefixed=1
+       fi
+       if test "x$ggzconfdir" != "x${prefix}/etc/ggzd" && test "x$prefixed" = 
"x1"; then
+               AC_MSG_RESULT([$have_ggzdconf ($ggzdconfdir, but using 
${prefix}/etc/ggzd nevertheless)])
+               ggzdconfdir="\${prefix}/etc/ggzd"
+       else
+               AC_MSG_RESULT([$have_ggzdconf ($ggzdconfdir)])
+       fi
+fi
+
+if test "$have_ggzdconf" = yes || test "x$2" = "xforce"; then
+       AC_SUBST(ggzdconfdir)
+
+       ggzddatadir=${prefix}/share/${PACKAGE}
+       AC_DEFINE_UNQUOTED(GGZDDATADIR, "${ggzddatadir}", [Game server data 
directory])
+       AC_SUBST(ggzddatadir)
+
+       if test "x${libdir}" = 'x${exec_prefix}/lib'; then
+         if test "x${exec_prefix}" = "xNONE"; then
+           if test "x${prefix}" = "xNONE"; then
+             ggzdexecmoddir="\${ac_default_prefix}/lib/ggzd"
+                 ggzdexecmodpath="${ac_default_prefix}/lib/ggzd"
+           else
+             ggzdexecmoddir="\${prefix}/lib/ggzd"
+                 ggzdexecmodpath="${prefix}/lib/ggzd"
+           fi
+         else
+           ggzdexecmoddir="\${exec_prefix}/lib/ggzd"
+               ggzdexecmodpath="${exec_prefix}/lib/ggzd"
+         fi
+       else
+         ggzdexecmoddir="\${libdir}/ggzd"
+         ggzdexecmodpath="${libdir}/ggzd"
+       fi
+       AC_SUBST(ggzdexecmoddir)
+       AC_SUBST(ggzdexecmodpath)
+
+       # Perform actions given by argument 1.
+       $1
+fi
+
+])
+
+dnl ------------------------------------------------------------------------
+dnl Find internationalization tools
+dnl ------------------------------------------------------------------------
+dnl
+AC_DEFUN([AC_GGZ_INTL],
+[
+AC_PATH_PROG(GETTEXT, xgettext)
+AC_PATH_PROG(MSGFMT, msgfmt)
+AC_PATH_PROG(MSGMERGE, msgmerge)
+
+intl=1
+if test "x$GETTEXT" = "x"; then intl=0; fi
+if test "x$MSGFMT" = "x"; then intl=0; fi
+if test "x$MSGMERGE" = "x"; then intl=0; fi
+AM_ICONV
+LIBS="$LIBICONV $LIBS"
+AC_CHECK_LIB(intl, gettext, [LIBS="-lintl $LIBS"])
+AC_CHECK_FUNCS([gettext ngettext], [], [intl=0])
+AC_CHECK_HEADERS([libintl.h locale.h])
+if test "$intl" = 0; then
+  if test "x$2" = "xignore"; then
+    AC_MSG_WARN([Internationalization tools missing. (ignored)])
+  else
+    AC_MSG_RESULT([Internationalization tools missing.])
+    if test "x$2" = "x"; then
+      AC_MSG_ERROR([Internationalization tools missing.])
+    fi
+
+    # Perform actions given by argument 2.
+    $2
+  fi
+else
+  AC_MSG_RESULT([Internationalization tools found.])
+
+  XGETTEXT=$GETTEXT
+  GMSGFMT=$MSGFMT
+
+  AC_SUBST(XGETTEXT)
+  AC_SUBST(GETTEXT)
+  AC_SUBST(GMSGFMT)
+  AC_SUBST(MSGFMT)
+  AC_SUBST(MSGMERGE)
+
+  AC_DEFINE(ENABLE_NLS, 1, [Define if NLS is enabled])
+
+  # Perform actions given by argument 1.
+  $1
+fi
+
+])
Index: configure.ac
===================================================================
--- configure.ac        (revision 11348)
+++ configure.ac        (working copy)
@@ -33,6 +33,8 @@
 AC_DEFINE_UNQUOTED(VERSION_STRING, 
"${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}${VERSION_LABEL}", [Version 
string])
 AC_DEFINE_UNQUOTED(IS_DEVEL_VERSION, $IS_DEVEL_VERSION, [Is this a devel 
version])
 AC_DEFINE_UNQUOTED(IS_BETA_VERSION, $IS_BETA_VERSION, [Is this a beta 
veersion])
+AC_SUBST(MAJOR_VERSION)
+AC_SUBST(MINOR_VERSION)
 
 dnl Initialize automake stuff
 AM_INIT_AUTOMAKE($PACKAGE, $VERSION)
@@ -439,6 +441,49 @@
   gui_sources="gui-$client"
 fi
 
+dnl Check for GGZ
+AC_GGZ_INIT
+AC_GGZ_LIBGGZ([try_ggz="yes"], [try_ggz="no"])
+ggz_server="no"
+ggz_client="no"
+AC_ARG_WITH(ggz-server,
+            AC_HELP_STRING([--with-ggz-server], [Force GGZ server support]),
+            [try_ggz_server=$withval])
+AC_ARG_WITH(ggz-client,
+            AC_HELP_STRING([--with-ggz-client], [Force GGZ client support]),
+            [try_ggz_client=$withval])
+if test "x$server" != "xno" && test "x$try_ggz_server" != "xno"; then
+  if test "$try_ggz" = "yes"; then
+    # Must pass something as the action-if-failed, or the macro will exit
+    AC_GGZ_GGZDMOD([ggz_server="yes"], [ggz_server="no"]])
+  fi
+  if test "$ggz_server" = "yes"; then
+    GGZ_SERVER_FILES="civserver.dsc civserver.room"
+    AC_DEFINE(GGZ_SERVER, 1, [Server support for GGZ])
+  else
+    if test "$try_ggz_server" = "yes"; then
+      AC_MSG_ERROR([Could not configure GGZ server support. See above 
messages.])
+    fi
+  fi
+fi
+if test "x$client" != "xno" && test "x$try_ggz_client" != "xno"; then
+  if test "$try_ggz" = "yes"; then
+    # Must pass something as the action-if-failed, or the macro will exit
+    AC_GGZ_GGZMOD([AC_GGZ_CONFIG([ggz_client="yes"], [ggz_client="no"])],
+                  [ggz_client="no"])
+  fi
+  if test "$ggz_client" = "yes"; then
+    GGZ_CLIENT_FILES="civclient.dsc"
+    AC_DEFINE(GGZ_CLIENT, 1, [Client support for GGZ])
+  else
+    if test "$try_ggz_client" = "yes"; then
+      AC_MSG_ERROR([Could not configure GGZ client support. See above 
messages.])
+    fi
+  fi
+fi
+AM_CONDITIONAL(GGZ_CLIENT, test "$ggz_client" = "yes")
+AM_CONDITIONAL(GGZ_SERVER, test "$ggz_server" = "yes")
+
 AC_SUBST(gui_sources)
 AC_SUBST(CLIENT_CFLAGS)
 AC_SUBST(CLIENT_CXXFLAGS)
@@ -670,6 +715,9 @@
 
 AC_CONFIG_FILES([Makefile
           data/Makefile
+         data/civclient.dsc
+         data/civserver.dsc
+         data/civserver.room
          data/amplio/Makefile
          data/flags/Makefile
          data/misc/Makefile
Index: server/civserver.c
===================================================================
--- server/civserver.c  (revision 11348)
+++ server/civserver.c  (working copy)
@@ -41,6 +41,7 @@
 #include "version.h"
 
 #include "console.h"
+#include "ggzserver.h"
 #include "meta.h"
 #include "sernet.h"
 #include "srv_main.h"
@@ -176,6 +177,10 @@
       srvarg.saves_pathname = option; /* Never freed. */
     } else if (is_option("--version", argv[inx]))
       showvers = TRUE;
+#ifdef GGZ_SERVER
+    else if (is_option("--zone", argv[inx]))
+      with_ggz = TRUE;
+#endif
     else {
       fc_fprintf(stderr, _("Error: unknown option '%s'\n"), argv[inx]);
       showhelp = TRUE;
@@ -231,6 +236,9 @@
               _("  -S, --Serverid ID\tSets the server id to ID\n"));
     fc_fprintf(stderr, _("  -r, --read FILE\tRead startup script FILE\n"));
     fc_fprintf(stderr, _("  -v, --version\t\tPrint the version number\n"));
+#ifdef GGZ_SERVER
+    fc_fprintf(stderr, _("  -z, --zone\t\tEnable GGZ mode\n"));
+#endif
     fc_fprintf(stderr, _("Report bugs to <%s>.\n"), BUG_EMAIL_ADDRESS);
     exit(EXIT_SUCCESS);
   }
@@ -238,6 +246,8 @@
   /* disallow running as root -- too dangerous */
   dont_run_as_root(argv[0], "freeciv_server");
 
+  ggz_initialize();
+
   /* have arguments, call the main server loop... */
   srv_main();
 
Index: server/srv_main.c
===================================================================
--- server/srv_main.c   (revision 11348)
+++ server/srv_main.c   (working copy)
@@ -78,6 +78,7 @@
 #include "diplhand.h"
 #include "gamehand.h"
 #include "gamelog.h"
+#include "ggzserver.h"
 #include "handchat.h"
 #include "maphand.h"
 #include "meta.h"
@@ -215,6 +216,7 @@
   if (game.info.year > game.info.end_year) {
     notify_conn(game.est_connections, NULL, E_GAME_END, 
                _("Game ended in a draw as end year exceeded"));
+    ggz_report_victory();
     gamelog(GAMELOG_JUDGE, GL_DRAW, 
             "Game ended in a draw as end year exceeded");
     return TRUE;
@@ -263,10 +265,18 @@
     if (!loner) {
       notify_conn(NULL, NULL, E_GAME_END,
                   _("Team victory to %s"), team_get_name_orig(victor->team));
+      players_iterate(pplayer) {
+       if (pplayer->team == victor->team) {
+         ggz_report_victor(pplayer);
+       }
+      } players_iterate_end;
+      ggz_report_victory();
       gamelog(GAMELOG_JUDGE, GL_TEAMWIN, victor->team);
     } else {
       notify_conn(NULL, NULL, E_GAME_END,
                   _("Game ended in victory for %s"), victor->name);
+      ggz_report_victor(victor);
+      ggz_report_victory();
       gamelog(GAMELOG_JUDGE, GL_LONEWIN, victor);
     }
 
@@ -290,6 +300,12 @@
     if (win) {
       notify_conn(game.est_connections, NULL, E_GAME_END,
                     _("Team victory to %s"), team_get_name_orig(pteam));
+      players_iterate(pplayer) {
+       if (pplayer->is_alive) {
+         ggz_report_victor(pplayer);
+       }
+      } players_iterate_end;
+      ggz_report_victory();
       gamelog(GAMELOG_JUDGE, GL_TEAMWIN, pteam);
       return TRUE;
     }
@@ -299,11 +315,14 @@
   if (alive == 1) {
     notify_conn(game.est_connections, NULL, E_GAME_END,
                   _("Game ended in victory for %s"), victor->name);
+    ggz_report_victor(victor);
+    ggz_report_victory();
     gamelog(GAMELOG_JUDGE, GL_LONEWIN, victor);
     return TRUE;
   } else if (alive == 0) {
     notify_conn(game.est_connections, NULL, E_GAME_END, 
                   _("Game ended in a draw"));
+    ggz_report_victory();
     gamelog(GAMELOG_JUDGE, GL_DRAW);
     return TRUE;
   }
@@ -1694,7 +1713,9 @@
 
   /* init network */  
   init_connections(); 
-  server_open_socket();
+  if (!with_ggz) {
+    server_open_socket();
+  }
 
   /* load a saved game */
   if (srvarg.load_filename[0] != '\0') {
Index: server/settings.c
===================================================================
--- server/settings.c   (revision 11348)
+++ server/settings.c   (working copy)
@@ -22,6 +22,7 @@
 #include "map.h"
 
 #include "gamelog.h"
+#include "ggzserver.h"
 #include "report.h"
 #include "settings.h"
 #include "srv_main.h"
@@ -152,6 +153,15 @@
 *************************************************************************/
 static bool maxplayers_callback(int value, const char **error_string)
 {
+#ifdef GGZ_SERVER
+  if (with_ggz) {
+    /* In GGZ mode the maxplayers is the number of actual players - set
+     * when the game is lauched and not changed thereafter.  This may be
+     * changed in future. */
+    *error_string = _("Cannot change maxplayers in GGZ mode.");
+    return FALSE;
+  }
+#endif
   if (value < game.info.nplayers) {
     *error_string =_("Number of players is higher than requested value; "
                     "Keeping old value.");
Index: server/gamelog.c
===================================================================
--- server/gamelog.c    (revision 11348)
+++ server/gamelog.c    (working copy)
@@ -548,6 +548,7 @@
                  team_get_name_orig(pteam));
       break;
     default:
+      assert(0);
       break;
     }
     cat_snprintf(buf, sizeof(buf), "<m>%s</m>", msg);
Index: server/ggzserver.c
===================================================================
--- server/ggzserver.c  (revision 0)
+++ server/ggzserver.c  (revision 0)
@@ -0,0 +1,314 @@
+/********************************************************************** 
+ Freeciv - Copyright (C) 2005 - Freeciv Development Team
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+***********************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef GGZ_SERVER
+
+#include <ggzdmod.h>
+
+#include "fciconv.h"
+#include "fcintl.h"
+#include "log.h"
+#include "support.h"
+
+#include "game.h"
+#include "player.h"
+
+#include "connecthand.h"
+#include "ggzserver.h"
+#include "score.h"
+#include "sernet.h"
+
+bool with_ggz = FALSE;
+
+static GGZdMod *ggzdmod;
+
+
+/**************************************************************************
+  Return the seat occupied by this player (or -1 if the player i
+  seatless).
+**************************************************************************/
+static int get_seat_for_player(const struct player *pplayer)
+{
+  int num_players = ggzdmod_get_num_seats(ggzdmod), i;
+
+  /* This is pretty inefficient.  It could be faster if a player->seat
+   * association was tracked but this is probably overkill. */
+  for (i = 0; i < num_players; i++) {
+    GGZSeat seat = ggzdmod_get_seat(ggzdmod, i);
+
+    if (mystrcasecmp(pplayer->username, seat.name) == 0) {
+      return seat.num;
+    }
+  }
+
+  return -1;
+}
+
+/**************************************************************************
+  Return the player sitting at the given seat (or NULL if no player can
+  be found or if the seat is empty).
+**************************************************************************/
+static struct player *get_player_for_seat(int seat_num)
+{
+  GGZSeat seat = ggzdmod_get_seat(ggzdmod, seat_num);
+
+  switch (seat.type) {
+  case GGZ_SEAT_OPEN:
+  case GGZ_SEAT_NONE:
+  case GGZ_SEAT_RESERVED:
+    return NULL;
+  case GGZ_SEAT_PLAYER:
+  case GGZ_SEAT_BOT:
+  default: /* Works for GGZ_SEAT_ABANDONED. */
+    break;
+  }
+
+  players_iterate(pplayer) {
+    if (mystrcasecmp(pplayer->username, seat.name)) {
+      return pplayer;
+    }
+  } players_iterate_end;
+
+  /* This is probably a bad bad error. */
+  return NULL;
+}
+
+static void handle_ggz_state_event(GGZdMod * ggz, GGZdModEvent event,
+                                  const void *data)
+{
+#if 0
+  const GGZdModState *old_state = data;
+  GGZdModState new_state = ggzdmod_get_state(ggz);
+
+  /* ??? */
+#endif
+}
+
+static void handle_ggz_seat_event(GGZdMod *ggz, GGZdModEvent event,
+                                 const void *data)
+{
+  const GGZSeat *old_seat = data;
+  GGZSeat new_seat = ggzdmod_get_seat(ggz, old_seat->num);
+#if 0
+  bool is_join = ((new_seat.type == GGZ_SEAT_PLAYER
+                  || new_seat.type == GGZ_SEAT_BOT)
+                 && (old_seat->type != new_seat.type
+                     || strcmp(old_seat->name, new_seat.name)));
+  bool is_leave = ((old_seat->type == GGZ_SEAT_PLAYER
+                  || old_seat->type == GGZ_SEAT_BOT)
+                  && (new_seat.type != old_seat->type
+                      || strcmp(old_seat->name, new_seat.name)));
+  GGZdModState new_state;
+
+#endif
+
+  if (new_seat.type == GGZ_SEAT_PLAYER
+      && old_seat->type != GGZ_SEAT_PLAYER) {
+    /* Player joins game. */
+    server_make_connection(new_seat.fd, "", "");
+  } else if (new_seat.type != GGZ_SEAT_PLAYER
+            && old_seat->type == GGZ_SEAT_PLAYER) {
+    /* Player leaves game. */
+    struct connection *leaving = NULL;
+
+    players_iterate(pplayer) {
+      conn_list_iterate(pplayer->connections, pconn) {
+       if (strcmp(pconn->username, old_seat->name) == 0) {
+         leaving = pconn;
+         break;
+       }
+      } conn_list_iterate_end;
+    } players_iterate_end;
+
+    if (leaving) {
+      printf("%s is leaving.\n", old_seat->name);
+      leaving->sock = -1;
+      lost_connection_to_client(leaving);
+      close_connection(leaving);
+    } else {
+      printf("Couldn't match player %s.\n", old_seat->name);
+    }
+  }
+}
+
+static void handle_ggz_spectator_seat_event(GGZdMod *ggz, GGZdModEvent event,
+                                           const void *data)
+{
+#if 0
+  const GGZSpectator *old = data;
+  GGZSpectator new = ggzdmod_get_spectator(ggz, spectator);
+
+  if (new.name) {
+
+  } else {
+
+  }
+#endif
+}
+
+/**************************************************************************
+  Connect to the GGZ server, if GGZ is being used.
+**************************************************************************/
+void ggz_initialize(void)
+{
+  if (with_ggz) {
+    int ggz_socket;
+
+    /* Detach from terminal. */
+    fclose(stdin);
+    //fclose(stdout);
+    fclose(stderr);
+
+    /* We're in GGZ mode */
+    ggzdmod = ggzdmod_new(GGZDMOD_GAME);
+    ggzdmod_set_handler(ggzdmod, GGZDMOD_EVENT_STATE,
+                       &handle_ggz_state_event);
+    ggzdmod_set_handler(ggzdmod, GGZDMOD_EVENT_JOIN,
+                       &handle_ggz_seat_event);
+    ggzdmod_set_handler(ggzdmod, GGZDMOD_EVENT_LEAVE,
+                       &handle_ggz_seat_event);
+    ggzdmod_set_handler(ggzdmod, GGZDMOD_EVENT_SEAT,
+                       &handle_ggz_seat_event);
+    ggzdmod_set_handler(ggzdmod, GGZDMOD_EVENT_SPECTATOR_JOIN,
+                       &handle_ggz_spectator_seat_event);
+    if (ggzdmod_connect(ggzdmod) < 0) {
+      exit(EXIT_FAILURE);
+    }
+    ggz_socket = ggzdmod_get_fd(ggzdmod);
+    if (ggz_socket < 0) {
+      fc_fprintf(stderr, _("Only the GGZ client must call civclient"
+                          " in ggz mode!\n"));
+      exit(EXIT_FAILURE);
+    }
+  }
+}
+
+/**************************************************************************
+
+**************************************************************************/
+void input_from_ggz(int socket)
+{
+  ggzdmod_dispatch(ggzdmod);
+}
+
+/**************************************************************************
+
+**************************************************************************/
+int get_ggz_socket(void)
+{
+  return ggzdmod_get_fd(ggzdmod);
+}
+
+static const struct player *victors[MAX_NUM_PLAYERS];
+static int num_victors;
+
+/**************************************************************************
+
+**************************************************************************/
+void ggz_report_victor(const struct player *winner)
+{
+  freelog(LOG_NORMAL, "Victor: %s", winner->name);
+
+  if (!with_ggz) {
+    return;
+  }
+
+  /* All players, including AI, are included on this list. */
+  victors[num_victors] = winner;
+  num_victors++;
+}
+
+/**************************************************************************
+
+**************************************************************************/
+void ggz_report_victory(void)
+{
+  int num_players = ggzdmod_get_num_seats(ggzdmod), i;
+  int teams[num_players], num_teams = 0, scores[num_players];
+  GGZGameResult results[num_players], default_result;
+
+  freelog(LOG_NORMAL, "Victory...");
+
+  if (!with_ggz) {
+    return;
+  }
+
+  /* Assign teams.  First put players who are on teams. */
+  team_iterate(pteam) {
+    players_iterate(pplayer) {
+      if (pplayer->team == pteam) {
+       int seat = get_seat_for_player(pplayer);
+
+       if (seat < 0) {
+         assert(0);
+       } else {
+         teams[get_seat_for_player(pplayer)] = num_teams;
+       }
+      }
+    } players_iterate_end;
+    num_teams++;
+  } team_iterate_end;
+
+  /* Then assign team numbers for non-team players. */
+  for (i = 0; i < num_players; i++) {
+    const struct player *pplayer = get_player_for_seat(i);
+
+    if (!pplayer) {
+      teams[i] = -1;
+    } else if (!pplayer->team) {
+      teams[i] = num_teams;
+      num_teams++;
+    } else {
+      assert(teams[i] >= 0 && teams[i] < num_teams);
+    }
+  }
+
+  /* Scores. */
+  for (i = 0; i < num_players; i++) {
+    const struct player *pplayer = get_player_for_seat(i);
+
+    if (pplayer) {
+      scores[i] = pplayer->score.game;
+    } else {
+      scores[i] = -1;
+    }
+  }
+
+  if (num_victors == 0) {
+    default_result = GGZ_GAME_TIE;
+  } else {
+    default_result = GGZ_GAME_LOSS;
+  }
+  for (i = 0; i < num_players; i++) {
+    results[i] = default_result;
+  }
+  for (i = 0; i < num_victors; i++) {
+    int seat_num = get_seat_for_player(victors[i]);
+
+    if (seat_num < 0) {
+      assert(0);
+    } else {
+      results[seat_num] = GGZ_GAME_WIN;
+    }
+  }
+
+  ggzdmod_report_game(ggzdmod, teams, results, scores);
+
+  num_victors = 0; /* In case there's another game. */
+}
+
+#endif
Index: server/ggzserver.h
===================================================================
--- server/ggzserver.h  (revision 0)
+++ server/ggzserver.h  (revision 0)
@@ -0,0 +1,40 @@
+/********************************************************************** 
+ Freeciv - Copyright (C) 2005 - Freeciv Development Team
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+***********************************************************************/
+#ifndef FC__GGZSERVER_H
+#define FC__GGZSERVER_H
+
+#ifdef GGZ_SERVER
+
+#include "shared.h"
+
+#include "player.h"
+
+extern bool with_ggz;
+
+void ggz_initialize(void);
+void input_from_ggz(int socket);
+int get_ggz_socket(void);
+
+void ggz_report_victor(const struct player *winner);
+void ggz_report_victory(void);
+
+#else
+
+#  define with_ggz FALSE
+#  define ggz_initialize() (void)0
+#  define ggz_report_victor(pplayer) (void)0
+#  define ggz_report_victory() (void)0
+
+#endif
+
+#endif  /* FC__GGZSERVER_H */
Index: server/sernet.c
===================================================================
--- server/sernet.c     (revision 11348)
+++ server/sernet.c     (working copy)
@@ -76,6 +76,7 @@
 
 #include "connecthand.h"
 #include "console.h"
+#include "ggzserver.h"
 #include "meta.h"
 #include "plrhand.h"
 #include "srv_main.h"
@@ -576,10 +577,19 @@
 #endif
     }
 
-    FD_SET(sock, &readfs);
-    FD_SET(sock, &exceptfs);
-    max_desc = sock;
+    if (with_ggz) {
+#ifdef GGZ_SERVER
+      int ggz_sock = get_ggz_socket();
 
+      FD_SET(ggz_sock, &readfs);
+      max_desc = MAX(sock, ggz_sock);
+#endif
+    } else {
+      FD_SET(sock, &readfs);
+      FD_SET(sock, &exceptfs);
+      max_desc = sock;
+    }
+
     for (i = 0; i < MAX_NUM_CONNECTIONS; i++) {
       if (connections[i].used) {
        FD_SET(connections[i].sock, &readfs);
@@ -635,16 +645,16 @@
       }
     }
 
-    if (FD_ISSET(sock, &exceptfs)) {
-      /* handle Ctrl-Z suspend/resume */
-      continue;
-    }
-    if (FD_ISSET(sock, &readfs)) {
-      /* new players connects */
-      freelog(LOG_VERBOSE, "got new connection");
-      if (server_accept_connection(sock) == -1) {
-       freelog(LOG_ERROR, "failed accepting connection");
+    if (!with_ggz) { /* No listening socket when using GGZ. */
+      if (FD_ISSET(sock, &exceptfs)) {      /* handle Ctrl-Z suspend/resume */
+       continue;
       }
+      if(FD_ISSET(sock, &readfs)) {         /* new players connects */
+       freelog(LOG_VERBOSE, "got new connection");
+       if(server_accept_connection(sock)==-1) {
+         freelog(LOG_ERROR, "failed accepting connection");
+       }
+      }
     }
     for (i = 0; i < MAX_NUM_CONNECTIONS; i++) {
       /* check for freaky players */
@@ -656,6 +666,17 @@
        close_socket_callback(pconn);
       }
     }
+#ifdef GGZ_SERVER
+    if (with_ggz) {
+      /* This is intentionally after all the player socket handling because
+       * it may cut a client. */
+      int ggz_sock = get_ggz_socket();
+
+      if (FD_ISSET(ggz_sock, &readfs)) {
+       input_from_ggz(ggz_sock);
+      }
+    }
+#endif
     
 #ifdef SOCKET_ZERO_ISNT_STDIN
     if (!no_input && (bufptr = my_read_console())) {
@@ -782,7 +803,6 @@
   int new_sock;
   union my_sockaddr fromend;
   struct hostent *from;
-  int i;
 
   fromlen = sizeof(fromend);
 
@@ -791,12 +811,28 @@
     return -1;
   }
 
-  my_nonblock(new_sock);
-
   from =
       gethostbyaddr((char *) &fromend.sockaddr_in.sin_addr,
                    sizeof(fromend.sockaddr_in.sin_addr), AF_INET);
 
+  return server_make_connection(new_sock,
+                               (from ? from->h_name
+                                : inet_ntoa(fromend.sockaddr_in.sin_addr)),
+                               inet_ntoa(fromend.sockaddr_in.sin_addr));
+}
+
+/********************************************************************
+  Server accepts connection from client:
+  Low level socket stuff, and basic-initialize the connection struct.
+  Returns 0 on success, -1 on failure (bad accept(), or too many
+  connections).
+********************************************************************/
+int server_make_connection(int new_sock, const char *client_addr, const char 
*client_ip)
+{
+  int i;
+
+  my_nonblock(new_sock);
+
   for(i=0; i<MAX_NUM_CONNECTIONS; i++) {
     struct connection *pconn = &connections[i];
     if (!pconn->used) {
@@ -822,11 +858,8 @@
       pconn->outgoing_packet_notify = NULL;
 
       sz_strlcpy(pconn->username, makeup_connection_name(&pconn->id));
-      sz_strlcpy(pconn->addr,
-                (from ? from->
-                 h_name : inet_ntoa(fromend.sockaddr_in.sin_addr)));
-      sz_strlcpy(pconn->server.ipaddr,
-                 inet_ntoa(fromend.sockaddr_in.sin_addr));
+      sz_strlcpy(pconn->addr, client_addr);
+      sz_strlcpy(pconn->server.ipaddr, client_ip);
 
       conn_list_append(game.all_connections, pconn);
   
@@ -1038,6 +1071,10 @@
   fd_set readfs, exceptfs;
   struct timeval tv;
 
+  if (with_ggz) {
+    return;
+  }
+
   FD_ZERO(&readfs);
   FD_ZERO(&exceptfs);
   FD_SET(socklan, &exceptfs);
Index: server/sernet.h
===================================================================
--- server/sernet.h     (revision 11348)
+++ server/sernet.h     (working copy)
@@ -27,6 +27,8 @@
 int sniff_packets(void);
 void close_connections_and_socket(void);
 void init_connections(void);
+int server_make_connection(int new_sock,
+                          const char *client_addr, const char *client_ip);
 void close_connection(struct connection *pconn);
 void handle_conn_pong(struct connection *pconn);
 
Index: server/stdinhand.c
===================================================================
--- server/stdinhand.c  (revision 11348)
+++ server/stdinhand.c  (working copy)
@@ -54,6 +54,7 @@
 #include "diplhand.h"
 #include "gamehand.h"
 #include "gamelog.h"
+#include "ggzserver.h"
 #include "mapgen.h"
 #include "maphand.h"
 #include "meta.h"
@@ -3355,6 +3356,7 @@
 {
   if (!check) {
     cmd_reply(CMD_QUIT, caller, C_OK, _("Goodbye."));
+    ggz_report_victory();
     gamelog(GAMELOG_JUDGE, GL_NONE);
     gamelog(GAMELOG_END);
     server_quit();
Index: server/Makefile.am
===================================================================
--- server/Makefile.am  (revision 11348)
+++ server/Makefile.am  (working copy)
@@ -7,7 +7,8 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/utility -I$(srcdir)/../common -I$(srcdir)/../ai \
        -I../intl -I$(top_srcdir)/common/aicore -I$(srcdir)/userdb \
-       -I$(srcdir)/generator -I$(srcdir)/scripting
+       -I$(srcdir)/generator -I$(srcdir)/scripting \
+       @LIBGGZ_INCLUDES@ @GGZDMOD_INCLUDES@
 
 ## Above, note -I../intl instead of -I$(top_srdir/intl) is deliberate.
 
@@ -42,6 +43,8 @@
                gamelog.h       \
                gotohand.c      \
                gotohand.h      \
+               ggzserver.c     \
+               ggzserver.h     \
                handchat.c      \
                handchat.h      \
                hand_gen.h      \
@@ -89,6 +92,7 @@
       ../dependencies/lua/src/lib/liblualib.a \
       ../dependencies/tolua/libtolua.a \
       ./generator/libgenerator.a $(USER_DB_DEP)
+civserver_LDFLAGS = @GGZDMOD_LDFLAGS@
 civserver_LDADD        = ../utility/libcivutility.a ../common/libcivcommon.a \
       ../ai/libcivai.a ../utility/libcivutility.a ./libcivserver.a @INTLLIBS@ \
       ../utility/libcivutility.a ../common/libcivcommon.a ../ai/libcivai.a \
@@ -98,7 +102,7 @@
       ../dependencies/lua/src/liblua.a \
       ../dependencies/lua/src/lib/liblualib.a \
       ../dependencies/tolua/libtolua.a \
-      $(USER_DB_LIB) $(SERVER_LIBS)
+      $(USER_DB_LIB) $(SERVER_LIBS) @LIB_GGZDMOD@
 
 
 
Index: data/civserver.dsc.in
===================================================================
--- data/civserver.dsc.in       (revision 0)
+++ data/civserver.dsc.in       (revision 0)
@@ -0,0 +1,28 @@
+# GGZ Server game description file for Freeciv
+
+[GameInfo]
+Author = See http://www.freeciv.org/people.phtml
+Description = Freeciv strategy game
+Homepage = http://www.freeciv.org/
+Name = Freeciv
+Version = @VERSION@
+
+[LaunchInfo]
+ExecutablePath = @prefix@/bin/civserver -z -q 180 -e
+
+[Protocol]
+Engine = Freeciv
+Version = @MAJOR_VERSION@.@MINOR_VERSION@
+
+[TableOptions]
+AllowLeave = 1
+# Freeciv bots are handled internally, but aren't visible to GGZ
+#BotsAllowed = 
+PlayersAllowed = 1..30
+# This should be 0, but civserver doesn't exit correctly in pregame
+KillWhenEmpty = 1
+AllowSpectators = 0
+
+[Statistics]
+Records = 1
+Ratings = 1
Index: data/civserver.room.in
===================================================================
--- data/civserver.room.in      (revision 0)
+++ data/civserver.room.in      (revision 0)
@@ -0,0 +1,16 @@
+# GGZ Server room description file for Freeciv
+[RoomInfo]
+
+# This is the short name for the room
+Name = Freeciv @MAJOR_VERSION@.@MINOR_VERSION@
+
+# This is the long descriptive name for the room.  Make sure it's updated
+# when new games are added.
+Description = Freeciv multiplayer strategy game
+
+# The gametype should match up to the Name of an added game
+GameType = Freeciv
+
+# These set maximum values for this room
+MaxPlayers = 150
+MaxTables = 45
Index: data/civclient.dsc.in
===================================================================
--- data/civclient.dsc.in       (revision 0)
+++ data/civclient.dsc.in       (revision 0)
@@ -0,0 +1,11 @@
+# GGZ client game description file for Freeciv
+
+[ModuleInfo]
+Author = See http://www.freeciv.org/people.phtml
+CommandLine = @prefix@/bin/civclient --zone
+Frontend = any
+Homepage = http://www.freeciv.org/
+Name = Freeciv
+ProtocolEngine = Freeciv
+ProtocolVersion = @MAJOR_VERSION@.@MINOR_VERSION@
+Version = @VERSION@
Index: data/Makefile.am
===================================================================
--- data/Makefile.am    (revision 11348)
+++ data/Makefile.am    (working copy)
@@ -36,6 +36,9 @@
        freeciv-client.png \
        freeciv.rc      \
        freeciv.rc-2.0  \
+       civserver.dsc.in        \
+       civclient.dsc.in        \
+       civserver.room.in       \
        amplio.tilespec \
        isophex.tilespec        \
        isotrident.tilespec \
@@ -68,3 +71,19 @@
 icon_DATA=$(ICONS)
 
 SUBDIRS = $(CLIENTDATADIRS) $(SERVERDATADIRS)
+
+if GGZ_CLIENT
+install-data-local:
+       $(GGZ_CONFIG) -D --install --modfile=civclient.dsc --force
+
+uninstall-local:
+       $(GGZ_CONFIG) -D --remove --modfile=civclient.dsc
+endif
+
+if GGZ_SERVER
+ggzroom_DATA = civserver.room
+ggzroomdir = ${prefix}/etc/ggzd/rooms/
+
+ggzgame_DATA = civserver.dsc
+ggzgamedir = ${prefix}/etc/ggzd/games/
+endif
Index: manual/Makefile.am
===================================================================
--- manual/Makefile.am  (revision 11348)
+++ manual/Makefile.am  (working copy)
@@ -19,6 +19,7 @@
       ../dependencies/lua/src/lib/liblualib.a \
       ../dependencies/tolua/libtolua.a \
       ../server/generator/libgenerator.a
+civmanual_LDFLAGS = @GGZDMOD_LDFLAGS@
 civmanual_LDADD        = ../utility/libcivutility.a ../common/libcivcommon.a \
       ../ai/libcivai.a ../utility/libcivutility.a ../server/libcivserver.a \
       @INTLLIBS@ ../client/helpdata.o \
@@ -31,4 +32,4 @@
       ../dependencies/lua/src/lib/liblualib.a \
       ../dependencies/tolua/libtolua.a \
       ../server/generator/libgenerator.a \
-      $(SERVER_LIBS)
+      $(SERVER_LIBS) @LIB_GGZDMOD@
Index: client/gui-gtk-2.0/gui_main.c
===================================================================
--- client/gui-gtk-2.0/gui_main.c       (revision 11348)
+++ client/gui-gtk-2.0/gui_main.c       (working copy)
@@ -55,6 +55,7 @@
 #include "dialogs.h"
 #include "diplodlg.h"
 #include "gotodlg.h"
+#include "ggzclient.h"
 #include "graphics.h"
 #include "gui_main.h"
 #include "gui_stuff.h"
@@ -1581,6 +1582,14 @@
 }
 
 /**************************************************************************
+  Callback for when the GGZ socket has data pending.
+**************************************************************************/
+static void get_ggz_input(gpointer data, gint fid, GdkInputCondition condition)
+{
+  input_from_ggz(fid);
+}
+
+/**************************************************************************
 ...
 **************************************************************************/
 static void set_wait_for_writable_socket(struct connection *pc,
@@ -1623,6 +1632,15 @@
   gdk_window_set_cursor(root_window, NULL);
 }
 
+/**************************************************************************
+  Called to monitor a GGZ socket.
+**************************************************************************/
+void add_ggz_input(int sock)
+{
+  (void) gtk_input_add_full(sock, GDK_INPUT_READ, get_ggz_input,
+                           NULL, NULL, NULL);
+}
+
 /****************************************************************
   This is the response callback for the dialog with the message:
   Are you sure you want to quit?
Index: client/include/gui_main_g.h
===================================================================
--- client/include/gui_main_g.h (revision 11348)
+++ client/include/gui_main_g.h (working copy)
@@ -26,6 +26,7 @@
 void sound_bell(void);
 void add_net_input(int);
 void remove_net_input(void);
+void add_ggz_input(int socket);
 
 void set_unit_icon(int idx, struct unit *punit);
 void set_unit_icons_more_arrow(bool onoff);
Index: client/ggzclient.c
===================================================================
--- client/ggzclient.c  (revision 0)
+++ client/ggzclient.c  (revision 0)
@@ -0,0 +1,84 @@
+/********************************************************************** 
+ Freeciv - Copyright (C) 2005 - Freeciv Development Team
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+***********************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef GGZ_CLIENT
+
+#include <ggzmod.h>
+
+#include "fciconv.h"
+#include "fcintl.h"
+
+#include "gui_main_g.h"
+
+#include "clinet.h"
+#include "ggzclient.h"
+
+
+bool with_ggz = FALSE;
+
+static GGZMod *ggzmod;
+
+/**************************************************************************
+  A callback that GGZ calls when we are connected to the freeciv
+  server.
+**************************************************************************/
+static void handle_ggzmod_server(GGZMod * ggzmod, GGZModEvent e,
+                                const void *data)
+{
+  const int *socket = data;
+  const char *username = ggzmod_get_player(ggzmod, NULL, NULL);
+
+  if (!username) {
+    username = "NONE";
+  }
+  make_connection(*socket, username);
+}
+
+/**************************************************************************
+  Connect to the GGZ client, if GGZ is being used.
+**************************************************************************/
+void ggz_initialize(void)
+{
+  if (with_ggz) {
+    int ggz_socket;
+
+    /* We're in GGZ mode */
+    printf("ggz initialize\n");
+    ggzmod = ggzmod_new(GGZMOD_GAME);
+    ggzmod_set_handler(ggzmod, GGZMOD_EVENT_SERVER, &handle_ggzmod_server);
+    if (ggzmod_connect(ggzmod) < 0) {
+      exit(EXIT_FAILURE);
+    }
+    ggz_socket = ggzmod_get_fd(ggzmod);
+    if (ggz_socket < 0) {
+      fc_fprintf(stderr, _("Only the GGZ client must call civclient"
+                          " in ggz mode!\n"));
+      exit(EXIT_FAILURE);
+    }
+    add_ggz_input(ggz_socket);
+  }
+}
+
+/**************************************************************************
+  Called when the ggz socket has data pending.
+**************************************************************************/
+void input_from_ggz(int socket)
+{
+  ggzmod_dispatch(ggzmod);
+}
+
+#endif
Index: client/ggzclient.h
===================================================================
--- client/ggzclient.h  (revision 0)
+++ client/ggzclient.h  (revision 0)
@@ -0,0 +1,33 @@
+/********************************************************************** 
+ Freeciv - Copyright (C) 2005 - Freeciv Development Team
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+***********************************************************************/
+#ifndef FC__GGZCLIENT_H
+#define FC__GGZCLIENT_H
+
+#ifdef GGZ_CLIENT
+
+#include "shared.h"
+
+extern bool with_ggz;
+
+void ggz_initialize(void);
+void input_from_ggz(int socket);
+
+#else
+
+#  define with_ggz FALSE
+#  define ggz_initialize() (void)0
+#  define input_from_ggz(socket) (void)0
+
+#endif
+
+#endif  /* FC__GGZCLIENT_H */
Index: client/clinet.c
===================================================================
--- client/clinet.c     (revision 11348)
+++ client/clinet.c     (working copy)
@@ -79,6 +79,7 @@
 #include "connectdlg_common.h"
 #include "connectdlg_g.h"
 #include "dialogs_g.h"         /* popdown_races_dialog() */
+#include "ggzclient.h"
 #include "gui_main_g.h"                /* add_net_input(), remove_net_input() 
*/
 #include "mapview_common.h"    /* unqueue_mapview_update */
 #include "menu_g.h"
@@ -124,6 +125,9 @@
   client_kill_server(TRUE);
   append_output_window(_("Lost connection to server!"));
   freelog(LOG_NORMAL, "lost connection to server");
+  if (with_ggz) {
+    ui_exit();
+  }
 }
 
 /**************************************************************************
@@ -182,8 +186,6 @@
 **************************************************************************/
 int try_to_connect(const char *username, char *errbuf, int errbufsize)
 {
-  struct packet_server_join_req req;
-
   close_socket_set_callback(close_socket_callback);
 
   /* connection in progress? wait. */
@@ -209,7 +211,20 @@
 #endif
   }
 
+  make_connection(aconnection.sock, username);
+
+  return 0;
+}
+ 
+/**************************************************************************
+  Called after a connection is completed (e.g., in try_to_connect).
+**************************************************************************/
+void make_connection(int socket, const char *username)
+{
+  struct packet_server_join_req req;
+
   connection_common_init(&aconnection);
+  aconnection.sock = socket;
   aconnection.is_server = FALSE;
   aconnection.client.last_request_id_used = 0;
   aconnection.client.last_processed_request_id_seen = 0;
@@ -230,8 +245,6 @@
   sz_strlcpy(req.username, username);
   
   send_packet_server_join_req(&aconnection, &req);
-
-  return 0;
 }
 
 /**************************************************************************
@@ -252,6 +265,9 @@
     client_kill_server(TRUE);
   }
   append_output_window(_("Disconnected from server."));
+  if (with_ggz) {
+    ui_exit();
+  }
 }  
 
 /**************************************************************************
Index: client/civclient.c
===================================================================
--- client/civclient.c  (revision 11348)
+++ client/civclient.c  (working copy)
@@ -55,6 +55,7 @@
 #include "control.h" 
 #include "dialogs_g.h"
 #include "diplodlg_g.h"
+#include "ggzclient.h"
 #include "goto.h"
 #include "gui_main_g.h"
 #include "helpdata.h"          /* boot_help_texts() */
@@ -221,6 +222,9 @@
       fc_fprintf(stderr, _("  -t, --tiles FILE\t"
                           "Use data file FILE.tilespec for tiles\n"));
       fc_fprintf(stderr, _("  -v, --version\t\tPrint the version number\n"));
+#ifdef GGZ_CLIENT
+    fc_fprintf(stderr, _("  -z, --zone\t\tEnable GGZ mode\n"));
+#endif
       fc_fprintf(stderr, _("      --\t\t"
                           "Pass any following options to the UI.\n"
                           "\t\t\tTry \"%s -- --help\" for more.\n"), argv[0]);
@@ -271,6 +275,10 @@
     } else if ((option = get_option_malloc("--tiles", argv, &i, argc))) {
       sz_strlcpy(tileset_name, option);
       free(option);
+#ifdef GGZ_CLIENT
+    } else if (is_option("--zone", argv[i])) {
+      with_ggz = TRUE;
+#endif
     } else if (is_option("--", argv[i])) {
       ui_separator = TRUE;
     } else {
@@ -347,6 +355,8 @@
   audio_real_init(sound_set_name, sound_plugin_name);
   audio_play_music("music_start", NULL);
 
+  ggz_initialize();
+
   /* run gui-specific client */
   ui_main(argc, argv);
 
Index: client/clinet.h
===================================================================
--- client/clinet.h     (revision 11348)
+++ client/clinet.h     (working copy)
@@ -28,6 +28,8 @@
 int get_server_address(const char *hostname, int port, char *errbuf,
                       int errbufsize);
 int try_to_connect(const char *username, char *errbuf, int errbufsize);
+void make_connection(int socket, const char *username);
+
 void input_from_server(int fd);
 void input_from_server_till_request_got_processed(int fd,
                                                  int expected_request_id);
Index: client/Makefile.am
===================================================================
--- client/Makefile.am  (revision 11348)
+++ client/Makefile.am  (working copy)
@@ -118,7 +118,7 @@
 
 bin_PROGRAMS = civclient
 
-AM_CPPFLAGS = -I$(top_srcdir)/utility -I$(srcdir)/include 
-I$(top_srcdir)/common -I$(top_srcdir)/common/aicore -I../intl 
-I$(srcdir)/agents @SOUND_CFLAGS@
+AM_CPPFLAGS = -I$(top_srcdir)/utility -I$(srcdir)/include 
-I$(top_srcdir)/common -I$(top_srcdir)/common/aicore -I../intl 
-I$(srcdir)/agents @SOUND_CFLAGS@ @LIBGGZ_INCLUDES@ @GGZMOD_INCLUDES@
 
 ## Above, note -I../intl instead of -I$(top_srdir/intl) is deliberate.
 
@@ -145,6 +145,8 @@
        colors_common.h         \
        control.c       \
        control.h       \
+       ggzclient.c     \
+       ggzclient.h     \
        goto.c          \
        goto.h          \
        helpdata.c      \
@@ -182,7 +184,7 @@
        audio_none.c    \
        audio_none.h
 
-civclient_LDFLAGS = @CLIENT_LDFLAGS@
+civclient_LDFLAGS = @CLIENT_LDFLAGS@ @GGZMOD_LDFLAGS@
 fc_civclient_libs =    ../utility/libcivutility.a      \
                        $(LIBFTWL)                      \
                        ../common/libcivcommon.a        \
@@ -191,7 +193,7 @@
                        @gui_sources@/libguiclient.a
 civclient_DEPENDENCIES = $(fc_civclient_libs)
 civclient_LDADD        = $(fc_civclient_libs) $(fc_civclient_libs) \
-       @INTLLIBS@ @CLIENT_LIBS@ @SOUND_LIBS@
+       @INTLLIBS@ @CLIENT_LIBS@ @SOUND_LIBS@ @LIB_GGZMOD@
 desktopfiledir = $(prefix)/share/applications
 desktopfile_DATA = \
        freeciv.desktop

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#14857) GGZ patch for freeciv development version, Jason Short <=