[Freeciv-Dev] Re: (PR#14857) GGZ patch for freeciv development version
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<URL: http://bugs.freeciv.org/Ticket/Display.html?id=14857 >
Here's a new patch. It has no real changes just a few cleanups.
-jason
Index: m4/ggz-user.m4
===================================================================
--- m4/ggz-user.m4 (revision 0)
+++ m4/ggz-user.m4 (revision 0)
@@ -0,0 +1,54 @@
+# AC_GGZ_CHECK
+# Check for presence of GGZ client and server libraries.
+#
+# Simply call this function in programs that use GGZ. GGZ_SERVER and
+# GGZ_CLIENT will be #defined in config.h, and created as conditionals
+# in Makefile.am files.
+AC_DEFUN([AC_GGZ_CHECK],
+[
+ 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$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$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")
+])
Index: m4/ggz.m4
===================================================================
--- m4/ggz.m4 (revision 0)
+++ m4/ggz.m4 (revision 0)
@@ -0,0 +1,851 @@
+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_INIT - initialization and paths/options setup
+dnl AC_GGZ_VERSION - ensure a minimum version of GGZ
+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_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
+ prefix="${ac_default_prefix}"
+fi
+AC_DEFINE_UNQUOTED([PREFIX], "${prefix}", [The installation prefix])
+
+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} -isystem
/usr/local/include"
+ LDFLAGS="$LDFLAGS -L${ac_ggz_prefix_libdir} -L/usr/local/lib"
+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 Ensure that a minimum version of GGZ is present
+dnl Synopsis: AC_GGZ_VERSION(major, minor, micro)
+dnl ------------------------------------------------------------------------
+dnl
+AC_DEFUN([AC_GGZ_VERSION],
+[
+ major=$1
+ minor=$2
+ micro=$3
+
+ testprologue="#include <ggz.h>"
+ testbody=""
+ testbody="$testbody if(LIBGGZ_VERSION_MAJOR > $major) return 0;"
+ testbody="$testbody if(LIBGGZ_VERSION_MAJOR < $major) return -1;"
+ testbody="$testbody if(LIBGGZ_VERSION_MINOR > $minor) return 0;"
+ testbody="$testbody if(LIBGGZ_VERSION_MINOR < $minor) return -1;"
+ testbody="$testbody if(LIBGGZ_VERSION_MICRO > $micro) return 0;"
+ testbody="$testbody if(LIBGGZ_VERSION_MICRO < $micro) return -1;"
+ testbody="$testbody return 0;"
+
+ AC_RUN_IFELSE(
+ [AC_LANG_PROGRAM([[$testprologue]], [[$testbody]])],
+ [],
+ [AC_MSG_ERROR([The GGZ version is too old. Version
$major.$minor.$micro is required.])]
+ )
+])
+
+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="true"
+ ggzexecmoddir="\${prefix}/lib/ggz"
+ ggzdatadir="\${prefix}/share/ggz"
+ AC_SUBST(GGZ_CONFIG)
+ AC_SUBST(ggzexecmoddir)
+ AC_SUBST(ggzdatadir)
+ 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
+ pathto_app=`echo $prefix/bin/ | tr -s "/"`
+ pathto_ggz=`echo $ac_ggz_config/ | tr -s "/"`
+
+ if test "x$pathto_app" != "x$pathto_ggz"; then
+ AC_MSG_RESULT([$have_ggz_config (dismissed due to different prefix)])
+ GGZ_CONFIG="true"
+ ggzexecmoddir="\${prefix}/lib/ggz"
+ ggzdatadir="\${prefix}/share/ggz"
+ AC_SUBST(GGZ_CONFIG)
+ AC_SUBST(ggzexecmoddir)
+ AC_SUBST(ggzdatadir)
+ 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_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)
+
+ AC_ARG_ENABLE([noregistry],
+ AC_HELP_STRING([--enable-noregistry], [Do not register game modules.]),
+ [enable_noregistry=yes], [enable_noregistry=no])
+
+ GGZ_CONFIG="${ggz_config}/ggz-config"
+ if test "$enable_noregistry" = yes; then
+ GGZ_CONFIG="$GGZ_CONFIG --noregistry=$enableval"
+ fi
+ 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
+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)
+
+ LIB_GGZMOD='-lggzmod'
+ 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$ggzdconfdir" != "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,333 @@
+/**********************************************************************
+ 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;
+}
+
+/****************************************************************************
+ Handles a state event as reported by the GGZ server.
+****************************************************************************/
+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);
+
+ /* Currently no handling is done. */
+#endif
+}
+
+/****************************************************************************
+ Handles a seat-change event as reported by the GGZ server.
+****************************************************************************/
+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
+ /* These values could be useful at some point. */
+ 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);
+ }
+ }
+}
+
+/****************************************************************************
+ Handles a spectator seat event as reported by the GGZ server.
+****************************************************************************/
+static void handle_ggz_spectator_seat_event(GGZdMod *ggz, GGZdModEvent event,
+ const void *data)
+{
+#if 0
+ /* Currently spectators are not supported. TODO: spectators should be
+ * integrated with observers. */
+ 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);
+ }
+ }
+}
+
+/****************************************************************************
+ Called by the network code when there is data to be read on the given
+ GGZ socket.
+****************************************************************************/
+void input_from_ggz(int socket)
+{
+ ggzdmod_dispatch(ggzdmod);
+}
+
+/****************************************************************************
+ Return the file descriptor for the GGZ socket. The network code needs to
+ monitor this socket and call input_from_ggz when data is to be read.
+****************************************************************************/
+int get_ggz_socket(void)
+{
+ return ggzdmod_get_fd(ggzdmod);
+}
+
+static const struct player *victors[MAX_NUM_PLAYERS];
+static int num_victors;
+
+/****************************************************************************
+ Register a single player as the game victor. See ggz_report_victory().
+****************************************************************************/
+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++;
+}
+
+/****************************************************************************
+ Report victory to the GGZ server.
+
+ One or more victor players may have been registered already using
+ ggz_report_victor; all other players are assumed to be losers.
+
+ Currently AI players are not considered at all.
+****************************************************************************/
+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: Makefile.am
===================================================================
--- Makefile.am (revision 11348)
+++ Makefile.am (working copy)
@@ -64,6 +64,8 @@
m4/freetype2.m4 \
m4/gettext.m4 \
m4/gettimeofday.m4 \
+ m4/ggz.m4 \
+ m4/ggz-user.m4 \
m4/glib-2.0.m4 \
m4/glib-gettext.m4 \
m4/glib.m4 \
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] Re: (PR#14857) GGZ patch for freeciv development version,
Jason Short <=
|
|