diff -Nru rcssserver-15.1.0/ChangeLog rcssserver-15.2.2/ChangeLog --- rcssserver-15.1.0/ChangeLog 2012-05-23 06:06:56.000000000 +0000 +++ rcssserver-15.2.2/ChangeLog 2013-06-17 07:39:47.000000000 +0000 @@ -1,3 +1,134 @@ +2013-06-17 Hidehisa Akiyama + + * NEWS: + * configure.ac: + - updated a point version number. Official release 15.2.2. + +2013-06-03 Hidehisa Akiyama + + * src/referee.cpp: + - fix a bug of the backpass detection. If kick and catch are taken + simultaneously by same team players and the before kicker also + belongs to the same team, the backpass is called. + +2013-05-27 Hidehisa Akiyama + + * NEWS: + * configure.ac: + - updated a point version number. Official release 15.2.1. + + * src/referee.cpp: + - fix a bug of the backpass detection. Two or more players from + different teams kick the ball in the same game cycle, the back + passer candidate should be deteted in that game cycle. + +2013-05-22 Hidehisa Akiyama + + * NEWS: + * configure.ac: + - updated a minor version number. Official release 15.2.0. + + * src/version.h: + - updated the copyright message. + + * src/coach.cpp: + - disable new change_player_type format. this command should be + enabled again when v16 simulator is released. + + * src/referee.cpp: + * src/referee.h: + - apply the patch from Fernand Almeida. + - clean up the code. + +2013-02-13 Fernando Almeida + + * src/referee.cpp: + * src/referee.h: + - Fixed an issue with the CatchRef which did not allow a goalie to + catch the ball, after having intercepted it from an opponent, + dribbled to its own area and catch it. Regardless of the + interception position, this should never lead to a foul being + called. + +2013-05-20 Hidehisa Akiyama + + * src/audio.cpp: + * src/bodysender.cpp: + * src/fullstatesender.cpp: + * src/initsendercoach.cpp: + * src/initsenderonlinecoach.cpp: + * src/initsenderplayer.cpp: + * src/serializercoachstdv14.cpp: + * src/serializercommonstdv8.cpp: + * src/serializeronlinecoachstdv14.cpp: + * src/serializerplayerstdv14.cpp: + * src/visualsendercoach.cpp: + * src/visualsenderplayer.cpp: + - disable v16 creators. + +2013-05-16 Hidehisa Akiyama + + * configure.ac: + * m4/ax_boost_filesystem.m4: + * m4/ax_boost_system.m4: + - update autoconf macros for checking boost libraries. + - add error routine for checking boost libraries. + +2012-05-25 Hidehisa Akiyama + + * src/player.cpp: + * src/player.h: + * src/referee.cpp: + * src/referee.h: + * src/stadium.cpp: + * src/stadium.h: + - clean up the implementation of kick and tackle event + handler. now, the kick event handlers are never called when + players perform tackle command. Instead, some procedures are added + to the tackle event handler to handle a tackle event as a kicking event. + - fix defects that foul can be performed without any penalty + + * src/coach.cpp: + - added the rule that forbid to use new change_player_type command + during play_on and penalty shootouts + + * src/audio.cpp: + * src/bodysender.cpp: + * src/fullstatesender.cpp: + * src/initsender.h: + * src/initsendercoach.cpp: + * src/initsenderonlinecoach.cpp: + * src/initsenderplayer.cpp: + * src/serializercoachstdv14.cpp: + * src/serializercommonstdv8.cpp: + * src/serializeronlinecoachstdv14.cpp: + * src/serializerplayerstdv14.cpp: + * src/visualsendercoach.cpp: + * src/visualsenderplayer.cpp: + - added version 16 creators. + + * src/serverparam.cpp: + - changed the date format of log files. The second is added by + default. + +2012-05-24 Hidehisa Akiyama + + * src/netif.cpp: + * src/netif.h: + * src/Makefile.am: + * src/coach.cpp: + * src/coach.h: + * src/object.h: + * src/player.cpp: + * src/player.h: + * src/stadium.cpp: + * src/stadium.h: + * src/team.cpp: + * src/team.h: + - implemented a variation of change_player_type command, that can + change an exsiting player to goalie. not fully tested yet + - deleted netif.{h,cpp} + 2012-05-23 Hidehisa Akiyama * NEWS: diff -Nru rcssserver-15.1.0/configure rcssserver-15.2.2/configure --- rcssserver-15.1.0/configure 2012-05-23 04:19:37.000000000 +0000 +++ rcssserver-15.2.2/configure 2013-06-17 07:40:01.000000000 +0000 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for RCSSServer 15.1.0. +# Generated by GNU Autoconf 2.68 for RCSSServer 15.2.2. # # Report bugs to . # @@ -570,8 +570,8 @@ # Identity of this package. PACKAGE_NAME='RCSSServer' PACKAGE_TARNAME='rcssserver' -PACKAGE_VERSION='15.1.0' -PACKAGE_STRING='RCSSServer 15.1.0' +PACKAGE_VERSION='15.2.2' +PACKAGE_STRING='RCSSServer 15.2.2' PACKAGE_BUGREPORT='sserver-admin@users.sf.net' PACKAGE_URL='' @@ -1325,7 +1325,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures RCSSServer 15.1.0 to adapt to many kinds of systems. +\`configure' configures RCSSServer 15.2.2 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1395,7 +1395,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of RCSSServer 15.1.0:";; + short | recursive ) echo "Configuration of RCSSServer 15.2.2:";; esac cat <<\_ACEOF @@ -1528,7 +1528,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -RCSSServer configure 15.1.0 +RCSSServer configure 15.2.2 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -2199,7 +2199,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by RCSSServer $as_me 15.1.0, which was +It was created by RCSSServer $as_me 15.2.2, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -3016,7 +3016,7 @@ # Define the identity of the package. PACKAGE='rcssserver' - VERSION='15.1.0' + VERSION='15.2.2' cat >>confdefs.h <<_ACEOF @@ -17470,7 +17470,7 @@ LDFLAGS_SAVE=$LDFLAGS if test "x$ax_boost_user_system_lib" = "x"; then - for libextension in `ls $BOOSTLIBDIR/libboost_system*.so* $BOOSTLIBDIR/libboost_system*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_system.*\)\.so.*$;\1;' -e 's;^lib\(boost_system.*\)\.a*$;\1;'` ; do + for libextension in `ls -r $BOOSTLIBDIR/libboost_system* 2>/dev/null | sed 's,.*/lib,,' | sed 's,\..*,,'` ; do ax_lib=${libextension} as_ac_Lib=`$as_echo "ac_cv_lib_$ax_lib''_exit" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for exit in -l$ax_lib" >&5 @@ -17518,7 +17518,7 @@ done if test "x$link_system" != "xyes"; then - for libextension in `ls $BOOSTLIBDIR/boost_system*.{dll,a}* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_system.*\)\.dll.*$;\1;' -e 's;^\(boost_system.*\)\.a*$;\1;'` ; do + for libextension in `ls -r $BOOSTLIBDIR/boost_system* 2>/dev/null | sed 's,.*/,,' | sed -e 's,\..*,,'` ; do ax_lib=${libextension} as_ac_Lib=`$as_echo "ac_cv_lib_$ax_lib''_exit" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for exit in -l$ax_lib" >&5 @@ -17709,7 +17709,7 @@ BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/[^\/]*//'` if test "x$ax_boost_user_filesystem_lib" = "x"; then - for libextension in `ls $BOOSTLIBDIR/libboost_filesystem*.so* $BOOSTLIBDIR/libboost_filesystem*.dylib* $BOOSTLIBDIR/libboost_filesystem*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_filesystem.*\)\.so.*$;\1;' -e 's;^lib\(boost_filesystem.*\)\.dylib.*$;\1;' -e 's;^lib\(boost_filesystem.*\)\.a.*$;\1;'` ; do + for libextension in `ls -r $BOOSTLIBDIR/libboost_filesystem* 2>/dev/null | sed 's,.*/lib,,' | sed 's,\..*,,'` ; do ax_lib=${libextension} as_ac_Lib=`$as_echo "ac_cv_lib_$ax_lib''_exit" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for exit in -l$ax_lib" >&5 @@ -17757,7 +17757,7 @@ done if test "x$link_filesystem" != "xyes"; then - for libextension in `ls $BOOSTLIBDIR/boost_filesystem*.dll* $BOOSTLIBDIR/boost_filesystem*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_filesystem.*\)\.dll.*$;\1;' -e 's;^\(boost_filesystem.*\)\.a.*$;\1;'` ; do + for libextension in `ls -r $BOOSTLIBDIR/boost_filesystem* 2>/dev/null | sed 's,.*/,,' | sed -e 's,\..*,,'` ; do ax_lib=${libextension} as_ac_Lib=`$as_echo "ac_cv_lib_$ax_lib''_exit" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for exit in -l$ax_lib" >&5 @@ -18539,7 +18539,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by RCSSServer $as_me 15.1.0, which was +This file was extended by RCSSServer $as_me 15.2.2, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -18605,7 +18605,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -RCSSServer config.status 15.1.0 +RCSSServer config.status 15.2.2 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff -Nru rcssserver-15.1.0/configure.ac rcssserver-15.2.2/configure.ac --- rcssserver-15.1.0/configure.ac 2012-05-23 04:11:49.000000000 +0000 +++ rcssserver-15.2.2/configure.ac 2013-06-17 07:39:34.000000000 +0000 @@ -3,7 +3,7 @@ AC_PREREQ(2.61) LT_PREREQ([2.2]) -AC_INIT([RCSSServer],[15.1.0],[sserver-admin@users.sf.net],[rcssserver]) +AC_INIT([RCSSServer],[15.2.2],[sserver-admin@users.sf.net],[rcssserver]) #AM_INIT_AUTOMAKE([gnu 1.7.2 check-news dist-bzip2 dist-zip]) AM_INIT_AUTOMAKE([gnu 1.7.2 check-news]) diff -Nru rcssserver-15.1.0/debian/changelog rcssserver-15.2.2/debian/changelog --- rcssserver-15.1.0/debian/changelog 2014-02-20 13:35:06.000000000 +0000 +++ rcssserver-15.2.2/debian/changelog 2014-02-22 14:15:25.000000000 +0000 @@ -1,3 +1,9 @@ +rcssserver (15.2.2-0saucy0) saucy; urgency=high + + * updated a minor version number. Official release 15.2.2 + + -- Hossein Ansari Sat, 22 Feb 2014 17:43:28 +0330 + rcssserver (15.1.0-0saucy7) saucy; urgency=high * updated a minor version number. Official release 15.1.0. diff -Nru rcssserver-15.1.0/m4/ax_boost_filesystem.m4 rcssserver-15.2.2/m4/ax_boost_filesystem.m4 --- rcssserver-15.1.0/m4/ax_boost_filesystem.m4 2012-05-23 04:19:02.000000000 +0000 +++ rcssserver-15.2.2/m4/ax_boost_filesystem.m4 2013-05-27 04:09:51.000000000 +0000 @@ -31,7 +31,7 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 24 +#serial 26 AC_DEFUN([AX_BOOST_FILESYSTEM], [ @@ -81,14 +81,14 @@ AC_DEFINE(HAVE_BOOST_FILESYSTEM,,[define if the Boost::Filesystem library is available]) BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` if test "x$ax_boost_user_filesystem_lib" = "x"; then - for libextension in `ls $BOOSTLIBDIR/libboost_filesystem*.so* $BOOSTLIBDIR/libboost_filesystem*.dylib* $BOOSTLIBDIR/libboost_filesystem*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_filesystem.*\)\.so.*$;\1;' -e 's;^lib\(boost_filesystem.*\)\.dylib.*$;\1;' -e 's;^lib\(boost_filesystem.*\)\.a.*$;\1;'` ; do + for libextension in `ls -r $BOOSTLIBDIR/libboost_filesystem* 2>/dev/null | sed 's,.*/lib,,' | sed 's,\..*,,'` ; do ax_lib=${libextension} AC_CHECK_LIB($ax_lib, exit, [BOOST_FILESYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_FILESYSTEM_LIB) link_filesystem="yes"; break], [link_filesystem="no"]) done if test "x$link_filesystem" != "xyes"; then - for libextension in `ls $BOOSTLIBDIR/boost_filesystem*.dll* $BOOSTLIBDIR/boost_filesystem*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_filesystem.*\)\.dll.*$;\1;' -e 's;^\(boost_filesystem.*\)\.a.*$;\1;'` ; do + for libextension in `ls -r $BOOSTLIBDIR/boost_filesystem* 2>/dev/null | sed 's,.*/,,' | sed -e 's,\..*,,'` ; do ax_lib=${libextension} AC_CHECK_LIB($ax_lib, exit, [BOOST_FILESYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_FILESYSTEM_LIB) link_filesystem="yes"; break], diff -Nru rcssserver-15.1.0/m4/ax_boost_system.m4 rcssserver-15.2.2/m4/ax_boost_system.m4 --- rcssserver-15.1.0/m4/ax_boost_system.m4 2012-05-23 04:16:21.000000000 +0000 +++ rcssserver-15.2.2/m4/ax_boost_system.m4 2013-05-27 04:09:51.000000000 +0000 @@ -31,7 +31,7 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 14 +#serial 17 AC_DEFUN([AX_BOOST_SYSTEM], [ @@ -83,14 +83,14 @@ LDFLAGS_SAVE=$LDFLAGS if test "x$ax_boost_user_system_lib" = "x"; then - for libextension in `ls $BOOSTLIBDIR/libboost_system*.so* $BOOSTLIBDIR/libboost_system*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_system.*\)\.so.*$;\1;' -e 's;^lib\(boost_system.*\)\.a*$;\1;'` ; do + for libextension in `ls -r $BOOSTLIBDIR/libboost_system* 2>/dev/null | sed 's,.*/lib,,' | sed 's,\..*,,'` ; do ax_lib=${libextension} AC_CHECK_LIB($ax_lib, exit, [BOOST_SYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_SYSTEM_LIB) link_system="yes"; break], [link_system="no"]) done if test "x$link_system" != "xyes"; then - for libextension in `ls $BOOSTLIBDIR/boost_system*.{dll,a}* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_system.*\)\.dll.*$;\1;' -e 's;^\(boost_system.*\)\.a*$;\1;'` ; do + for libextension in `ls -r $BOOSTLIBDIR/boost_system* 2>/dev/null | sed 's,.*/,,' | sed -e 's,\..*,,'` ; do ax_lib=${libextension} AC_CHECK_LIB($ax_lib, exit, [BOOST_SYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_SYSTEM_LIB) link_system="yes"; break], diff -Nru rcssserver-15.1.0/NEWS rcssserver-15.2.2/NEWS --- rcssserver-15.1.0/NEWS 2012-05-23 05:51:48.000000000 +0000 +++ rcssserver-15.2.2/NEWS 2013-06-17 07:54:11.000000000 +0000 @@ -1,3 +1,26 @@ +[15.2.2] + * Fixed a bug of the backpass detection. If kick and catch are taken + simultaneously by same team players but the before kicker also + belongs to the same team, the backpass violation is detected. + +[15.2.1] + * Fixed a bug of the backpass detection. Two or more players from + different teams kick the ball in the same game cycle, the backpass + violation is never detected. + +[15.2.0] + * Fixed an issue with the CatchRef which did not allow a goalie to + catch the ball, after having intercepted it from an opponent, + dribbled to its own area and catch it. Regardless of the + interception position, this should never lead to a foul being + called. Thanks go to Fernando Almeida for reporting the problem + and providing the patch. + + * Changed the defalut value of server::log_date_format from + "%Y%m%d%H%M-" to "%Y%m%d%H%M%S-". + + * Fixed a defect of boost detection. + [15.1.0] * Fixed a defect of boost detection by updating autoconf macros. diff -Nru rcssserver-15.1.0/src/audio.cpp rcssserver-15.2.2/src/audio.cpp --- rcssserver-15.1.0/src/audio.cpp 2011-08-17 09:32:20.000000000 +0000 +++ rcssserver-15.2.2/src/audio.cpp 2013-05-27 04:09:51.000000000 +0000 @@ -979,6 +979,7 @@ RegHolder vp13 = AudioSenderPlayer::factory().autoReg( &create< AudioSenderPlayerv8 >, 13 ); RegHolder vp14 = AudioSenderPlayer::factory().autoReg( &create< AudioSenderPlayerv8 >, 14 ); RegHolder vp15 = AudioSenderPlayer::factory().autoReg( &create< AudioSenderPlayerv8 >, 15 ); +//RegHolder vp16 = AudioSenderPlayer::factory().autoReg( &create< AudioSenderPlayerv8 >, 16 ); template< typename Sender > AudioSender::Ptr @@ -1002,6 +1003,7 @@ RegHolder vc13 = AudioSenderCoach::factory().autoReg( &create< AudioSenderCoachv7 >, 13 ); RegHolder vc14 = AudioSenderCoach::factory().autoReg( &create< AudioSenderCoachv7 >, 14 ); RegHolder vc15 = AudioSenderCoach::factory().autoReg( &create< AudioSenderCoachv7 >, 15 ); +//RegHolder vc16 = AudioSenderCoach::factory().autoReg( &create< AudioSenderCoachv7 >, 16 ); template< typename Sender > AudioSender::Ptr @@ -1025,5 +1027,6 @@ RegHolder voc13 = AudioSenderOnlineCoach::factory().autoReg( &create< AudioSenderOnlineCoachv7 >, 13 ); RegHolder voc14 = AudioSenderOnlineCoach::factory().autoReg( &create< AudioSenderOnlineCoachv7 >, 14 ); RegHolder voc15 = AudioSenderOnlineCoach::factory().autoReg( &create< AudioSenderOnlineCoachv7 >, 15 ); +//RegHolder voc16 = AudioSenderOnlineCoach::factory().autoReg( &create< AudioSenderOnlineCoachv7 >, 16 ); } } diff -Nru rcssserver-15.1.0/src/bodysender.cpp rcssserver-15.2.2/src/bodysender.cpp --- rcssserver-15.1.0/src/bodysender.cpp 2011-08-17 09:32:20.000000000 +0000 +++ rcssserver-15.2.2/src/bodysender.cpp 2013-05-27 04:09:51.000000000 +0000 @@ -426,6 +426,7 @@ RegHolder vp13 = BodySenderPlayer::factory().autoReg( &create< BodySenderPlayerV13 >, 13 ); RegHolder vp14 = BodySenderPlayer::factory().autoReg( &create< BodySenderPlayerV14 >, 14 ); RegHolder vp15 = BodySenderPlayer::factory().autoReg( &create< BodySenderPlayerV14 >, 15 ); +//RegHolder vp16 = BodySenderPlayer::factory().autoReg( &create< BodySenderPlayerV14 >, 16 ); } } diff -Nru rcssserver-15.1.0/src/coach.cpp rcssserver-15.2.2/src/coach.cpp --- rcssserver-15.1.0/src/coach.cpp 2012-04-05 07:55:21.000000000 +0000 +++ rcssserver-15.2.2/src/coach.cpp 2013-05-27 04:28:13.000000000 +0000 @@ -42,18 +42,12 @@ #include #include +#include #include #include #include #include -// #ifdef HAVE_NETINET_IN_H -// #include -// #endif -// #ifdef HAVE_WINSOCK2_H -// #include -// #endif - namespace { PlayMode @@ -249,7 +243,6 @@ void Coach::parse_command( const char * command ) { -#if 1 char com[128]; if ( std::sscanf( command, " ( %127[-0-9a-zA-Z.+*/?<>_] ", com ) != 1 ) @@ -327,14 +320,26 @@ { char name[128]; int unum, player_type; - if ( std::sscanf( command, " ( change_player_type %s %d %d ) ", - name, &unum, &player_type ) != 3 ) + // char goalie[16]; + + if ( std::sscanf( command, " ( change_player_type %127s %d %d ) ", + name, &unum, &player_type ) == 3 ) + { + change_player_type( name, unum, player_type ); + } +#if 0 + else if ( std::sscanf( command, " ( change_player_type %127s %d %15[^ ( )] ) ", + name, &unum, goalie ) == 3 + && ! std::strncmp( goalie, "goalie", 6 ) ) + { + change_player_type_goalie( name, unum ); + } +#endif + else { send( "(error illegal_command_form)" ); - return; } - change_player_type( name, unum, player_type ); return; } //pfr:SYNCH @@ -361,178 +366,6 @@ send( "(error unknown_command)" ); return; } -#else - const char * buf = command;; - int n_read = 0; - int count = 0; - - while ( *buf != '\0' ) - { - while ( std::isspace( *buf ) ) ++buf; - if ( *buf == '\0' ) break; - - if ( ! std::strncmp( buf, "(start)", 7 ) ) - { - buf += 7; - Stadium::kick_off( M_stadium ); - send( "(ok start)" ); - } - else if ( ! std::strncmp( buf, "(change_mode ", 13 ) ) - { - int n = parse_change_mode( buf ); - if ( n == 0 ) - { - send( "(error illegal_command_form)" ); - //std::cerr << "Error parsing >" << buf << "<\n"; - return; - } - buf += n; - } - else if ( ! std::strcmp( buf, "move" ) ) - { - int n = parse_move( buf ); - if ( n == 0 ) - { - send( "(error illegal_command_form)" ); - //std::cerr << "Error parsing >" << buf << "<\n"; - return; - } - buf += n; - } - else if ( ! std::strncmp( buf, "(look)", 6 ) ) - { - buf += 6; - look(); - } - else if ( ! std::strncmp( buf, "(team_names)", 12 ) ) - { - buf += 12; - team_names(); - } - else if ( ! std::strncmp( buf, "(recover)", 9 ) ) - { - buf += 9; - recover(); - } - else if ( ! std::strncmp( buf, "(check_ball)", 12 ) ) - { - buf += 12; - check_ball(); - } - else if( ! std::strncmp( buf, "(say ", 5 ) ) - { - buf += 5; - char msg[MaxMesg]; - if ( *buf == '"' - && std::sscanf( buf, " \"%[-0-9a-zA-Z ().+*/?<>_]\" ) %n ", - msg, &n_read ) == 1 ) - { - buf += n_read; - } - else if ( std::sscanf( buf, "%[-0-9a-zA-Z ().+*/?<>_]", - msg ) == 1 ) - { - //chop_last_parenthesis( msg, ServerParam::instance().freeformMsgSize() ); - int l = std::strlen( msg ); - if ( msg[l-1] == ')' ) - { - msg[l-1] = '\0'; - } - else - { - send( "(error illegal_command_form)" ); - //std::cerr << "Error parsing >" << buf << "<\n"; - return; - } - } - else - { - send( "(error illegal_command_form)" ); - //std::cerr << "Error parsing >" << buf << "<\n"; - return; - } - - M_stadium.sendCoachAudio( *this, msg ); - send( "(ok say)" ); - } - else if ( ! std::strncmp( buf, "(ear ", 5 ) ) - { - char mode[16] ; - if ( std::sscanf( buf," ( ear %15[^ ()] ) %n ", - mode, &n_read ) != 1 ) - { - send( "(error illegal_command_form)" ); - return; - } - buf += n_read; - - ear( mode ); - return; - } - else if ( ! std::strncmp( buf, "(eye ", 5 ) ) - { - char mode[16] ; - if ( std::sscanf( buf, " ( eye %15[^ ()] ) %n ", - mode, &n_read ) != 1 ) - { - send( "(error illegal_command_form)" ); - return; - } - - eye( mode ); - return; - } - else if ( ! std::strncmp( buf, "(change_player_type ", 20 ) ) - { - char name[128]; - int unum, player_type; - if ( std::sscanf( buf, " ( change_player_type %s %d %d ) %n ", - name, &unum, &player_type, &n_read ) != 3 ) - { - send( "(error illegal_command_form)" ); - return; - } - buf += n_read; - - change_player_type( name, unum, player_type ); - return; - } - //pfr:SYNCH - else if ( ! std::strncmp( buf, "(done)", 6 ) ) - { - //std::cerr << "Recv trainer done" << std::endl; - M_done_received = true; - return; - } - else if ( ! std::strncmp( buf, "(compression ", 13 ) ) - { - int level; - if ( std::sscanf( buf, " ( compression %d ) %n ", - &level, &n_read ) != 1 ) - { - send( "(error illegal_command_form)" ); - return; - } - buf += n_read; - - compression( level ); - return; - } - else - { - send( "(error unknown_command)" ); - return; - } - - ++count; - } - - - if ( count == 0 ) - { - send( "(error illegal_command_form)" ); - } -#endif } @@ -769,19 +602,11 @@ } -#ifdef HAVE_SSTREAM std::ostringstream reply; reply << "(ok compression " << level << ")"; send ( reply.str().c_str() ); -#else - std::ostrstream reply; - reply << "(ok compression " << level << ")" << std::ends; - send ( reply.str() ); - reply.freeze( false ); -#endif setCompressionLevel ( level ); - #else send ( "(warning compression_unsupported)" ); #endif @@ -794,11 +619,7 @@ { M_observer->sendLook(); } -// #ifdef HAVE_SSTREAM // std::ostringstream ost; -// #else -// std::ostrstream ost; -// #endif // ost << "(ok look " << stad.time(); // if ( version() >= 7.0 ) @@ -856,23 +677,13 @@ // << ")" ; // } // ost << ")" << std::endl; -// #ifdef HAVE_SSTREAM // send(ost.str().c_str()); -// #else -// ost << std::ends; -// send(ost.str()); -// ost.freeze(); -// #endif } void Coach::team_names() { -#ifdef HAVE_SSTREAM std::ostringstream ost; -#else - std::ostrstream ost; -#endif ost << "(ok team_names"; @@ -887,13 +698,7 @@ } ost << ")" << std::endl; -#ifdef HAVE_SSTREAM send( ost.str().c_str() ); -#else - ost<< std::ends; - send( ost.str() ); - ost.freeze(); -#endif } void @@ -901,16 +706,9 @@ { M_stadium.recoveryPlayers(); -#ifdef HAVE_SSTREAM std::ostringstream ost; ost << "(ok recover)" << std::endl; send( ost.str().c_str() ); -#else - std::ostrstream ost; - ost << "(ok recover)" << std::endl << std::ends; - send( ost.str() ); - ost.freeze(); -#endif } @@ -919,7 +717,6 @@ int unum, int player_type ) { - const Team * team = NULL; if ( M_stadium.teamLeft().name() == team_name ) { @@ -970,17 +767,84 @@ send( buf ); } +void +Coach::change_player_type_goalie( const std::string & team_name, + int unum ) +{ + const Team * team = NULL; + if ( M_stadium.teamLeft().name() == team_name ) + { + team = &( M_stadium.teamLeft() ); + } + + if ( M_stadium.teamRight().name() == team_name ) + { + team = &( M_stadium.teamRight() ); + } + + if ( ! team ) + { + send( "(warning no_team_found)" ); + return; + } + + if ( change_player_type_goalie_impl( team, unum ) ) + { + char buf[64]; + snprintf ( buf, 64, "(ok change_player_type %s %d goalie)", + team_name.c_str(), unum ); + send( buf ); + } +} + +bool +Coach::change_player_type_goalie_impl( const Team * team, + int unum ) +{ + if ( ! team ) + { + send( "(warning no_team_found)" ); + return false; + } + + const Player * player = static_cast< const Player * >( 0 ); + + for ( int i = 0; i < team->size(); ++i ) + { + const Player * p = team->player( i ); + + if ( ! p ) continue; + if ( ! p->isEnabled() ) continue; + + if ( p->isGoalie() ) + { + send( "(error goalie_already_exists)" ); + return false; + } + + if ( p->unum() == unum ) + { + player = p; + } + } + + if ( ! player ) + { + send( "(warning no_such_player)" ); + return false; + } + + M_stadium.changePlayerToGoalie( player ); + + return true; +} void Coach::send_visual_info() { M_observer->sendVisual(); -// #ifdef HAVE_SSTREAM // std::ostringstream ost; -// #else -// std::ostrstream ost; -// #endif // if ( version() >= 7.0 ) // ost << "(see_global " << M_stadium.time(); @@ -1059,42 +923,21 @@ // } // } // ost << ")" << std::endl; -// #ifdef HAVE_SSTREAM // send( ost.str().c_str() ); -// #else -// ost << std::ends; - -// send( ost.str() ); -// ost.freeze( false ); -// #endif } void Coach::check_ball() { -#ifdef HAVE_SSTREAM - std::ostringstream ost; -#else - std::ostrstream ost; -#endif - static const char * BallPosInfoStr[] = BALL_POS_INFO_STRINGS; BallPosInfo info = M_stadium.ballPosInfo(); + std::ostringstream ost; ost << "(ok check_ball " << M_stadium.time() << " " ; - ost << BallPosInfoStr[info] << ")"; - ost << std::ends; -#ifdef HAVE_SSTREAM send( ost.str().c_str() ); -#else - ost << std::ends; - - send( ost.str() ); - ost.freeze( false ); -#endif } @@ -1138,11 +981,7 @@ { if ( M_assigned ) { - //std::cout << "An online coach disconnected\n"; std::cout << "An online coach disconnected : (" -// << ( side() == LEFT -// ? M_stadium.teamLeft().name() -// : M_stadium.teamRight().name() ); << M_team.name(); if ( ! name().empty() ) std::cout << " " << name(); std::cout << ")\n"; @@ -1529,22 +1368,26 @@ eye( mode ); return; } -// else if ( ! std::strcmp( com, "change_player_types" ) ) -// { -// change_player_types( command ); -// return; -// } else if ( ! std::strcmp ( com, "change_player_type" ) ) { int unum, player_type; + char goalie[16]; if ( std::sscanf( command, " ( change_player_type %d %d )", - &unum, &player_type ) != 2 ) + &unum, &player_type ) == 2 ) + { + change_player_type( unum, player_type ); + } + else if ( std::sscanf( command, " ( change_player_type %d %15[^ ( )] ) ", + &unum, goalie ) == 2 + && ! std::strncmp( goalie, "goalie", 6 ) ) + { + change_player_type_goalie( unum ); + } + else { send( "(error illegal_command_form)" ); - return; } - change_player_type( unum, player_type ); return; } //pfr:SYNCH @@ -1776,7 +1619,6 @@ send( buf ); } - void OnlineCoach::change_player_types( const char * command ) { @@ -2009,16 +1851,38 @@ M_team.addTeamGraphic( x, y, holder ); M_stadium.sendTeamGraphic( side(), x, y ); -#ifdef HAVE_SSTREAM std::ostringstream msg; msg << "(ok team_graphic " << x << " " << y << ")"; send( msg.str().c_str() ); -#else - std::ostrstream msg; - msg << "(ok team_graphic " << x << " " << y << ")" << std::ends; - send( msg.str() ); - msg.freeze( false ); -#endif +} + + +void +OnlineCoach::change_player_type_goalie( int unum ) +{ + const PlayMode pm = M_stadium.playmode(); + if ( pm == PM_PlayOn ) + { + send( "(warning cannot_change_goalie_while_playon)" ); + return; + } + + if ( pm == PM_PenaltyReady_Left + || pm == PM_PenaltyReady_Right + || pm == PM_PenaltyTaken_Left + || pm == PM_PenaltyTaken_Right ) + { + send( "(warning cannot_change_goalie_while_penalty_taken)" ); + return; + } + + if ( change_player_type_goalie_impl( &M_team, unum ) ) + { + char buf[64]; + snprintf( buf, 64, "(ok change_player_type %d goalie)", + unum ); + send( buf ); + } } diff -Nru rcssserver-15.1.0/src/coach.h rcssserver-15.2.2/src/coach.h --- rcssserver-15.1.0/src/coach.h 2011-08-17 09:32:20.000000000 +0000 +++ rcssserver-15.2.2/src/coach.h 2013-05-27 04:09:51.000000000 +0000 @@ -90,7 +90,7 @@ const size_t & len ); virtual - void parse_command( const char *command ); + void parse_command( const char * command ); virtual Side side() const @@ -112,8 +112,7 @@ return M_hear; } - const - double & version() const + double version() const { return M_version; } @@ -130,17 +129,27 @@ void change_mode( std::string mode ); void ear( std::string mode ); -public: - void eye( std::string mode ); - void compression( int level ); - void look(); - void team_names(); + void recover(); - void check_ball(); void change_player_type( const std::string & team_name, int unum, int player_type ); + void change_player_type_goalie( const std::string & team_name, + int unum ); + +protected: + void check_ball(); + void look(); + void team_names(); + void eye( std::string mode ); + bool change_player_type_goalie_impl( const Team * team, + int unum ); + void compression( int level ); + + void sendOKEye(); + +public: void send_visual_info(); void resetCommandFlags() @@ -149,11 +158,6 @@ } void sendExternalMsg(); - -protected: - - void sendOKEye(); - }; /*! @@ -237,24 +241,25 @@ private: void change_player_types( const char * command ); -public: + void change_player_type( int unum, int player_type ); + void change_player_type_goalie( int unum ); + void team_graphic( const char * command ); +public: + void sendPlayerClangVer(); + void sendPlayerClangVer( const Player & player ); /* this deques and says any messages which should come out returns the number of messages se nt out */ int check_message_queue( int time ); - //returns whether it updated anything bool update_messages_left( int time ); - void sendPlayerClangVer(); - void sendPlayerClangVer( const Player & player ); - }; #endif diff -Nru rcssserver-15.1.0/src/fullstatesender.cpp rcssserver-15.2.2/src/fullstatesender.cpp --- rcssserver-15.1.0/src/fullstatesender.cpp 2011-08-17 09:32:20.000000000 +0000 +++ rcssserver-15.2.2/src/fullstatesender.cpp 2013-05-27 04:09:51.000000000 +0000 @@ -477,6 +477,7 @@ RegHolder vp13 = FullStateSenderPlayer::factory().autoReg( &create< FullStateSenderPlayerV13 >, 13 ); RegHolder vp14 = FullStateSenderPlayer::factory().autoReg( &create< FullStateSenderPlayerV13 >, 14 ); RegHolder vp15 = FullStateSenderPlayer::factory().autoReg( &create< FullStateSenderPlayerV13 >, 15 ); +//RegHolder vp16 = FullStateSenderPlayer::factory().autoReg( &create< FullStateSenderPlayerV13 >, 16 ); } } diff -Nru rcssserver-15.1.0/src/initsendercoach.cpp rcssserver-15.2.2/src/initsendercoach.cpp --- rcssserver-15.1.0/src/initsendercoach.cpp 2011-08-17 09:32:20.000000000 +0000 +++ rcssserver-15.2.2/src/initsendercoach.cpp 2013-05-27 04:09:51.000000000 +0000 @@ -220,6 +220,7 @@ RegHolder vc13 = InitSenderOfflineCoach::factory().autoReg( &create< InitSenderOfflineCoachV8 >, 13 ); RegHolder vc14 = InitSenderOfflineCoach::factory().autoReg( &create< InitSenderOfflineCoachV8 >, 14 ); RegHolder vc15 = InitSenderOfflineCoach::factory().autoReg( &create< InitSenderOfflineCoachV8 >, 15 ); +//RegHolder vc16 = InitSenderOfflineCoach::factory().autoReg( &create< InitSenderOfflineCoachV8 >, 16 ); } } diff -Nru rcssserver-15.1.0/src/initsender.h rcssserver-15.2.2/src/initsender.h --- rcssserver-15.1.0/src/initsender.h 2011-08-17 09:32:20.000000000 +0000 +++ rcssserver-15.2.2/src/initsender.h 2013-05-27 04:09:51.000000000 +0000 @@ -61,12 +61,12 @@ const Stadium & stadium, unsigned int version, const bool new_line = false ) - : M_transport( transport ) - , M_serializer( serializer ) - , M_stadium( stadium ) - , M_version( version ) - , M_new_line( new_line ) - {} + : M_transport( transport ), + M_serializer( serializer ), + M_stadium( stadium ), + M_version( version ), + M_new_line( new_line ) + { } virtual ~InitSenderCommon() @@ -77,14 +77,12 @@ return M_transport; } - const - Serializer & serializer() + const Serializer & serializer() { return *M_serializer; } - const - Stadium & stadium() + const Stadium & stadium() { return M_stadium; } @@ -191,7 +189,7 @@ stad, version, new_line ) - {} + { } virtual ~InitSenderCommonV1() @@ -234,7 +232,7 @@ stad, version, new_line ) - {} + { } virtual ~InitSenderCommonV7() diff -Nru rcssserver-15.1.0/src/initsenderonlinecoach.cpp rcssserver-15.2.2/src/initsenderonlinecoach.cpp --- rcssserver-15.1.0/src/initsenderonlinecoach.cpp 2011-08-17 09:32:20.000000000 +0000 +++ rcssserver-15.2.2/src/initsenderonlinecoach.cpp 2013-05-27 04:09:51.000000000 +0000 @@ -304,6 +304,7 @@ RegHolder voc13 = InitSenderOnlineCoach::factory().autoReg( &create< InitSenderOnlineCoachV8 >, 13 ); RegHolder voc14 = InitSenderOnlineCoach::factory().autoReg( &create< InitSenderOnlineCoachV8 >, 14 ); RegHolder voc15 = InitSenderOnlineCoach::factory().autoReg( &create< InitSenderOnlineCoachV8 >, 15 ); +//RegHolder voc16 = InitSenderOnlineCoach::factory().autoReg( &create< InitSenderOnlineCoachV8 >, 16 ); } } diff -Nru rcssserver-15.1.0/src/initsenderplayer.cpp rcssserver-15.2.2/src/initsenderplayer.cpp --- rcssserver-15.1.0/src/initsenderplayer.cpp 2011-08-17 09:32:20.000000000 +0000 +++ rcssserver-15.2.2/src/initsenderplayer.cpp 2013-05-27 04:09:51.000000000 +0000 @@ -283,6 +283,7 @@ RegHolder vp13 = InitSenderPlayer::factory().autoReg( &create< InitSenderPlayerV8 >, 13 ); RegHolder vp14 = InitSenderPlayer::factory().autoReg( &create< InitSenderPlayerV8 >, 14 ); RegHolder vp15 = InitSenderPlayer::factory().autoReg( &create< InitSenderPlayerV8 >, 15 ); +//RegHolder vp16 = InitSenderPlayer::factory().autoReg( &create< InitSenderPlayerV8 >, 16 ); } } diff -Nru rcssserver-15.1.0/src/Makefile.am rcssserver-15.2.2/src/Makefile.am --- rcssserver-15.1.0/src/Makefile.am 2011-08-17 09:32:20.000000000 +0000 +++ rcssserver-15.2.2/src/Makefile.am 2013-05-27 04:09:51.000000000 +0000 @@ -103,7 +103,6 @@ logger.cpp \ main.cpp \ monitor.cpp \ - netif.cpp \ pcombuilder.cpp \ pcomparser.cpp \ player.cpp \ diff -Nru rcssserver-15.1.0/src/Makefile.in rcssserver-15.2.2/src/Makefile.in --- rcssserver-15.1.0/src/Makefile.in 2012-05-23 04:19:39.000000000 +0000 +++ rcssserver-15.2.2/src/Makefile.in 2013-06-17 07:40:02.000000000 +0000 @@ -120,9 +120,9 @@ initsendermonitor.$(OBJEXT) initsenderonlinecoach.$(OBJEXT) \ initsenderplayer.$(OBJEXT) landmarkreader.$(OBJEXT) \ logger.$(OBJEXT) main.$(OBJEXT) monitor.$(OBJEXT) \ - netif.$(OBJEXT) pcombuilder.$(OBJEXT) pcomparser.$(OBJEXT) \ - player.$(OBJEXT) playerparam.$(OBJEXT) object.$(OBJEXT) \ - referee.$(OBJEXT) remoteclient.$(OBJEXT) resultsaver.$(OBJEXT) \ + pcombuilder.$(OBJEXT) pcomparser.$(OBJEXT) player.$(OBJEXT) \ + playerparam.$(OBJEXT) object.$(OBJEXT) referee.$(OBJEXT) \ + remoteclient.$(OBJEXT) resultsaver.$(OBJEXT) \ serializer.$(OBJEXT) serializercoachstdv1.$(OBJEXT) \ serializercoachstdv7.$(OBJEXT) serializercoachstdv8.$(OBJEXT) \ serializercoachstdv13.$(OBJEXT) \ @@ -421,7 +421,6 @@ logger.cpp \ main.cpp \ monitor.cpp \ - netif.cpp \ pcombuilder.cpp \ pcomparser.cpp \ player.cpp \ @@ -799,7 +798,6 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logger.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/monitor.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netif.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/object.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcombuilder.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcomparser.Po@am__quote@ diff -Nru rcssserver-15.1.0/src/netif.cpp rcssserver-15.2.2/src/netif.cpp --- rcssserver-15.1.0/src/netif.cpp 2011-08-17 09:32:20.000000000 +0000 +++ rcssserver-15.2.2/src/netif.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,735 +0,0 @@ -/* -*- Mode: C++ -*- - *Header: - *File: netif.C (for C++ & cc) - *Author: Noda Itsuki - *Date: 1996/02/14 - *EndHeader: - */ - -/* - *Copyright: - - Copyright (C) 1996-2000 Electrotechnical Laboratory. - Itsuki Noda, Yasuo Kuniyoshi and Hitoshi Matsubara. - Copyright (C) 2000, 2001 RoboCup Soccer Server Maintainance Group. - Patrick Riley, Tom Howard, Daniel Polani, Itsuki Noda, - Mikhail Prokopenko, Jan Wendler - Copyright (C) 2002- RoboCup Soccer Simulator Maintainance Group. - - This file is a part of SoccerServer. - - This code is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - *EndCopyright: - */ - -// [2000/01/14:I.Noda] -// escape prototype of recvfrom -// for escape conversion of signed-unsigned ints -//#define recvfrom _escape_recvfrom -// - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "stadium.h" - -#include "param.h" -#include "types.h" -#include "utility.h" -#include "object.h" -#include "coach.h" -#include "player.h" - -#include "random.h" -#include "serializer.h" -#include "clangparser.h" -#include "clangmsg.h" -//#include "coach_lang_comp.h" -#include "clangmsgbuilder.h" -#include "xpmholder.h" -#include "remoteclient.h" -#include "monitor.h" - -#include - -#include -#include -#include -#include - -// #ifdef __APPLE__ -// extern "C" { -// int isnan (double); -// } -// #endif - - -/* - *=================================================================== - *Part: Recv - *=================================================================== - */ - -namespace { -template < class T > -void -recv_from_clients( std::vector< T > & clients ) -{ - std::random_shuffle( clients.begin(), clients.end(), - irand ); //rcss::random::UniformRNG::instance() ); - - for ( typename std::vector< T >::iterator i = clients.begin(); - i != clients.end(); ) - { - if ( (*i)->recv() == -1 ) - { - ++i; - } - } -} -} - - -void -Stadium::udp_recv_message() -{ - recv_from_clients( M_remote_players ); - recv_from_clients( M_monitors ); - - while ( 1 ) - { - char message[MaxMesg]; - std::memset( &message, 0, sizeof( char ) * MaxMesg ); - - rcss::net::Addr cli_addr; - - int len = M_player_socket.recv( message, MaxMesg, cli_addr ); - - if ( len > 0 ) - { - // std::cerr << "Got: "; - // std::cerr.write( message, iMsgLength ); - // std::cerr << std::endl; - - bool found = false; - for ( PlayerCont::iterator i = M_remote_players.begin(); - i != M_remote_players.end(); - ++i ) - { - if ( (*i)->getDest() == cli_addr ) - { - (*i)->undedicatedRecv( message, len ); - found = true; - break; - } - } - - if ( ! found ) - { - for ( MonitorCont::iterator i = M_monitors.begin(); - i != M_monitors.end(); - ++i ) - { - if ( (*i)->getDest() == cli_addr ) - { - (*i)->undedicatedRecv( message, len ); - found = true; - break; - } - } - } - - if ( ! found ) - { - // a new monitor or a new player - - /* chop newline */ - if ( message[len - 1] == '\n' ) - { - --len; - } - message[len] = '\0'; - - if ( ! parseMonitorInit( message, cli_addr ) ) - { - parsePlayerInit( message, cli_addr ); - } - } - } - else if ( errno != EWOULDBLOCK ) - { - std::cerr << __FILE__ << ": " << __LINE__ - << ": Error recv'ing from socket: " - << std::strerror( errno ) << std::endl; - } - - if ( len < 0 ) - { - break; - } - } -} - - - -void -Stadium::parsePlayerInit( const char * message, - const rcss::net::Addr & cli_addr ) -{ - // - // init : a new player connects to the server - // - if ( ! std::strncmp( message, "(init ", std::strlen( "(init " ) ) ) - { - // (init [(version )][ (goalie)]) - - const char * msg = message; - - char teamname[16]; - double version = 3.0; - bool goalie = false; - - int n_read = 0; - if ( std::sscanf( msg, " ( init %15[+-_a-zA-Z0-9] %n ", - teamname, &n_read ) != 1 - || n_read == 0 ) - { - sendToPlayer( "(error illegal_teamname)", cli_addr ); - return; - } - msg += n_read; - - if ( *msg != '(' && *msg != ')' && ! std::isspace( *msg ) ) - { - sendToPlayer( "(error illegal_teamname_or_too_long_teamname)", cli_addr ); - return; - } - - while ( *msg != '\0' && *msg != '(' ) ++msg; - - while ( *msg != '\0' && *msg != ')' ) - { - if ( ! std::strncmp( msg, "(version ", std::strlen( "(version " ) ) ) - { - n_read = 0; - if ( std::sscanf( msg, " ( version %lf ) %n ", - &version, &n_read ) != 1 - || n_read == 0 ) - { - sendToPlayer( "(error illegal_command_form)", cli_addr ); - return; - } - msg += n_read; - } - else if ( ! std::strncmp( msg, "(goalie)", std::strlen( "(goalie)" ) ) ) - { - goalie = true; - msg += std::strlen( "(goalie)" ); - } - else - { - sendToPlayer( "(error illegal_command_form)", cli_addr ); - return; - } - - if ( *msg != '(' && *msg != ')' && ! std::isspace( *msg ) ) - { - sendToPlayer( "(error illegal_command_form)", cli_addr ); - return; - } - - while ( *msg != '\0' && std::isspace( *msg ) ) ++msg; - } - - Player * p = initPlayer( teamname, version, goalie, cli_addr ); - if ( p ) - { - std::cout << "A new (v" << static_cast< int >( version ) << ") " - << "player (" << teamname << ' ' << p->unum() << ") connected." - << std::endl; - - M_logger.writePlayerLog( *p, message, RECV ); - } - - return; - } - - // - // reconnect : a player reconnects to the server - // - if ( ! std::strncmp( message, "(reconnect ", std::strlen( "(reconnect " ) ) ) - { - if ( playmode() == PM_PlayOn ) - { - sendToPlayer( "(error cannot_reconnect_while_playon)", cli_addr ); - return; - } - - char teamname[128]; - int unum; - - if ( std::sscanf( message, - " ( reconnect %127s %d ) ", - teamname, &unum ) < 2 ) - { - sendToPlayer( "(error illegal_command_form)", cli_addr ); - } - - Player * p = reconnectPlayer( teamname, unum, cli_addr ); - if ( p ) - { - std::cout << "A player (" << teamname << ' ' << p->unum() << ") reconnected." - << std::endl; - M_logger.writePlayerLog( *p, message, RECV ); - } - - return; - } - - sendToPlayer( "(error unknown_command)", cli_addr ); -} - - -bool -Stadium::parseMonitorInit( const char * message, - const rcss::net::Addr & addr ) -{ - double ver = 1.0; - if ( ! std::strncmp( message, "(dispinit)", 10 ) - || std::sscanf( message, " ( dispinit version %lf ) ", &ver ) == 1 ) - { - if ( ServerParam::instance().maxMonitors() > 0 - && static_cast< int >( M_monitors.size() ) >= ServerParam::instance().maxMonitors() ) - { - sendToPlayer( "(error no_more_monitor)", addr ); - return true; - } - - // a new monitor connected - Monitor * mon = new Monitor( *this, ver ); - - if( ! mon->connect( addr ) ) - { - sendToPlayer( "(error connection_failed)", addr ); - delete mon; - return true; - } - - if ( ! mon->setSenders() ) - { - sendToPlayer( "(error illegal_client_version)", addr ); - delete mon; - return true; - } - std::cout << "A new (v" << ver << ") monitor connected." << std::endl; - - mon->setEnforceDedicatedPort( ver >= 2.0 ); - M_monitors.push_back( mon ); - - // send server parameter information to monitor - mon->sendInit(); - return true; - } - - return false; -} - -void -Stadium::udp_recv_from_coach() -{ - const bool allow_coach = ( ServerParam::instance().coachMode() - || ServerParam::instance().coachWithRefereeMode() ); - - if ( allow_coach ) - { - recv_from_clients( M_remote_offline_coaches ); - } - - while ( 1 ) - { - char message[MaxMesg]; - std::memset( &message, 0, sizeof( char ) * MaxMesg ); - - rcss::net::Addr cli_addr; - - int len = M_offline_coach_socket.recv( message, MaxMesg, cli_addr ); - - if ( len > 0 ) - { - if ( ! allow_coach ) - { - sendToCoach( "(error connected_offline_coach_without_coach_mode)", cli_addr ); - continue; - } - - bool found = false; - for ( OfflineCoachCont::iterator i = M_remote_offline_coaches.begin(); - i != M_remote_offline_coaches.end(); - ++i ) - { - if ( (*i)->getDest() == cli_addr ) - { - (*i)->undedicatedRecv( message, len ); - found = true; - break; - } - } - - if ( ! found ) - { - // a new offline coach - - // chop newline - if ( message[len - 1] == '\n' ) - { - --len; - } - message[len] = '\0'; - - parseCoachInit( message, cli_addr ); - } - } - else if ( errno != EWOULDBLOCK ) - { - std::cerr << __FILE__ << ": " << __LINE__ - << ": Error recv'ing from socket: " - << strerror( errno ) << std::endl; - } - - if ( len < 0 ) - { - break; - } - } -} - -bool -Stadium::parseCoachInit( const char * message, - const rcss::net::Addr & cli_addr ) -{ - if ( ! M_remote_offline_coaches.empty() ) - { - sendToCoach( "(error already_have_offline_coach)", cli_addr ); - return false; - } - - char command[128]; - int n = std::sscanf( message, " ( %127[-0-9a-zA-Z.+*/?<>_] ", command ); - if( n < 1 ) - { - sendToCoach( "(error illegal_command_form)", cli_addr ); - return false; - } - - // (init[ (version )]) - - if ( ! std::strcmp( command, "init" ) ) - { - double version = 3.0; - int n = std::sscanf( message, " ( init ( version %lf ) ) ", &version ); - if ( ( n != 0 && n != 1 ) - || version < 1.0 ) - { - sendToCoach( "(error illegal_command_form)", cli_addr ); - return false; - } - - Coach * coach = initCoach( version, cli_addr ); - if ( coach ) - { - std::cout << "A new (v" << coach->version() << ") " - << "offline coach connected" << std::endl; - M_logger.writeCoachLog( message, RECV ); - } - } - else - { - kickOff(); // need to remove this line if we - // dont want the server to start when the coach connects - M_coach->parse_command( message ); - M_logger.writeCoachLog( message, RECV ); - } - - return true; -} - -void -Stadium::udp_recv_from_online_coach() -{ - recv_from_clients( M_remote_online_coaches ); - - while ( 1 ) - { - char message[MaxMesg]; - std::memset( &message, 0, sizeof ( char ) * MaxMesg ); - - rcss::net::Addr cli_addr; - - int len = M_online_coach_socket.recv( message, MaxMesg, cli_addr ); - - if ( len > 0 ) - { - bool found = false; - for ( OnlineCoachCont::iterator i = M_remote_online_coaches.begin(); - i != M_remote_online_coaches.end(); - ++i ) - { - if ( (*i)->getDest() == cli_addr ) - { - (*i)->undedicatedRecv( message, len ); - found = true; - break; - } - } - if ( ! found ) - { - // a new online coach - - /* chop newline */ - if ( message[len - 1] == '\n' ) - { - --len; - } - message[len] = '\0'; - - parseOnlineCoachInit( message, cli_addr ); - } - } - else if ( errno != EWOULDBLOCK ) - { - std::cerr << __FILE__ << ": " << __LINE__ - << ": Error recv'ing from socket: " - << strerror( errno ) << std::endl; - } - - if ( len < 0 ) - { - break; - } - } -} - -void -Stadium::parseOnlineCoachInit( const char * message, - const rcss::net::Addr & addr ) -{ - if ( std::strncmp( message, "(init", std::strlen( "(init" ) ) != 0 ) - { - sendToOnlineCoach( "(error illegal_command_form)", - addr ); - return; - } - - // (init [ ][ (version )]) - - const char * msg = message; - - const double default_olcoach_version = 5.0; - - char teamname[16]; - char coachname[128]; - double version = default_olcoach_version; - - std::memset( teamname, 0, 16 ); - std::memset( coachname, 0, 128 ); - - int n_read = 0; - - // read team name - if ( std::sscanf( msg, " ( init %15[+-_a-zA-Z0-9] %n ", - teamname, &n_read ) != 1 - || n_read == 0 ) - { - sendToOnlineCoach( "(error illegal_command_form)", addr ); - return; - } - msg += n_read; - - while ( *msg != '\0' && std::isspace( *msg ) ) ++msg; - - // read coach name - if ( *msg != '(' ) - { - if ( std::sscanf( msg, " %127[+-_a-zA-Z0-9] %n ", - coachname, &n_read ) != 1 ) - { - sendToOnlineCoach( "(error illegal_command_form)", addr ); - return; - } - msg += n_read; - - if ( *msg != '(' && *msg != ')' && ! std::isspace( *msg ) ) - { - sendToOnlineCoach( "(error illegal_coachname_or_too_long_coachname)", addr ); - return; - } - } - - while ( *msg != '\0' && *msg != '(' ) ++msg; - - // read protocol version - if ( ! std::strncmp( "(version", msg, std::strlen( "(version" ) ) ) - { - if ( std::sscanf( msg, " ( version %lf ) %n ", - &version, &n_read ) != 1 - || n_read == 0 ) - { - sendToOnlineCoach( "(error illegal_command_form)", addr ); - return; - } - msg += n_read; - - if ( *msg != '(' && *msg != ')' && ! std::isspace( *msg ) ) - { - sendToOnlineCoach( "(error illegal_client_version)", addr ); - return; - } - - if ( version < default_olcoach_version ) - { - sendToOnlineCoach( "(error illegal_client_version)", addr ); - return; - } - } - - // - // assign new online coach - // - - OnlineCoach * olc = initOnlineCoach( teamname, coachname, version, addr ); - if ( olc ) - { - std::cout << "A new (v" << static_cast< int >( version ) << ") " - << "online coach (" << teamname << ") connected." - << std::endl;; - - M_logger.writeOnlineCoachLog( *olc, message, RECV ); - } -} - -void -Stadium::sendToPlayer( const char * msg, - const rcss::net::Addr & cli_addr ) -{ - if ( M_player_socket.send( msg, std::strlen( msg ) + 1, cli_addr ) == -1 ) - { - std::cerr << __FILE__ ": " << __LINE__ - << ": Error sending to socket: " - << strerror( errno ) << std::endl; - } -} - -void -Stadium::sendToCoach( const char * msg, - const rcss::net::Addr & cli_addr ) -{ - if ( M_offline_coach_socket.send( msg, std::strlen( msg ) + 1, cli_addr ) == -1 ) - { - std::cerr << __FILE__ ": " << __LINE__ - << ": Error sending to socket: " - << strerror( errno ) << std::endl; - } -} - -void -Stadium::sendToOnlineCoach( const char * msg, - const rcss::net::Addr & cli_addr ) -{ - if ( M_online_coach_socket.send( msg, std::strlen( msg ) + 1, cli_addr ) == -1 ) - { - std::cerr << __FILE__ ": " << __LINE__ - << ": Error sending to socket: " - << strerror( errno ) << std::endl; - } -} - - -void -Stadium::broadcastSubstitution( const int side, - const int unum, - const int player_type ) -{ - char allies[64]; - char enemies[64]; - snprintf( allies, 64, "(change_player_type %d %d)", unum, player_type ); - snprintf( enemies, 64, "(change_player_type %d)", unum ); - - // tell players - for ( int i = 0 ; i < MAX_PLAYER * 2; ++i ) - { - if ( ! M_players[i]->isEnabled() ) continue; - if ( M_players[i]->version() < 7.0 ) continue; - - if ( ( side == LEFT && M_players[i]->team() == M_team_l ) - || ( side == RIGHT && M_players[i]->team() == M_team_r ) ) - { - M_players[i]->send( allies ); - } - else - { - M_players[i]->send( enemies ); - } - } - - // tell coaches - if ( M_olcoaches[1] - && M_olcoaches[1]->assigned() - && M_olcoaches[1]->version() >= 7.0 ) - { - if ( side == RIGHT ) - { - //team_r->olcoach()->send( allies ); - M_olcoaches[1]->send( allies ); - } - if ( side == LEFT ) - { - //team_r->olcoach()->send( enemies ); - M_olcoaches[1]->send( enemies ); - } - } - - if ( M_olcoaches[0] - && M_olcoaches[0]->assigned() - && M_olcoaches[0]->version() >= 7.0 ) - { - if ( side == LEFT ) - { - //team_l->olcoach()->send( allies ); - M_olcoaches[0]->send( allies ); - } - if ( side == RIGHT ) - { - //team_l->olcoach()->send( enemies ); - M_olcoaches[0]->send( enemies ); - } - } - - // TODO: send to offline coach - - char buffer[64]; - snprintf( buffer, 64, - "(change_player_type %s %d %d)", - ( side == LEFT ? "l" : "r" ), - unum, player_type ); - for ( MonitorCont::iterator i = M_monitors.begin(); - i != M_monitors.end(); ++i ) - { - (*i)->sendMsg( MSG_BOARD, buffer ); - } - - M_logger.writeTextLog( buffer, SUBS ); -} diff -Nru rcssserver-15.1.0/src/object.h rcssserver-15.2.2/src/object.h --- rcssserver-15.1.0/src/object.h 2012-05-18 04:22:34.000000000 +0000 +++ rcssserver-15.2.2/src/object.h 2013-05-27 04:09:51.000000000 +0000 @@ -414,20 +414,17 @@ return M_id; } - const - std::string & name() const + const std::string & name() const { return M_name; } - const - std::string & shortName() const + const std::string & shortName() const { return M_short_name; } - const - std::string & closeName() const + const std::string & closeName() const { return M_close_name; } @@ -437,20 +434,17 @@ return M_short_close_name; } - const - double & objectVersion() const + double objectVersion() const { return M_object_version; } - const - double & size() const + double size() const { return M_size; } - const - PVector & pos() const + const PVector & pos() const { return M_pos; } diff -Nru rcssserver-15.1.0/src/player.cpp rcssserver-15.2.2/src/player.cpp --- rcssserver-15.1.0/src/player.cpp 2011-08-17 09:32:20.000000000 +0000 +++ rcssserver-15.2.2/src/player.cpp 2013-05-27 04:09:51.000000000 +0000 @@ -267,7 +267,7 @@ } bool -Player::init( const double & ver, +Player::init( const double ver, const bool goalie ) { M_version = ver; @@ -447,6 +447,22 @@ } void +Player::changeToGoalie() +{ + M_goalie = true; + + setEnable(); + + { + char lname[128], sname[128]; + snprintf( lname, 128, PLAYER_NAME_FORMAT, team()->name().c_str(), unum() ); + snprintf( sname, 128, PLAYER_NAME_FORMAT_SHORT, team()->name().c_str(), unum(), + isGoalie() ? GOALIE_VISUAL_STRING : "" ); + setName( lname, sname ); + } +} + +void Player::parseMsg( char * msg, const size_t & len ) { @@ -2027,8 +2043,7 @@ drand( -M_PI, M_PI ) ); accel += tackle_noise; - M_stadium.kickTaken( *this, accel ); - M_stadium.tackleTaken( *this, foul ); + M_stadium.tackleTaken( *this, accel, foul ); } else { @@ -2130,7 +2145,7 @@ } // 2008-02-09 akiyama -// comand to change the see message timer +// command to change the see message timer void Player::synch_see() { diff -Nru rcssserver-15.1.0/src/player.h rcssserver-15.2.2/src/player.h --- rcssserver-15.1.0/src/player.h 2011-08-17 09:32:20.000000000 +0000 +++ rcssserver-15.2.2/src/player.h 2013-05-27 04:09:51.000000000 +0000 @@ -194,7 +194,7 @@ int number ); ~Player(); - bool init( const double & ver, + bool init( const double ver, const bool goalie ); bool setSenders(); @@ -202,6 +202,8 @@ void disable(); void discard(); + void changeToGoalie(); + // // receive message // diff -Nru rcssserver-15.1.0/src/referee.cpp rcssserver-15.2.2/src/referee.cpp --- rcssserver-15.1.0/src/referee.cpp 2012-05-18 04:54:59.000000000 +0000 +++ rcssserver-15.2.2/src/referee.cpp 2013-06-17 07:34:58.000000000 +0000 @@ -342,7 +342,7 @@ { // according to FIFA the ball is catchable if it is at // least partly within the penalty area, thus we add ball size - static RArea pen_area( PVector( +ServerParam::PITCH_LENGTH/2 + static RArea pen_area( PVector( + ServerParam::PITCH_LENGTH/2 - ServerParam::PENALTY_AREA_LENGTH/2.0, 0.0 ), PVector( ServerParam::PENALTY_AREA_LENGTH @@ -804,6 +804,126 @@ } } +void +Referee::checkFoul( const Player & tackler, + const bool foul, + bool * detect_charge, + bool * detect_yellow, + bool * detect_red ) +{ + bool foul_charge = false; + bool yellow_card = false; + bool red_card = false; + + boost::bernoulli_distribution<> rng( tackler.foulDetectProbability() ); + boost::variate_generator< rcss::random::DefaultRNG &, boost::bernoulli_distribution<> > + dst( rcss::random::DefaultRNG::instance(), rng ); + + // 2011-05-14 akiyama + // added red card probability + boost::bernoulli_distribution<> red_rng( ServerParam::instance().redCardProbability() ); + boost::variate_generator< rcss::random::DefaultRNG &, boost::bernoulli_distribution<> > + red_dst( rcss::random::DefaultRNG::instance(), red_rng ); + + const double ball_dist2 = tackler.pos().distance2( M_stadium.ball().pos() ); + const double ball_angle = ( M_stadium.ball().pos() - tackler.pos() ).th(); + + //std::cerr << M_stadium.time() << " (tackleTaken) " + // << " (tackler " << SideStr( tackler.side() ) << ' ' << tackler.unum() << ")" + // << std::endl; + + const Stadium::PlayerCont::iterator end = M_stadium.players().end(); + for ( Stadium::PlayerCont::iterator p = M_stadium.players().begin(); + p != end; + ++p ) + { + if ( ! (*p)->isEnabled() ) continue; + if ( (*p)->side() == tackler.side() ) continue; + + if ( ! (*p)->ballKickable() ) continue; // no kickable + + bool pre_check = false; + if ( foul ) + { + (*p)->setFoulCharged(); + + //std::cerr << "---->" << (*p)->unum() << " intentional foul. prob=" << rng.p() << std::endl; + if ( dst() ) + { + //std::cerr << "----> " << (*p)->unum() << " detected intentional foul." << std::endl; + pre_check = true; + foul_charge = true; + } + } + + if ( ! (*p)->dashed() ) + { + //std::cerr << "----> " << (*p)->unum() << " no dash." << std::endl; + continue; // no dashing + } + + PVector player_rel = (*p)->pos() - tackler.pos(); + + if ( player_rel.r2() > ball_dist2 ) + { + //std::cerr << "----> " << (*p)->unum() << " ball near." << std::endl; + continue; // further than ball + } + + //std::cerr << "--> (player " << SideStr( (*p)->side() ) << ' ' << (*p)->unum() << ")\n"; + + player_rel.rotate( -ball_angle ); + + if ( player_rel.x < 0.0 + || std::fabs( player_rel.y ) > (*p)->size() + tackler.size() ) + { + //std::cerr << "----> " << (*p)->unum() << " behind or big y_diff. rel=" << player_rel + // << std::endl; + continue; + } + + double body_diff = std::fabs( normalize_angle( (*p)->angleBodyCommitted() - ball_angle ) ); + if ( body_diff > M_PI*0.5 ) + { + //std::cerr << "----> " << (*p)->unum() << " over body angle. angle=" << body_diff / M_PI * 180.0 + // << std::endl; + continue; + } + + if ( foul ) + { + if ( pre_check ) + { + //std::cerr << "----> " << (*p)->unum() << " detected yellow_card." << std::endl; + yellow_card = true; + if ( red_dst() ) + { + yellow_card = false; + red_card = true; + } + } + } + else + { + if ( dst() ) + { + //std::cerr << "----> " << (*p)->unum() << " detected foul. prob=" << rng.p() << std::endl; + foul_charge = true; + if ( red_dst() ) + { + yellow_card = true; + } + } + } + //std::cerr << "----> not detected foul. prob=" << rng.p()<< std::endl; + } + + *detect_charge = foul_charge; + *detect_yellow = yellow_card; + *detect_red = red_card; +} + + //********** // BallStuckRef //********** @@ -865,6 +985,13 @@ } void +OffsideRef::tackleTaken( const Player & tackler, + const bool ) +{ + setOffsideMark( tackler ); +} + +void OffsideRef::failedTackleTaken( const Player & tackler ) { checkIntentionalAction( tackler ); @@ -1020,7 +1147,6 @@ if ( M_last_kick_time == M_stadium.time() && M_last_kick_stoppage_time == M_stadium.stoppageTime() ) { - M_last_kicker_side = NEUTRAL; M_offside_candidates.clear(); return; @@ -1390,6 +1516,13 @@ } void +FreeKickRef::tackleTaken( const Player & tackler, + const bool ) +{ + kickTaken( tackler ); +} + +void FreeKickRef::ballTouched( const Player & player ) { if ( ( M_stadium.playmode() == PM_GoalKick_Left @@ -1930,6 +2063,14 @@ } } + +void +TouchRef::tackleTaken( const Player & tackler, + const bool ) +{ + kickTaken( tackler ); +} + void TouchRef::ballTouched( const Player & kicker ) { @@ -2091,74 +2232,61 @@ void CatchRef::kickTaken( const Player & kicker ) { - // if ( ! kicker.isGoalie() ) + if ( kicker.side() == LEFT ) { - if ( kicker.side() == LEFT ) - { - M_team_l_touched = true; - } - else if ( kicker.side() == RIGHT ) - { - M_team_r_touched = true; - } + M_team_l_touched = true; + } + else if ( kicker.side() == RIGHT ) + { + M_team_r_touched = true; + } - if ( M_team_l_touched && M_team_r_touched ) - { - M_last_back_passer = NULL; - } - else if ( kicker.isGoalie() ) - { - if ( M_last_back_passer - && M_last_back_passer->side() != kicker.side() ) - { + if ( M_team_l_touched && M_team_r_touched ) + { + M_last_back_passer = NULL; + M_before_last_back_passer = NULL; + return; + } - } - else - { - M_last_back_passer = &kicker; - M_last_back_passer_time = M_stadium.time(); - } - } - else if ( M_last_back_passer != &kicker ) - { - M_last_back_passer = &kicker; - if ( ! M_last_back_passer - || M_last_back_passer->side() != kicker.side() ) - { - M_last_back_passer_time = M_stadium.time(); - } - } + //! check if a different player kicked the ball + if ( M_last_back_passer != &kicker ) + { + M_before_last_back_passer = M_last_back_passer; + M_last_back_passer = &kicker; + M_last_back_passer_time = M_stadium.time(); + } + else + { + //! same player is kicking the ball again, update last kick time + M_last_back_passer_time = M_stadium.time(); } - // else if ( M_last_back_passer != NULL - // && M_last_back_passer->team() != kicker.team() ) - // { - // M_last_back_passer = NULL; - // // The else if above is to handle rare situations where a player from team - // // A kicks the ball, the goalie from team B kicks it, and then the goalie - // // from team A cacthes it. This should not be concidered a back pass and - // // the else if make sure of that. - // } +} + +void +CatchRef::tackleTaken( const Player & tackler, + const bool ) +{ + kickTaken( tackler ); } void CatchRef::ballTouched( const Player & player ) { // If ball is not kicked, back pass violation is never taken. - // if ( ! player.isGoalie() ) + + if ( player.side() == LEFT ) { - if ( player.side() == LEFT ) - { - M_team_l_touched = true; - } - else if ( player.side() == RIGHT ) - { - M_team_r_touched = true; - } + M_team_l_touched = true; + } + else if ( player.side() == RIGHT ) + { + M_team_r_touched = true; + } - if ( M_team_l_touched && M_team_r_touched ) - { - M_last_back_passer = NULL; - } + if ( M_team_l_touched && M_team_r_touched ) + { + M_before_last_back_passer = NULL; + M_last_back_passer = NULL; } } @@ -2181,25 +2309,38 @@ } // check backpass violation - if ( M_stadium.playmode() != PM_AfterGoal_Left + if ( ServerParam::instance().backPasses() + && M_stadium.playmode() != PM_AfterGoal_Left && M_stadium.playmode() != PM_AfterGoal_Right && M_stadium.playmode() != PM_TimeOver - && M_stadium.time() != M_last_back_passer_time && M_last_back_passer != NULL - //&& M_last_back_passer != &catcher - && M_last_back_passer->team() == catcher.team() - && ServerParam::instance().backPasses() ) + && M_last_back_passer->team() == catcher.team() ) { - //M_last_back_passer->alive |= BACK_PASS; - M_stadium.setPlayerState( M_last_back_passer->side(), - M_last_back_passer->unum(), - BACK_PASS ); - callBackPass( catcher.side() ); + if ( M_last_back_passer == &catcher + && M_before_last_back_passer != NULL + && M_before_last_back_passer->team() != catcher.team() ) + { + // no backpass violation, if last kicker is goalie itself and before kicker is opponent + } + else if ( M_stadium.time() == M_last_back_passer_time + && ( M_before_last_back_passer == NULL + || M_before_last_back_passer->team() != catcher.team() ) ) + { + // no backpass violation. kick and catch are taken simultaneously + } + else + { + M_stadium.setPlayerState( M_last_back_passer->side(), + M_last_back_passer->unum(), + BACK_PASS ); + callBackPass( catcher.side() ); - return; + return; + } } M_last_back_passer = NULL; + M_before_last_back_passer = NULL; awardFreeKick( catcher.side(), M_stadium.ball().pos() ); } @@ -2213,7 +2354,6 @@ return; } - // check handling violation if ( M_stadium.playmode() != PM_AfterGoal_Left && M_stadium.playmode() != PM_AfterGoal_Right @@ -2230,20 +2370,28 @@ && M_stadium.playmode() != PM_TimeOver && M_stadium.time() != M_last_back_passer_time && M_last_back_passer != NULL - //&& M_last_back_passer != &catcher && M_last_back_passer->team() == catcher.team() && ServerParam::instance().backPasses() ) { - //M_last_back_passer->alive |= BACK_PASS; - M_stadium.setPlayerState( M_last_back_passer->side(), - M_last_back_passer->unum(), - BACK_PASS ); - callBackPass( catcher.side() ); + if ( M_last_back_passer == &catcher + && M_before_last_back_passer + && M_before_last_back_passer->team() != catcher.team() ) + { + // no backpass violatoin, if last kicker is goalie itself and before kicker is opponent + } + else + { + M_stadium.setPlayerState( M_last_back_passer->side(), + M_last_back_passer->unum(), + BACK_PASS ); + callBackPass( catcher.side() ); + } return; } M_last_back_passer = NULL; + M_before_last_back_passer = NULL; } @@ -2351,6 +2499,7 @@ { if ( pmode != PM_PlayOn ) { + M_before_last_back_passer = NULL; M_last_back_passer = NULL; } @@ -2358,7 +2507,6 @@ || pmode == PM_Back_Pass_Left ) { M_stadium.clearBallCatcher(); - M_last_back_passer = NULL; M_after_back_pass_time = 0; } else if ( pmode == PM_CatchFault_Left @@ -2431,108 +2579,7 @@ bool detect_yellow = false; bool detect_red = false; - boost::bernoulli_distribution<> rng( tackler.foulDetectProbability() ); - boost::variate_generator< rcss::random::DefaultRNG &, boost::bernoulli_distribution<> > - dst( rcss::random::DefaultRNG::instance(), rng ); - - // 2011-05-14 akiyama - // added red card probability - boost::bernoulli_distribution<> red_rng( ServerParam::instance().redCardProbability() ); - boost::variate_generator< rcss::random::DefaultRNG &, boost::bernoulli_distribution<> > - red_dst( rcss::random::DefaultRNG::instance(), red_rng ); - - const double ball_dist2 = tackler.pos().distance2( M_stadium.ball().pos() ); - const double ball_angle = ( M_stadium.ball().pos() - tackler.pos() ).th(); - - //std::cerr << M_stadium.time() << " (tackleTaken) " - // << " (tackler " << SideStr( tackler.side() ) << ' ' << tackler.unum() << ")" - // << std::endl; - - const Stadium::PlayerCont::iterator end = M_stadium.players().end(); - for ( Stadium::PlayerCont::iterator p = M_stadium.players().begin(); - p != end; - ++p ) - { - if ( ! (*p)->isEnabled() ) continue; - if ( (*p)->side() == tackler.side() ) continue; - - if ( ! (*p)->ballKickable() ) continue; // no kickable - - bool pre_check = false; - if ( foul ) - { - (*p)->setFoulCharged(); - - //std::cerr << "---->" << (*p)->unum() << " intentional foul. prob=" << rng.p() << std::endl; - if ( dst() ) - { - //std::cerr << "----> " << (*p)->unum() << " detected intentional foul." << std::endl; - pre_check = true; - detect_charge = true; - } - } - - if ( ! (*p)->dashed() ) - { - //std::cerr << "----> " << (*p)->unum() << " no dash." << std::endl; - continue; // no dashing - } - - PVector player_rel = (*p)->pos() - tackler.pos(); - - if ( player_rel.r2() > ball_dist2 ) - { - //std::cerr << "----> " << (*p)->unum() << " ball near." << std::endl; - continue; // further than ball - } - - //std::cerr << "--> (player " << SideStr( (*p)->side() ) << ' ' << (*p)->unum() << ")\n"; - - player_rel.rotate( -ball_angle ); - - if ( player_rel.x < 0.0 - || std::fabs( player_rel.y ) > (*p)->size() + tackler.size() ) - { - //std::cerr << "----> " << (*p)->unum() << " behind or big y_diff. rel=" << player_rel - // << std::endl; - continue; - } - - double body_diff = std::fabs( normalize_angle( (*p)->angleBodyCommitted() - ball_angle ) ); - if ( body_diff > M_PI*0.5 ) - { - //std::cerr << "----> " << (*p)->unum() << " over body angle. angle=" << body_diff / M_PI * 180.0 - // << std::endl; - continue; - } - - if ( foul ) - { - if ( pre_check ) - { - //std::cerr << "----> " << (*p)->unum() << " detected yellow_card." << std::endl; - detect_yellow = true; - if ( red_dst() ) - { - detect_red = true; - } - } - } - else - { - if ( dst() ) - { - //std::cerr << "----> " << (*p)->unum() << " detected foul. prob=" << rng.p() << std::endl; - detect_charge = true; - if ( red_dst() ) - { - detect_yellow = true; - } - } - } - - //std::cerr << "----> not detected foul. prob=" << rng.p()<< std::endl; - } + checkFoul( tackler, foul, &detect_charge, &detect_yellow, &detect_red ); if ( detect_red ) { @@ -3270,11 +3317,6 @@ return; } - if ( M_bDebug ) - { - std::cerr << "kick taken in mode " << M_stadium.playmode() << std::endl; - } - if ( M_stadium.ballCatcher() != NULL ) { std::cerr << "player kicked and goalie catched at the same time" << std::endl; @@ -3322,7 +3364,7 @@ && ! kicker.isGoalie() ) { // field player in the defending team must not kick the ball. - penalty_foul( (Side)( -M_cur_pen_taker ) ); + penalty_foul( static_cast< Side >( -M_cur_pen_taker ) ); } else { @@ -3356,8 +3398,45 @@ { M_stadium.placeBall( M_pen_side, M_stadium.ball().pos() ); } + } + +void +PenaltyRef::tackleTaken( const Player & tackler, + const bool foul ) +{ + if ( ! isPenaltyShootOut( M_stadium.playmode() ) ) + { + return; + } + + bool detect_charge = false; + bool detect_yellow = false; + bool detect_red = false; + + checkFoul( tackler, foul, &detect_charge, &detect_yellow, &detect_red ); + + if ( detect_charge + || detect_yellow + || detect_red ) + { + if ( tackler.side() == M_cur_pen_taker ) + { + penalty_foul( M_cur_pen_taker ); + } + else + { + penalty_foul( static_cast< Side >( -M_cur_pen_taker ) ); + } + } + else + { + kickTaken( tackler ); + } +} + + void PenaltyRef::playModeChange( PlayMode pm ) { @@ -3458,9 +3537,6 @@ void PenaltyRef::penalty_foul( const Side side ) { - if ( M_bDebug ) - std::cerr << "penalty_foul " << side << std::endl; - M_stadium.sendRefereeAudio( ( side == LEFT ? "penalty_foul_l" : "penalty_foul_r" ) ); diff -Nru rcssserver-15.1.0/src/referee.h rcssserver-15.2.2/src/referee.h --- rcssserver-15.1.0/src/referee.h 2011-08-17 09:32:20.000000000 +0000 +++ rcssserver-15.2.2/src/referee.h 2013-05-27 04:09:51.000000000 +0000 @@ -249,6 +249,13 @@ void clearPlayersFromBall( const Side side ); + + void checkFoul( const Player & tackler, + const bool foul, + bool * detect_charge, + bool * detect_yellow, + bool * detect_red ); + public: static PVector truncateToPitch( PVector ball_pos ); @@ -362,6 +369,10 @@ void failedKickTaken( const Player & kicker ); virtual + void tackleTaken( const Player & tackler, + const bool foul ); + + virtual void failedTackleTaken( const Player & kicker ); virtual @@ -419,6 +430,10 @@ void kickTaken( const Player & kicker ); virtual + void tackleTaken( const Player & kicker, + const bool foul ); + + virtual void ballTouched( const Player & player ); virtual @@ -482,6 +497,10 @@ void kickTaken( const Player & kicker ); virtual + void tackleTaken( const Player & kicker, + const bool foul ); + + virtual void ballTouched( const Player & player ); virtual @@ -507,8 +526,22 @@ static const int AFTER_BACKPASS_WAIT; static const int AFTER_CATCH_FAULT_WAIT; + struct Kicker { + int time_; + Side side_; + int unum_; + Kicker( const int time, + const Side side, + const int unum ) + : time_( time ), + side_( side ), + unum_( unum ) + { } + }; + int M_last_back_passer_time; const Player * M_last_back_passer; + const Player * M_before_last_back_passer; bool M_team_l_touched; bool M_team_r_touched; @@ -522,6 +555,7 @@ : Referee( stadium ), M_last_back_passer_time( 0 ), M_last_back_passer( NULL ), + M_before_last_back_passer( NULL ), M_team_l_touched( false ), M_team_r_touched( false ), M_after_back_pass_time( 0 ), @@ -536,6 +570,10 @@ void kickTaken( const Player & kicker ); virtual + void tackleTaken( const Player & kicker, + const bool foul ); + + virtual void ballTouched( const Player & player ); virtual @@ -664,6 +702,10 @@ void kickTaken( const Player & kicker ); virtual + void tackleTaken( const Player & tackler, + const bool foul ); + + virtual void playModeChange( PlayMode pm ); virtual diff -Nru rcssserver-15.1.0/src/serializercoachstdv14.cpp rcssserver-15.2.2/src/serializercoachstdv14.cpp --- rcssserver-15.1.0/src/serializercoachstdv14.cpp 2011-08-17 09:32:20.000000000 +0000 +++ rcssserver-15.2.2/src/serializercoachstdv14.cpp 2013-05-27 04:09:51.000000000 +0000 @@ -136,6 +136,7 @@ namespace { RegHolder v14 = SerializerCoach::factory().autoReg( &SerializerCoachStdv14::create, 14 ); RegHolder v15 = SerializerCoach::factory().autoReg( &SerializerCoachStdv14::create, 15 ); +//RegHolder v16 = SerializerCoach::factory().autoReg( &SerializerCoachStdv14::create, 16 ); } } diff -Nru rcssserver-15.1.0/src/serializercommonstdv8.cpp rcssserver-15.2.2/src/serializercommonstdv8.cpp --- rcssserver-15.1.0/src/serializercommonstdv8.cpp 2011-08-17 09:32:20.000000000 +0000 +++ rcssserver-15.2.2/src/serializercommonstdv8.cpp 2013-05-27 04:09:51.000000000 +0000 @@ -106,6 +106,7 @@ RegHolder v13 = SerializerCommon::factory().autoReg( &SerializerCommonStdv8::create, 13 ); RegHolder v14 = SerializerCommon::factory().autoReg( &SerializerCommonStdv8::create, 14 ); RegHolder v15 = SerializerCommon::factory().autoReg( &SerializerCommonStdv8::create, 15 ); +//RegHolder v16 = SerializerCommon::factory().autoReg( &SerializerCommonStdv8::create, 16 ); } } diff -Nru rcssserver-15.1.0/src/serializeronlinecoachstdv14.cpp rcssserver-15.2.2/src/serializeronlinecoachstdv14.cpp --- rcssserver-15.1.0/src/serializeronlinecoachstdv14.cpp 2011-08-17 09:32:20.000000000 +0000 +++ rcssserver-15.2.2/src/serializeronlinecoachstdv14.cpp 2013-05-27 04:09:51.000000000 +0000 @@ -62,6 +62,7 @@ namespace { RegHolder v14 = SerializerOnlineCoach::factory().autoReg( &SerializerOnlineCoachStdv14::create, 14 ); RegHolder v15 = SerializerOnlineCoach::factory().autoReg( &SerializerOnlineCoachStdv14::create, 15 ); +//RegHolder v16 = SerializerOnlineCoach::factory().autoReg( &SerializerOnlineCoachStdv14::create, 16 ); } } diff -Nru rcssserver-15.1.0/src/serializerplayerstdv14.cpp rcssserver-15.2.2/src/serializerplayerstdv14.cpp --- rcssserver-15.1.0/src/serializerplayerstdv14.cpp 2011-08-17 09:32:20.000000000 +0000 +++ rcssserver-15.2.2/src/serializerplayerstdv14.cpp 2013-05-27 04:09:51.000000000 +0000 @@ -140,6 +140,7 @@ namespace { RegHolder v14 = SerializerPlayer::factory().autoReg( &SerializerPlayerStdv14::create, 14 ); RegHolder v15 = SerializerPlayer::factory().autoReg( &SerializerPlayerStdv14::create, 15 ); +//RegHolder v16 = SerializerPlayer::factory().autoReg( &SerializerPlayerStdv14::create, 16 ); } } diff -Nru rcssserver-15.1.0/src/serverparam.cpp rcssserver-15.2.2/src/serverparam.cpp --- rcssserver-15.1.0/src/serverparam.cpp 2011-08-17 09:32:20.000000000 +0000 +++ rcssserver-15.2.2/src/serverparam.cpp 2013-05-27 04:09:51.000000000 +0000 @@ -237,7 +237,7 @@ const int ServerParam::GAME_LOG_FIXED = false; const int ServerParam::TEXT_LOG_DATED = true; const int ServerParam::GAME_LOG_DATED = true; -const std::string ServerParam::LOG_DATE_FORMAT = "%Y%m%d%H%M-"; +const std::string ServerParam::LOG_DATE_FORMAT = "%Y%m%d%H%M%S-"; const int ServerParam::LOG_TIMES = false; const int ServerParam::RECORD_MESSAGES = false; const int ServerParam::TEXT_LOG_COMPRESSION = 0; diff -Nru rcssserver-15.1.0/src/stadium.cpp rcssserver-15.2.2/src/stadium.cpp --- rcssserver-15.1.0/src/stadium.cpp 2012-05-18 04:32:29.000000000 +0000 +++ rcssserver-15.2.2/src/stadium.cpp 2013-05-27 04:09:51.000000000 +0000 @@ -1572,6 +1572,148 @@ } void +Stadium::broadcastSubstitution( const int side, + const int unum, + const int player_type ) +{ + char allies[64]; + char enemies[64]; + snprintf( allies, 64, "(change_player_type %d %d)", unum, player_type ); + snprintf( enemies, 64, "(change_player_type %d)", unum ); + + // tell players + for ( int i = 0 ; i < MAX_PLAYER * 2; ++i ) + { + if ( ! M_players[i]->isEnabled() ) continue; + if ( M_players[i]->version() < 7.0 ) continue; + + if ( ( side == LEFT && M_players[i]->team() == M_team_l ) + || ( side == RIGHT && M_players[i]->team() == M_team_r ) ) + { + M_players[i]->send( allies ); + } + else + { + M_players[i]->send( enemies ); + } + } + + // tell coaches + if ( M_olcoaches[1] + && M_olcoaches[1]->assigned() + && M_olcoaches[1]->version() >= 7.0 ) + { + if ( side == RIGHT ) + { + //team_r->olcoach()->send( allies ); + M_olcoaches[1]->send( allies ); + } + if ( side == LEFT ) + { + //team_r->olcoach()->send( enemies ); + M_olcoaches[1]->send( enemies ); + } + } + + if ( M_olcoaches[0] + && M_olcoaches[0]->assigned() + && M_olcoaches[0]->version() >= 7.0 ) + { + if ( side == LEFT ) + { + //team_l->olcoach()->send( allies ); + M_olcoaches[0]->send( allies ); + } + if ( side == RIGHT ) + { + //team_l->olcoach()->send( enemies ); + M_olcoaches[0]->send( enemies ); + } + } + + // TODO: send to offline coach + + char buffer[64]; + snprintf( buffer, 64, + "(change_player_type %s %d %d)", + ( side == LEFT ? "l" : "r" ), + unum, player_type ); + for ( MonitorCont::iterator i = M_monitors.begin(); + i != M_monitors.end(); ++i ) + { + (*i)->sendMsg( MSG_BOARD, buffer ); + } + + M_logger.writeTextLog( buffer, SUBS ); +} + + +bool +Stadium::changePlayerToGoalie( const Player * player ) +{ + if ( player->side() == LEFT ) + { + if ( M_team_l->changePlayerToGoalie( player ) ) + { + broadcastChangePlayerToGoalie( player ); + return true; + } + } + else if ( player->side() == RIGHT ) + { + if ( M_team_r->changePlayerToGoalie( player ) ) + { + broadcastChangePlayerToGoalie( player ); + return true; + } + } + + return false; +} + +void +Stadium::broadcastChangePlayerToGoalie( const Player * player ) +{ + char msg[64]; + snprintf( msg, 64, "(change_player_type %c %d goalie)", + player->side() == LEFT ? 'l' : player->side() == RIGHT ? 'r' : '?', + player->unum() ); + + // tell players + for ( int i = 0 ; i < MAX_PLAYER * 2; ++i ) + { + if ( M_players[i]->isEnabled() + && M_players[i]->version() >= 16.0 ) + { + M_players[i]->send( msg ); + } + } + + // tell coaches + for ( int i = 0; i < 2; ++i ) + { + if ( M_olcoaches[i] + && M_olcoaches[i]->assigned() + && M_olcoaches[i]->version() >= 16.0 ) + { + M_olcoaches[i]->send( msg ); + } + } + + // TODO: send to offline coach + + // monitors + for ( MonitorCont::iterator i = M_monitors.begin(); + i != M_monitors.end(); ++i ) + { + (*i)->sendMsg( MSG_BOARD, msg ); + } + + M_logger.writeTextLog( msg, SUBS ); +} + + +void Stadium::collisions() { bool col = false; @@ -1812,8 +1954,13 @@ void Stadium::tackleTaken( const Player & tackler, + const PVector & accel, const bool foul ) { + M_ball_catcher = static_cast< const Player * >( 0 ); + + M_ball->push( accel ); + for_each( M_referees.begin(), M_referees.end(), Referee::doTackleTaken( tackler, foul ) ); } @@ -2538,6 +2685,581 @@ return shutdown; } + + +namespace { +template < class T > +void +recv_from_clients( std::vector< T > & clients ) +{ + std::random_shuffle( clients.begin(), clients.end(), + irand ); //rcss::random::UniformRNG::instance() ); + + for ( typename std::vector< T >::iterator i = clients.begin(); + i != clients.end(); ) + { + if ( (*i)->recv() == -1 ) + { + ++i; + } + } +} +} + + +void +Stadium::udp_recv_message() +{ + recv_from_clients( M_remote_players ); + recv_from_clients( M_monitors ); + + while ( 1 ) + { + char message[MaxMesg]; + std::memset( &message, 0, sizeof( char ) * MaxMesg ); + + rcss::net::Addr cli_addr; + + int len = M_player_socket.recv( message, MaxMesg, cli_addr ); + + if ( len > 0 ) + { + // std::cerr << "Got: "; + // std::cerr.write( message, iMsgLength ); + // std::cerr << std::endl; + + bool found = false; + for ( PlayerCont::iterator i = M_remote_players.begin(); + i != M_remote_players.end(); + ++i ) + { + if ( (*i)->getDest() == cli_addr ) + { + (*i)->undedicatedRecv( message, len ); + found = true; + break; + } + } + + if ( ! found ) + { + for ( MonitorCont::iterator i = M_monitors.begin(); + i != M_monitors.end(); + ++i ) + { + if ( (*i)->getDest() == cli_addr ) + { + (*i)->undedicatedRecv( message, len ); + found = true; + break; + } + } + } + + if ( ! found ) + { + // a new monitor or a new player + + /* chop newline */ + if ( message[len - 1] == '\n' ) + { + --len; + } + message[len] = '\0'; + + if ( ! parseMonitorInit( message, cli_addr ) ) + { + parsePlayerInit( message, cli_addr ); + } + } + } + else if ( errno != EWOULDBLOCK ) + { + std::cerr << __FILE__ << ": " << __LINE__ + << ": Error recv'ing from socket: " + << std::strerror( errno ) << std::endl; + } + + if ( len < 0 ) + { + break; + } + } +} + + + +void +Stadium::parsePlayerInit( const char * message, + const rcss::net::Addr & cli_addr ) +{ + // + // init : a new player connects to the server + // + if ( ! std::strncmp( message, "(init ", std::strlen( "(init " ) ) ) + { + // (init [(version )][ (goalie)]) + + const char * msg = message; + + char teamname[16]; + double version = 3.0; + bool goalie = false; + + int n_read = 0; + if ( std::sscanf( msg, " ( init %15[+-_a-zA-Z0-9] %n ", + teamname, &n_read ) != 1 + || n_read == 0 ) + { + sendToPlayer( "(error illegal_teamname)", cli_addr ); + return; + } + msg += n_read; + + if ( *msg != '(' && *msg != ')' && ! std::isspace( *msg ) ) + { + sendToPlayer( "(error illegal_teamname_or_too_long_teamname)", cli_addr ); + return; + } + + while ( *msg != '\0' && *msg != '(' ) ++msg; + + while ( *msg != '\0' && *msg != ')' ) + { + if ( ! std::strncmp( msg, "(version ", std::strlen( "(version " ) ) ) + { + n_read = 0; + if ( std::sscanf( msg, " ( version %lf ) %n ", + &version, &n_read ) != 1 + || n_read == 0 ) + { + sendToPlayer( "(error illegal_command_form)", cli_addr ); + return; + } + msg += n_read; + } + else if ( ! std::strncmp( msg, "(goalie)", std::strlen( "(goalie)" ) ) ) + { + goalie = true; + msg += std::strlen( "(goalie)" ); + } + else + { + sendToPlayer( "(error illegal_command_form)", cli_addr ); + return; + } + + if ( *msg != '(' && *msg != ')' && ! std::isspace( *msg ) ) + { + sendToPlayer( "(error illegal_command_form)", cli_addr ); + return; + } + + while ( *msg != '\0' && std::isspace( *msg ) ) ++msg; + } + + Player * p = initPlayer( teamname, version, goalie, cli_addr ); + if ( p ) + { + std::cout << "A new (v" << static_cast< int >( version ) << ") " + << "player (" << teamname << ' ' << p->unum() << ") connected." + << std::endl; + + M_logger.writePlayerLog( *p, message, RECV ); + } + + return; + } + + // + // reconnect : a player reconnects to the server + // + if ( ! std::strncmp( message, "(reconnect ", std::strlen( "(reconnect " ) ) ) + { + if ( playmode() == PM_PlayOn ) + { + sendToPlayer( "(error cannot_reconnect_while_playon)", cli_addr ); + return; + } + + char teamname[128]; + int unum; + + if ( std::sscanf( message, + " ( reconnect %127s %d ) ", + teamname, &unum ) < 2 ) + { + sendToPlayer( "(error illegal_command_form)", cli_addr ); + } + + Player * p = reconnectPlayer( teamname, unum, cli_addr ); + if ( p ) + { + std::cout << "A player (" << teamname << ' ' << p->unum() << ") reconnected." + << std::endl; + M_logger.writePlayerLog( *p, message, RECV ); + } + + return; + } + + sendToPlayer( "(error unknown_command)", cli_addr ); +} + + +bool +Stadium::parseMonitorInit( const char * message, + const rcss::net::Addr & addr ) +{ + double ver = 1.0; + if ( ! std::strncmp( message, "(dispinit)", 10 ) + || std::sscanf( message, " ( dispinit version %lf ) ", &ver ) == 1 ) + { + if ( ServerParam::instance().maxMonitors() > 0 + && static_cast< int >( M_monitors.size() ) >= ServerParam::instance().maxMonitors() ) + { + sendToPlayer( "(error no_more_monitor)", addr ); + return true; + } + + // a new monitor connected + Monitor * mon = new Monitor( *this, ver ); + + if( ! mon->connect( addr ) ) + { + sendToPlayer( "(error connection_failed)", addr ); + delete mon; + return true; + } + + if ( ! mon->setSenders() ) + { + sendToPlayer( "(error illegal_client_version)", addr ); + delete mon; + return true; + } + std::cout << "A new (v" << ver << ") monitor connected." << std::endl; + + mon->setEnforceDedicatedPort( ver >= 2.0 ); + M_monitors.push_back( mon ); + + // send server parameter information to monitor + mon->sendInit(); + return true; + } + + return false; +} + +void +Stadium::udp_recv_from_coach() +{ + const bool allow_coach = ( ServerParam::instance().coachMode() + || ServerParam::instance().coachWithRefereeMode() ); + + if ( allow_coach ) + { + recv_from_clients( M_remote_offline_coaches ); + } + + while ( 1 ) + { + char message[MaxMesg]; + std::memset( &message, 0, sizeof( char ) * MaxMesg ); + + rcss::net::Addr cli_addr; + + int len = M_offline_coach_socket.recv( message, MaxMesg, cli_addr ); + + if ( len > 0 ) + { + if ( ! allow_coach ) + { + sendToCoach( "(error connected_offline_coach_without_coach_mode)", cli_addr ); + continue; + } + + bool found = false; + for ( OfflineCoachCont::iterator i = M_remote_offline_coaches.begin(); + i != M_remote_offline_coaches.end(); + ++i ) + { + if ( (*i)->getDest() == cli_addr ) + { + (*i)->undedicatedRecv( message, len ); + found = true; + break; + } + } + + if ( ! found ) + { + // a new offline coach + + // chop newline + if ( message[len - 1] == '\n' ) + { + --len; + } + message[len] = '\0'; + + parseCoachInit( message, cli_addr ); + } + } + else if ( errno != EWOULDBLOCK ) + { + std::cerr << __FILE__ << ": " << __LINE__ + << ": Error recv'ing from socket: " + << strerror( errno ) << std::endl; + } + + if ( len < 0 ) + { + break; + } + } +} + +bool +Stadium::parseCoachInit( const char * message, + const rcss::net::Addr & cli_addr ) +{ + if ( ! M_remote_offline_coaches.empty() ) + { + sendToCoach( "(error already_have_offline_coach)", cli_addr ); + return false; + } + + char command[128]; + int n = std::sscanf( message, " ( %127[-0-9a-zA-Z.+*/?<>_] ", command ); + if( n < 1 ) + { + sendToCoach( "(error illegal_command_form)", cli_addr ); + return false; + } + + // (init[ (version )]) + + if ( ! std::strcmp( command, "init" ) ) + { + double version = 3.0; + int n = std::sscanf( message, " ( init ( version %lf ) ) ", &version ); + if ( ( n != 0 && n != 1 ) + || version < 1.0 ) + { + sendToCoach( "(error illegal_command_form)", cli_addr ); + return false; + } + + Coach * coach = initCoach( version, cli_addr ); + if ( coach ) + { + std::cout << "A new (v" << coach->version() << ") " + << "offline coach connected" << std::endl; + M_logger.writeCoachLog( message, RECV ); + } + } + else + { + kickOff(); // need to remove this line if we + // dont want the server to start when the coach connects + M_coach->parse_command( message ); + M_logger.writeCoachLog( message, RECV ); + } + + return true; +} + +void +Stadium::udp_recv_from_online_coach() +{ + recv_from_clients( M_remote_online_coaches ); + + while ( 1 ) + { + char message[MaxMesg]; + std::memset( &message, 0, sizeof ( char ) * MaxMesg ); + + rcss::net::Addr cli_addr; + + int len = M_online_coach_socket.recv( message, MaxMesg, cli_addr ); + + if ( len > 0 ) + { + bool found = false; + for ( OnlineCoachCont::iterator i = M_remote_online_coaches.begin(); + i != M_remote_online_coaches.end(); + ++i ) + { + if ( (*i)->getDest() == cli_addr ) + { + (*i)->undedicatedRecv( message, len ); + found = true; + break; + } + } + if ( ! found ) + { + // a new online coach + + /* chop newline */ + if ( message[len - 1] == '\n' ) + { + --len; + } + message[len] = '\0'; + + parseOnlineCoachInit( message, cli_addr ); + } + } + else if ( errno != EWOULDBLOCK ) + { + std::cerr << __FILE__ << ": " << __LINE__ + << ": Error recv'ing from socket: " + << strerror( errno ) << std::endl; + } + + if ( len < 0 ) + { + break; + } + } +} + +void +Stadium::parseOnlineCoachInit( const char * message, + const rcss::net::Addr & addr ) +{ + if ( std::strncmp( message, "(init", std::strlen( "(init" ) ) != 0 ) + { + sendToOnlineCoach( "(error illegal_command_form)", + addr ); + return; + } + + // (init [ ][ (version )]) + + const char * msg = message; + + const double default_olcoach_version = 5.0; + + char teamname[16]; + char coachname[128]; + double version = default_olcoach_version; + + std::memset( teamname, 0, 16 ); + std::memset( coachname, 0, 128 ); + + int n_read = 0; + + // read team name + if ( std::sscanf( msg, " ( init %15[+-_a-zA-Z0-9] %n ", + teamname, &n_read ) != 1 + || n_read == 0 ) + { + sendToOnlineCoach( "(error illegal_command_form)", addr ); + return; + } + msg += n_read; + + while ( *msg != '\0' && std::isspace( *msg ) ) ++msg; + + // read coach name + if ( *msg != '(' ) + { + if ( std::sscanf( msg, " %127[+-_a-zA-Z0-9] %n ", + coachname, &n_read ) != 1 ) + { + sendToOnlineCoach( "(error illegal_command_form)", addr ); + return; + } + msg += n_read; + + if ( *msg != '(' && *msg != ')' && ! std::isspace( *msg ) ) + { + sendToOnlineCoach( "(error illegal_coachname_or_too_long_coachname)", addr ); + return; + } + } + + while ( *msg != '\0' && *msg != '(' ) ++msg; + + // read protocol version + if ( ! std::strncmp( "(version", msg, std::strlen( "(version" ) ) ) + { + if ( std::sscanf( msg, " ( version %lf ) %n ", + &version, &n_read ) != 1 + || n_read == 0 ) + { + sendToOnlineCoach( "(error illegal_command_form)", addr ); + return; + } + msg += n_read; + + if ( *msg != '(' && *msg != ')' && ! std::isspace( *msg ) ) + { + sendToOnlineCoach( "(error illegal_client_version)", addr ); + return; + } + + if ( version < default_olcoach_version ) + { + sendToOnlineCoach( "(error illegal_client_version)", addr ); + return; + } + } + + // + // assign new online coach + // + + OnlineCoach * olc = initOnlineCoach( teamname, coachname, version, addr ); + if ( olc ) + { + std::cout << "A new (v" << static_cast< int >( version ) << ") " + << "online coach (" << teamname << ") connected." + << std::endl;; + + M_logger.writeOnlineCoachLog( *olc, message, RECV ); + } +} + +void +Stadium::sendToPlayer( const char * msg, + const rcss::net::Addr & cli_addr ) +{ + if ( M_player_socket.send( msg, std::strlen( msg ) + 1, cli_addr ) == -1 ) + { + std::cerr << __FILE__ ": " << __LINE__ + << ": Error sending to socket: " + << strerror( errno ) << std::endl; + } +} + +void +Stadium::sendToCoach( const char * msg, + const rcss::net::Addr & cli_addr ) +{ + if ( M_offline_coach_socket.send( msg, std::strlen( msg ) + 1, cli_addr ) == -1 ) + { + std::cerr << __FILE__ ": " << __LINE__ + << ": Error sending to socket: " + << strerror( errno ) << std::endl; + } +} + +void +Stadium::sendToOnlineCoach( const char * msg, + const rcss::net::Addr & cli_addr ) +{ + if ( M_online_coach_socket.send( msg, std::strlen( msg ) + 1, cli_addr ) == -1 ) + { + std::cerr << __FILE__ ": " << __LINE__ + << ": Error sending to socket: " + << strerror( errno ) << std::endl; + } +} + void Stadium::doQuit() { diff -Nru rcssserver-15.1.0/src/stadium.h rcssserver-15.2.2/src/stadium.h --- rcssserver-15.1.0/src/stadium.h 2011-08-17 09:32:20.000000000 +0000 +++ rcssserver-15.2.2/src/stadium.h 2013-05-27 04:09:51.000000000 +0000 @@ -415,11 +415,14 @@ public: void substitute( const Player * player, const int player_type_id ); - void broadcastSubstitution( const int side, const int unum, const int player_type ); + bool changePlayerToGoalie( const Player * player ); + void broadcastChangePlayerToGoalie( const Player * player ); + + void setPlayerState( const Side side, const int unum, const int state ); @@ -428,6 +431,7 @@ const PVector & accel ); void failedKickTaken( const Player & kicker ); void tackleTaken( const Player & tackler, + const PVector & accel, const bool foul ); void failedTackleTaken( const Player & tackler, const bool foul ); diff -Nru rcssserver-15.1.0/src/team.cpp rcssserver-15.2.2/src/team.cpp --- rcssserver-15.1.0/src/team.cpp 2011-08-17 09:32:20.000000000 +0000 +++ rcssserver-15.2.2/src/team.cpp 2013-05-27 04:09:51.000000000 +0000 @@ -342,6 +342,44 @@ } +bool +Team::changePlayerToGoalie( const Player * player ) +{ + if ( ! player ) + { + return false; + } + + Player * candidate = static_cast< Player * >( 0 ); + for ( int i = 0; i < this->size(); ++i ) + { + if ( M_players[i]->isEnabled() ) + { + if ( M_players[i]->isGoalie() ) + { + return false; + } + + if ( player == M_players[i] ) + { + candidate = M_players[i]; + } + } + } + + if ( ! candidate ) + { + std::cerr << __FILE__ << ":" << __LINE__ + << " Warning: no such player." << std::endl; + return false; + } + + candidate->changeToGoalie(); + + return true; +} + + void Team::addTeamGraphic( const unsigned int x, const unsigned int y, diff -Nru rcssserver-15.1.0/src/team.h rcssserver-15.2.2/src/team.h --- rcssserver-15.1.0/src/team.h 2011-08-17 09:32:20.000000000 +0000 +++ rcssserver-15.2.2/src/team.h 2013-05-27 04:09:51.000000000 +0000 @@ -194,14 +194,12 @@ return M_subs_count; } - const - std::map< int, int > & ptypeCount() const + const std::map< int, int > & ptypeCount() const { return M_ptype_count; } - const - std::map< int, int > & ptypeUsedCount() const + const std::map< int, int > & ptypeUsedCount() const { return M_ptype_used_count; } @@ -213,6 +211,8 @@ void substitute( const Player * player, const int player_type ); + bool changePlayerToGoalie( const Player * player ); + OnlineCoach * olcoach() { return M_olcoach; diff -Nru rcssserver-15.1.0/src/version.h rcssserver-15.2.2/src/version.h --- rcssserver-15.1.0/src/version.h 2012-05-23 06:06:44.000000000 +0000 +++ rcssserver-15.2.2/src/version.h 2013-05-27 04:09:51.000000000 +0000 @@ -33,4 +33,4 @@ char Copyright[] = "Copyright (C) 1995, 1996, 1997, 1998, 1999 Electrotechnical Laboratory.\n\ -2000 - 2012 RoboCup Soccer Simulator Maintenance Group.\n"; +2000 - RoboCup Soccer Simulator Maintenance Group.\n"; diff -Nru rcssserver-15.1.0/src/visualsendercoach.cpp rcssserver-15.2.2/src/visualsendercoach.cpp --- rcssserver-15.1.0/src/visualsendercoach.cpp 2011-08-17 09:32:20.000000000 +0000 +++ rcssserver-15.2.2/src/visualsendercoach.cpp 2013-05-27 04:09:51.000000000 +0000 @@ -359,6 +359,7 @@ RegHolder vc13 = VisualSenderCoach::factory().autoReg( &create< VisualSenderCoachV13 >, 13 ); RegHolder vc14 = VisualSenderCoach::factory().autoReg( &create< VisualSenderCoachV13 >, 14 ); RegHolder vc15 = VisualSenderCoach::factory().autoReg( &create< VisualSenderCoachV13 >, 15 ); +//RegHolder vc16 = VisualSenderCoach::factory().autoReg( &create< VisualSenderCoachV13 >, 16 ); } } diff -Nru rcssserver-15.1.0/src/visualsenderplayer.cpp rcssserver-15.2.2/src/visualsenderplayer.cpp --- rcssserver-15.1.0/src/visualsenderplayer.cpp 2011-08-17 09:32:20.000000000 +0000 +++ rcssserver-15.2.2/src/visualsenderplayer.cpp 2013-05-27 04:09:51.000000000 +0000 @@ -1077,6 +1077,7 @@ RegHolder vp13 = VisualSenderPlayer::factory().autoReg( &create< VisualSenderPlayerV13 >, 13 ); RegHolder vp14 = VisualSenderPlayer::factory().autoReg( &create< VisualSenderPlayerV13 >, 14 ); RegHolder vp15 = VisualSenderPlayer::factory().autoReg( &create< VisualSenderPlayerV13 >, 15 ); +//RegHolder vp16 = VisualSenderPlayer::factory().autoReg( &create< VisualSenderPlayerV13 >, 16 ); } }