Fawkes API Fawkes Development Version

spl.cpp

00001 
00002 /***************************************************************************
00003  *  spl.cpp - Fawkes SPL refbox repeater
00004  *
00005  *  Created: Tue Jul 08 13:50:06 2008
00006  *  Copyright  2008  Tim Niemueller [www.niemueller.de]
00007  *
00008  ****************************************************************************/
00009 
00010 /*  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version.
00014  *
00015  *  This program is distributed in the hope that it will be useful,
00016  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  *  GNU Library General Public License for more details.
00019  *
00020  *  Read the full text in the LICENSE.GPL file in the doc directory.
00021  */
00022 
00023 #include "spl.h"
00024 #include <netcomm/socket/datagram.h>
00025 
00026 #include <cstring>
00027 #include <cstdio>
00028 #include <unistd.h>
00029 
00030 using namespace fawkes;
00031 
00032 static const uint32_t  SPL_STRUCT_VERSION = 6;
00033 
00034 static const uint8_t   SPL_STATE_INITIAL  = 0;
00035 static const uint8_t   SPL_STATE_READY    = 1;
00036 static const uint8_t   SPL_STATE_SET      = 2;
00037 static const uint8_t   SPL_STATE_PLAYING  = 3;
00038 static const uint8_t   SPL_STATE_FINISHED = 4;
00039 
00040 static const uint8_t   SPL_STATE2_NORMAL       = 0;
00041 static const uint8_t   SPL_STATE2_PENALTYSHOOT = 1;
00042 
00043 static const uint8_t   SPL_PENALTY_NONE              =  0;
00044 static const uint8_t   SPL_PENALTY_BALL_HOLDING      =  1;
00045 static const uint8_t   SPL_PENALTY_GOALIE_PUSHING    =  2;
00046 static const uint8_t   SPL_PENALTY_PLAYER_PUSHING    =  3;
00047 static const uint8_t   SPL_PENALTY_ILLEGAL_DEFENDER  =  4;
00048 static const uint8_t   SPL_PENALTY_ILLEGAL_DEFENSE   =  5;
00049 static const uint8_t   SPL_PENALTY_OBSTRUCTION       =  6;
00050 static const uint8_t   SPL_PENALTY_REQ_FOR_PICKUP    =  7;
00051 static const uint8_t   SPL_PENALTY_LEAVING           =  8;
00052 static const uint8_t   SPL_PENALTY_DAMAGE            =  9;
00053 static const uint8_t   SPL_PENALTY_MANUAL            = 10;
00054 
00055 // team numbers
00056 static const uint8_t   SPL_TEAM_BLUE                 =  0;
00057 static const uint8_t   SPL_TEAM_RED                  =  1;
00058 
00059 static const char    SPL_GAMECONTROL_HEADER[GCHS]  = {'R', 'G', 'm', 'e'};
00060 
00061 
00062 /** @class SplRefBoxRepeater <tools/refboxrep/spl.h>
00063  * SPL league refbox repeater.
00064  * This class will listen to SPL refbox commands and derive matching
00065  * game states from the communication stream and send this via the world info.
00066  * @author Tim Niemueller
00067  */
00068 
00069 /** Constructor.
00070  * @param rss refbox state sender
00071  * @param broadcast_ip Broadcast IP
00072  * @param broadcast_port Broadcast port
00073  * @param our_team our initial team
00074  * @param our_goal our initial goal
00075  */
00076 SplRefBoxRepeater::SplRefBoxRepeater(RefBoxStateSender &rss,
00077                                      const char *broadcast_ip,
00078                                      unsigned short int broadcast_port,
00079                                      fawkes::worldinfo_gamestate_team_t our_team,
00080                                      fawkes::worldinfo_gamestate_goalcolor_t our_goal)
00081   : __rss(rss)
00082 {
00083   __quit = false;
00084   __our_team = our_team;
00085   __our_goal = our_goal;
00086   __s = new DatagramSocket();
00087   __s->bind(broadcast_port);
00088 
00089   for (unsigned int i = 0; i < MAX_NUM_PLAYERS; ++i) {
00090     __penalties[i] = SPL_PENALTY_NONE;
00091   }
00092 }
00093 
00094 
00095 /** Destructor. */
00096 SplRefBoxRepeater::~SplRefBoxRepeater()
00097 {
00098   __s->close();
00099   delete __s;
00100 }
00101 
00102 
00103 /** Process received struct. */
00104 void
00105 SplRefBoxRepeater::process_struct(spl_gamecontrol_t *msg)
00106 {
00107   switch (msg->state) {
00108   case SPL_STATE_INITIAL:
00109     __rss.set_gamestate(GS_SPL_INITIAL, TEAM_BOTH);
00110     break;
00111   case SPL_STATE_READY:
00112     __rss.set_gamestate(GS_SPL_READY,
00113                         (msg->kick_off_team == SPL_TEAM_BLUE) ? TEAM_CYAN : TEAM_MAGENTA);
00114     break;
00115   case SPL_STATE_SET:
00116     __rss.set_gamestate(GS_SPL_SET,
00117                         (msg->kick_off_team == SPL_TEAM_BLUE) ? TEAM_CYAN : TEAM_MAGENTA);
00118     break;
00119   case SPL_STATE_PLAYING:
00120     __rss.set_gamestate(GS_SPL_PLAY,
00121                         (msg->kick_off_team == SPL_TEAM_BLUE) ? TEAM_CYAN : TEAM_MAGENTA);
00122     break;
00123   case SPL_STATE_FINISHED:
00124     __rss.set_gamestate(GS_SPL_FINISHED, TEAM_BOTH);
00125     break;
00126   default:
00127     __rss.set_gamestate(GS_FROZEN, TEAM_BOTH); break;
00128   }
00129 
00130   __rss.set_half( (msg->first_half == 1) ? HALF_FIRST : HALF_SECOND);
00131 
00132   if (msg->teams[0].team_color == SPL_TEAM_BLUE) {
00133     __rss.set_score( msg->teams[0].score, msg->teams[1].score);
00134   } else {
00135     __rss.set_score( msg->teams[1].score, msg->teams[0].score);
00136   }
00137 
00138   int oti = (msg->teams[0].team_color == __our_team) ? 0 : 1;
00139   for (unsigned int i = 0; i < MAX_NUM_PLAYERS; ++i) {
00140     if ( (__penalties[i] != msg->teams[oti].players[i].penalty) ||
00141          (msg->teams[oti].players[i].penalty != SPL_PENALTY_NONE) ) {
00142       __rss.add_penalty(i, msg->teams[oti].players[i].penalty,
00143                         msg->teams[oti].players[i].secs_till_unpenalized);
00144     }
00145   }
00146 
00147   __rss.send();
00148 }
00149 
00150 
00151 /** Run.
00152  * Reads messages from the network, processes them and calls the refbox state sender.
00153  */
00154 void
00155 SplRefBoxRepeater::run()
00156 {
00157   spl_gamecontrol_t ctrlmsg;
00158   while ( ! __quit ) {
00159     size_t bytes_read = __s->recv((void *)&ctrlmsg, sizeof(ctrlmsg));
00160     if ( bytes_read == sizeof(ctrlmsg) ) {
00161       if ( (strncmp(ctrlmsg.header, SPL_GAMECONTROL_HEADER, GCHS) == 0) &&
00162            (ctrlmsg.version == SPL_STRUCT_VERSION) ) {
00163         process_struct(&ctrlmsg);
00164       } else {
00165         printf("Received illegal package\n");
00166       }
00167     }
00168   }
00169 }
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends