spl.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "spl.h"
00025 #include "state_handler.h"
00026 #include <core/exception.h>
00027 #include <netcomm/socket/datagram.h>
00028 #include <utils/logging/logger.h>
00029
00030 #include <cstring>
00031 #include <cstdio>
00032 #include <unistd.h>
00033 #include <cerrno>
00034
00035 #ifdef errno
00036 # undef errno
00037 #endif
00038 using namespace fawkes;
00039
00040 static const uint32_t SPL_STRUCT_VERSION = 6;
00041
00042 static const uint8_t SPL_STATE_INITIAL = 0;
00043 static const uint8_t SPL_STATE_READY = 1;
00044 static const uint8_t SPL_STATE_SET = 2;
00045 static const uint8_t SPL_STATE_PLAYING = 3;
00046 static const uint8_t SPL_STATE_FINISHED = 4;
00047
00048 static const uint8_t SPL_STATE2_NORMAL = 0;
00049 static const uint8_t SPL_STATE2_PENALTYSHOOT = 1;
00050
00051 static const uint8_t SPL_PENALTY_NONE = 0;
00052 static const uint8_t SPL_PENALTY_BALL_HOLDING = 1;
00053 static const uint8_t SPL_PENALTY_GOALIE_PUSHING = 2;
00054 static const uint8_t SPL_PENALTY_PLAYER_PUSHING = 3;
00055 static const uint8_t SPL_PENALTY_ILLEGAL_DEFENDER = 4;
00056 static const uint8_t SPL_PENALTY_ILLEGAL_DEFENSE = 5;
00057 static const uint8_t SPL_PENALTY_OBSTRUCTION = 6;
00058 static const uint8_t SPL_PENALTY_REQ_FOR_PICKUP = 7;
00059 static const uint8_t SPL_PENALTY_LEAVING = 8;
00060 static const uint8_t SPL_PENALTY_DAMAGE = 9;
00061 static const uint8_t SPL_PENALTY_MANUAL = 10;
00062
00063
00064 static const uint8_t SPL_TEAM_BLUE = 0;
00065 static const uint8_t SPL_TEAM_RED = 1;
00066
00067 static const char SPL_GAMECONTROL_HEADER[GCHS] = {'R', 'G', 'm', 'e'};
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 SplRefBoxProcessor::SplRefBoxProcessor(fawkes::Logger *logger,
00084 unsigned short int broadcast_port,
00085 unsigned int team_number,
00086 unsigned int player_number)
00087 {
00088 __player_number = player_number;
00089 __team_number = team_number;
00090 __logger = logger;
00091 __quit = false;
00092 __s = new DatagramSocket(0.0000000001);
00093 __s->bind(broadcast_port);
00094
00095 __penalty = SPL_PENALTY_NONE;
00096 }
00097
00098
00099
00100 SplRefBoxProcessor::~SplRefBoxProcessor()
00101 {
00102 __s->close();
00103 delete __s;
00104 }
00105
00106
00107
00108 void
00109 SplRefBoxProcessor::process_struct(spl_gamecontrol_t *msg)
00110 {
00111 fawkes::worldinfo_gamestate_team_t our_team;
00112
00113
00114 int team_index;
00115 if (msg->teams[0].team_number == __team_number) team_index = 0;
00116 else if (msg->teams[1].team_number == __team_number) team_index = 1;
00117 else return;
00118
00119 switch (msg->teams[team_index].team_color) {
00120 case SPL_TEAM_BLUE:
00121 our_team = TEAM_CYAN;
00122 break;
00123 case SPL_TEAM_RED:
00124 our_team = TEAM_MAGENTA;
00125 break;
00126 default:
00127 printf("Ignoring faulty packet\n");
00128 return;
00129 }
00130
00131 _rsh->set_score(msg->teams[team_index].score, msg->teams[(team_index == 1 ? 0 : 1)].score);
00132 _rsh->set_team_goal(our_team, (our_team == TEAM_CYAN ? GOAL_BLUE : GOAL_YELLOW));
00133
00134 for (unsigned int pl_num = 0; pl_num < MAX_NUM_PLAYERS; ++pl_num)
00135 {
00136 if ((pl_num + 1) == __player_number)
00137 {
00138 if ((msg->teams[team_index].players[pl_num].penalty != __penalty) ||
00139 (msg->teams[team_index].players[pl_num].penalty != PENALTY_NONE))
00140 {
00141 __penalty = msg->teams[team_index].players[pl_num].penalty;
00142 _rsh->add_penalty(__penalty,
00143 msg->teams[team_index].players[pl_num].secs_till_unpenalized);
00144 }
00145 break;
00146 }
00147 }
00148
00149 switch (msg->state) {
00150 case SPL_STATE_INITIAL:
00151 _rsh->set_gamestate(GS_SPL_INITIAL, TEAM_BOTH);
00152 break;
00153 case SPL_STATE_READY:
00154 _rsh->set_gamestate(GS_SPL_READY, TEAM_BOTH);
00155 break;
00156 case SPL_STATE_SET:
00157 _rsh->set_gamestate(GS_SPL_SET, TEAM_BOTH);
00158 break;
00159 case SPL_STATE_PLAYING:
00160 _rsh->set_gamestate(GS_SPL_PLAY, TEAM_BOTH);
00161 break;
00162 case SPL_STATE_FINISHED:
00163 _rsh->set_gamestate(GS_SPL_FINISHED, TEAM_BOTH);
00164 break;
00165 default:
00166 _rsh->set_gamestate(GS_SPL_FINISHED, TEAM_BOTH);
00167 break;
00168 }
00169
00170 _rsh->set_half((msg->first_half == 1) ? HALF_FIRST : HALF_SECOND,
00171 msg->kick_off_team == team_index);
00172 }
00173
00174
00175 void
00176 SplRefBoxProcessor::refbox_process()
00177 {
00178 try {
00179 spl_gamecontrol_t ctrlmsg;
00180 size_t bytes_read = __s->recv((void *)&ctrlmsg, sizeof(ctrlmsg));
00181 if ( bytes_read == sizeof(ctrlmsg) ) {
00182 if ( (strncmp(ctrlmsg.header, SPL_GAMECONTROL_HEADER, GCHS) == 0) &&
00183 (ctrlmsg.version == SPL_STRUCT_VERSION) ) {
00184 process_struct(&ctrlmsg);
00185 }
00186 }
00187 } catch (fawkes::Exception &e) {
00188 if ( e.errno() != EAGAIN ) {
00189 __logger->log_warn("SplRefBoxProcessor", "Receiving failed, exception follows");
00190 __logger->log_warn("SplRefBoxProcessor", e);
00191 }
00192 }
00193 }
00194
00195 bool
00196 SplRefBoxProcessor::check_connection()
00197 {
00198 return true;
00199 }
00200
00201
00202
00203
00204
00205 void
00206 SplRefBoxProcessor::run()
00207 {
00208 spl_gamecontrol_t ctrlmsg;
00209 while ( ! __quit ) {
00210 size_t bytes_read = __s->recv((void *)&ctrlmsg, sizeof(ctrlmsg));
00211 if ( bytes_read == sizeof(ctrlmsg) ) {
00212 if ( (strncmp(ctrlmsg.header, SPL_GAMECONTROL_HEADER, GCHS) == 0) &&
00213 (ctrlmsg.version == SPL_STRUCT_VERSION) ) {
00214 process_struct(&ctrlmsg);
00215 _rsh->handle_refbox_state();
00216 } else {
00217 printf("Received illegal package\n");
00218 }
00219 }
00220 }
00221 }