| 1 | #include "netgame_ode_pong.h" |
|---|
| 2 | #include "player.h" |
|---|
| 3 | |
|---|
| 4 | using namespace mmp; |
|---|
| 5 | |
|---|
| 6 | |
|---|
| 7 | void NetGameODEPong::srv_con_start(NetCon::pointer con) { |
|---|
| 8 | NetGame::srv_con_start(con); |
|---|
| 9 | |
|---|
| 10 | |
|---|
| 11 | boost::shared_ptr<Player> newplayer=srv_ent_create<Player>(); |
|---|
| 12 | uint16_t newplayerid=newplayer->get_entid(); |
|---|
| 13 | NetMsg::pointer msgnewplayer=msg_ent_new_create(newplayerid); |
|---|
| 14 | |
|---|
| 15 | |
|---|
| 16 | uint16_t newteamid=team2players.begin()->first; |
|---|
| 17 | for (std::map<uint16_t, std::set<uint16_t> >::iterator it=team2players.begin(); it!=team2players.end(); it++) |
|---|
| 18 | if (it->second.size() < team2players[newteamid].size()) |
|---|
| 19 | newteamid=it->first; |
|---|
| 20 | team2players[newteamid].insert(newplayerid); |
|---|
| 21 | player2team[newplayerid]=newteamid; |
|---|
| 22 | |
|---|
| 23 | boost::shared_ptr<ODEBox> playerpad=srv_ent_create<ODEBox>(); |
|---|
| 24 | playerpad->geom.setLengths(0.05,0.5,0.05); |
|---|
| 25 | double ang=M_PI*(1.0+2.0*newteamid/srv_teamid_cur); |
|---|
| 26 | playerpad->setPosition(cos(ang)*1.05, sin(ang)*1.05, 0.0); |
|---|
| 27 | uint16_t newpadid=playerpad->get_entid(); |
|---|
| 28 | player2pad[newplayerid]=newpadid; |
|---|
| 29 | NetMsg::pointer msgnewpad=msg_ent_new_create(newpadid); |
|---|
| 30 | for (std::set<NetCon::pointer>::iterator it=srv_cons.begin(); it!=srv_cons.end(); it++) { |
|---|
| 31 | (*it)->write(msgnewplayer); |
|---|
| 32 | (*it)->write(msgnewpad); |
|---|
| 33 | } |
|---|
| 34 | |
|---|
| 35 | srv_con2player[con]=newplayerid; |
|---|
| 36 | |
|---|
| 37 | |
|---|
| 38 | |
|---|
| 39 | |
|---|
| 40 | { |
|---|
| 41 | NetMsg::pointer msgnewid=NetMsg::create(NetMsg::CmdGameCustom); |
|---|
| 42 | msgnewid->pack_begin(); |
|---|
| 43 | uint16_t customcmd=PlayerId; |
|---|
| 44 | msgnewid & customcmd & newplayerid & newteamid & newpadid; |
|---|
| 45 | msgnewid->pack_finish(); |
|---|
| 46 | con->write(msgnewid); |
|---|
| 47 | } |
|---|
| 48 | |
|---|
| 49 | |
|---|
| 50 | { |
|---|
| 51 | NetMsg::pointer msgnewplayer=NetMsg::create(NetMsg::CmdGameCustom); |
|---|
| 52 | msgnewplayer->pack_begin(); |
|---|
| 53 | uint16_t customcmd=PlayerEnter; |
|---|
| 54 | msgnewplayer & customcmd & newplayerid & newteamid & newpadid; |
|---|
| 55 | msgnewplayer->pack_finish(); |
|---|
| 56 | for (std::set<NetCon::pointer>::iterator it=srv_cons.begin(); it!=srv_cons.end(); it++) |
|---|
| 57 | if (*it != con) |
|---|
| 58 | (*it)->write(msgnewplayer); |
|---|
| 59 | } |
|---|
| 60 | |
|---|
| 61 | |
|---|
| 62 | for (std::map<uint16_t, uint16_t>::iterator it=player2team.begin(); it!=player2team.end(); it++) { |
|---|
| 63 | if (it->first != newplayerid) { |
|---|
| 64 | NetMsg::pointer msgplayer=NetMsg::create(NetMsg::CmdGameCustom); |
|---|
| 65 | msgplayer->pack_begin(); |
|---|
| 66 | uint16_t customcmd=PlayerEnter; |
|---|
| 67 | msgplayer->pack(customcmd); |
|---|
| 68 | msgplayer->pack(it->first); |
|---|
| 69 | msgplayer->pack(it->second); |
|---|
| 70 | msgplayer->pack(player2pad[it->first]); |
|---|
| 71 | msgplayer->pack_finish(); |
|---|
| 72 | con->write(msgplayer); |
|---|
| 73 | } |
|---|
| 74 | } |
|---|
| 75 | |
|---|
| 76 | LOGDBG("New player " << newplayerid << " entered game in team " << newteamid << " with paddle " << newpadid); |
|---|
| 77 | print_playerlist(); |
|---|
| 78 | }; |
|---|
| 79 | |
|---|
| 80 | void NetGameODEPong::srv_con_end(NetCon::pointer con) { |
|---|
| 81 | uint16_t playerid=srv_con2player[con]; |
|---|
| 82 | uint16_t teamid=player2team[playerid]; |
|---|
| 83 | uint16_t padid=player2pad[playerid]; |
|---|
| 84 | team2players[teamid].erase(playerid); |
|---|
| 85 | player2team.erase(playerid); |
|---|
| 86 | player2pad.erase(playerid); |
|---|
| 87 | srv_con2player.erase(con); |
|---|
| 88 | |
|---|
| 89 | LOGDBG("Player " << playerid << " left game in team " << teamid); |
|---|
| 90 | |
|---|
| 91 | |
|---|
| 92 | { |
|---|
| 93 | NetMsg::pointer msgleave=NetMsg::create(NetMsg::CmdGameCustom); |
|---|
| 94 | msgleave->pack_begin(); |
|---|
| 95 | uint16_t customcmd=PlayerLeave; |
|---|
| 96 | msgleave->pack(customcmd); |
|---|
| 97 | msgleave->pack(playerid); |
|---|
| 98 | msgleave->pack(teamid); |
|---|
| 99 | msgleave->pack(padid); |
|---|
| 100 | msgleave->pack_finish(); |
|---|
| 101 | |
|---|
| 102 | for (std::set<NetCon::pointer>::iterator it=srv_cons.begin(); it!=srv_cons.end(); it++) |
|---|
| 103 | if (con!=*it) |
|---|
| 104 | (*it)->write( msgleave ); |
|---|
| 105 | } |
|---|
| 106 | |
|---|
| 107 | |
|---|
| 108 | |
|---|
| 109 | { |
|---|
| 110 | NetMsg::pointer msgplayer=msg_ent_destroy_create(playerid); |
|---|
| 111 | NetMsg::pointer msgpad=msg_ent_destroy_create(padid); |
|---|
| 112 | for (std::set<NetCon::pointer>::iterator it=srv_cons.begin(); it!=srv_cons.end(); it++) |
|---|
| 113 | if (con!=*it) { |
|---|
| 114 | (*it)->write(msgplayer); |
|---|
| 115 | (*it)->write(msgpad); |
|---|
| 116 | } |
|---|
| 117 | } |
|---|
| 118 | ents.erase(playerid); |
|---|
| 119 | ents.erase(padid); |
|---|
| 120 | print_playerlist(); |
|---|
| 121 | }; |
|---|
| 122 | |
|---|
| 123 | |
|---|
| 124 | bool NetGameODEPong::srv_msg_process(NetCon::pointer con, NetMsg::pointer msg) { |
|---|
| 125 | |
|---|
| 126 | switch (msg->get_cmd()) { |
|---|
| 127 | case NetMsg::CmdGameStart: |
|---|
| 128 | case NetMsg::CmdGameStop: |
|---|
| 129 | LOGWARN("client " << con->socket().remote_endpoint() << " tries to start/stop the game."); |
|---|
| 130 | return false; |
|---|
| 131 | break; |
|---|
| 132 | |
|---|
| 133 | case NetMsg::CmdEntNew: |
|---|
| 134 | case NetMsg::CmdEntDestroy: |
|---|
| 135 | LOGWARN("client " << con->socket().remote_endpoint() << " tries to create/destroy a NetEnt."); |
|---|
| 136 | return false; |
|---|
| 137 | break; |
|---|
| 138 | |
|---|
| 139 | |
|---|
| 140 | case NetMsg::CmdEntUpdate: |
|---|
| 141 | { |
|---|
| 142 | msg->unpack_begin(); |
|---|
| 143 | uint16_t entid, classid; |
|---|
| 144 | msg->unpack(entid); |
|---|
| 145 | msg->unpack(classid); |
|---|
| 146 | |
|---|
| 147 | |
|---|
| 148 | NetEnt::pointer ent=ents[entid]; |
|---|
| 149 | if (!ent) { |
|---|
| 150 | LOGWARN("client " << con->socket().remote_endpoint() << " tries to modify a non-existent NetEnt."); |
|---|
| 151 | msg->unpack_finish(); |
|---|
| 152 | return false; |
|---|
| 153 | } |
|---|
| 154 | |
|---|
| 155 | |
|---|
| 156 | if (ent->get_classid()!=classid) { |
|---|
| 157 | LOGWARN("client " << con->socket().remote_endpoint() << " tries to modify a NetEnt with wrong classid."); |
|---|
| 158 | msg->unpack_finish(); |
|---|
| 159 | return false; |
|---|
| 160 | } |
|---|
| 161 | |
|---|
| 162 | |
|---|
| 163 | bool permit=false; |
|---|
| 164 | uint16_t playerid=srv_con2player[con]; |
|---|
| 165 | if (entid==playerid) |
|---|
| 166 | permit=true; |
|---|
| 167 | if (entid==player2pad[playerid]) |
|---|
| 168 | permit=true; |
|---|
| 169 | |
|---|
| 170 | if (permit) { |
|---|
| 171 | LOGDBG("permission is granted to client " << con->socket().remote_endpoint() << " for updating entid " << entid); |
|---|
| 172 | ent->update(msg); |
|---|
| 173 | |
|---|
| 174 | |
|---|
| 175 | msg->unpack_finish(); |
|---|
| 176 | |
|---|
| 177 | NetMsg::pointer forwardmsg=msg_ent_update_create(entid); |
|---|
| 178 | |
|---|
| 179 | for (std::set<NetCon::pointer>::iterator it=srv_cons.begin(); it!=srv_cons.end(); it++) |
|---|
| 180 | if (con!=*it) |
|---|
| 181 | con->write(forwardmsg); |
|---|
| 182 | } else { |
|---|
| 183 | LOGWARN("client " << con->socket().remote_endpoint() << " tries to modify a NetEnt it is not allowed to."); |
|---|
| 184 | msg->unpack_finish(); |
|---|
| 185 | return false; |
|---|
| 186 | } |
|---|
| 187 | } |
|---|
| 188 | break; |
|---|
| 189 | |
|---|
| 190 | |
|---|
| 191 | case NetMsg::CmdGameCustom: |
|---|
| 192 | { |
|---|
| 193 | LOGWARN("CmdGameCustom not yet used for client => server communication"); |
|---|
| 194 | return true; |
|---|
| 195 | |
|---|
| 196 | |
|---|
| 197 | } |
|---|
| 198 | break; |
|---|
| 199 | }; |
|---|
| 200 | |
|---|
| 201 | return true; |
|---|
| 202 | }; |
|---|
| 203 | |
|---|
| 204 | NetEnt::pointer NetGameODEPong::cln_ent_update(NetMsg::pointer msg) { |
|---|
| 205 | NetEnt::pointer ent=NetGameODE::cln_ent_update(msg); |
|---|
| 206 | if (ent->get_classid()==NetEnt::Player) |
|---|
| 207 | print_playerlist(); |
|---|
| 208 | return ent; |
|---|
| 209 | }; |
|---|
| 210 | |
|---|
| 211 | |
|---|
| 212 | void NetGameODEPong::cln_msg_custom(NetMsg::pointer msg) { |
|---|
| 213 | if (msg->get_cmd()!=NetMsg::CmdGameCustom) |
|---|
| 214 | throw std::runtime_error("NetMsg cmd is not CmdGameCustom!"); |
|---|
| 215 | |
|---|
| 216 | msg->unpack_begin(); |
|---|
| 217 | uint16_t cmd; |
|---|
| 218 | msg->unpack(cmd); |
|---|
| 219 | switch(cmd) { |
|---|
| 220 | case PlayerEnter: |
|---|
| 221 | { |
|---|
| 222 | uint16_t playerid, teamid, padid; |
|---|
| 223 | msg & playerid & teamid & padid; |
|---|
| 224 | team2players[teamid].insert(playerid); |
|---|
| 225 | player2team[playerid]=teamid; |
|---|
| 226 | player2pad[playerid]=padid; |
|---|
| 227 | LOGDBG("New player " << playerid << " entered game in team " << teamid << " with paddle " << padid); |
|---|
| 228 | print_playerlist(); |
|---|
| 229 | } |
|---|
| 230 | break; |
|---|
| 231 | |
|---|
| 232 | case PlayerId: |
|---|
| 233 | { |
|---|
| 234 | uint16_t playerid, teamid, padid; |
|---|
| 235 | msg & playerid & teamid & padid; |
|---|
| 236 | myplayerid=playerid; |
|---|
| 237 | myteamid=teamid; |
|---|
| 238 | mypadid=padid; |
|---|
| 239 | team2players[teamid].insert(playerid); |
|---|
| 240 | player2team[playerid]=teamid; |
|---|
| 241 | player2pad[playerid]=padid; |
|---|
| 242 | LOGDBG("I am player " << playerid << " in team " << teamid << " with paddle " << padid); |
|---|
| 243 | print_playerlist(); |
|---|
| 244 | } |
|---|
| 245 | break; |
|---|
| 246 | |
|---|
| 247 | case PlayerLeave: |
|---|
| 248 | { |
|---|
| 249 | uint16_t playerid, teamid, padid; |
|---|
| 250 | msg & playerid & teamid & padid; |
|---|
| 251 | team2players[teamid].erase(playerid); |
|---|
| 252 | player2team.erase(playerid); |
|---|
| 253 | player2pad.erase(playerid); |
|---|
| 254 | LOGDBG("Player " << playerid << " left game in team " << teamid << " with paddle " << padid); |
|---|
| 255 | print_playerlist(); |
|---|
| 256 | } |
|---|
| 257 | break; |
|---|
| 258 | default: |
|---|
| 259 | LOGWARN("CmdGameCustom with cmd=="<<cmd<<" not understood"); |
|---|
| 260 | break; |
|---|
| 261 | } |
|---|
| 262 | |
|---|
| 263 | msg->unpack_finish(); |
|---|
| 264 | |
|---|
| 265 | }; |
|---|
| 266 | |
|---|
| 267 | void NetGameODEPong::cln_set_paddlepos(float pos) { |
|---|
| 268 | if (pos>1.0) |
|---|
| 269 | pos=1.0; |
|---|
| 270 | if (pos<0.0) |
|---|
| 271 | pos=0.0; |
|---|
| 272 | if (pos!=mypadpos) { |
|---|
| 273 | mypadpos=pos; |
|---|
| 274 | boost::shared_ptr<ODEBox> pad=get_ent<ODEBox>(mypadid); |
|---|
| 275 | double ang=M_PI*(1.0+2.0*myteamid/srv_teamid_cur); |
|---|
| 276 | pad->setPosition(cos(ang)*1.05, -1.0 + 2.0 * mypadpos, 0.0); |
|---|
| 277 | NetMsg::pointer msg=NetMsg::create(NetMsg::CmdGameCustom); |
|---|
| 278 | msg->pack_begin(); |
|---|
| 279 | uint16_t customcmd=PlayerPadPos; |
|---|
| 280 | msg->pack(customcmd); |
|---|
| 281 | msg->pack(mypadpos); |
|---|
| 282 | msg->pack_finish(); |
|---|
| 283 | cln_con->write(msg); |
|---|
| 284 | } |
|---|
| 285 | }; |
|---|
| 286 | |
|---|
| 287 | void NetGameODEPong::print_playerlist() { |
|---|
| 288 | for (std::map<uint16_t, std::set<uint16_t> >::iterator itteam=team2players.begin(); itteam!=team2players.end(); itteam++) { |
|---|
| 289 | LOG("Team " << itteam->first); |
|---|
| 290 | if (itteam->second.size()) { |
|---|
| 291 | for (std::set<uint16_t>::iterator itplayer=itteam->second.begin(); itplayer!=itteam->second.end(); itplayer++) { |
|---|
| 292 | boost::shared_ptr<Player> player=boost::dynamic_pointer_cast<Player>(ents[*itplayer]); |
|---|
| 293 | LOG(" * " << player->name); |
|---|
| 294 | } |
|---|
| 295 | } else |
|---|
| 296 | LOG(" * (empty)"); |
|---|
| 297 | } |
|---|
| 298 | }; |
|---|