root / branches / cpp-ode / src / libmmpong / netgame_ode_pong.cc @ 539

Revision 539, 8.7 kB (checked in by gaul@…, 7 months ago)
  • ignore client updates
Line 
1#include "netgame_ode_pong.h"
2#include "player.h"
3
4using namespace mmp;
5
6
7void NetGameODEPong::srv_con_start(NetCon::pointer con) {
8        NetGame::srv_con_start(con); //send all ents to client
9       
10        //now add new object for the new client and send it to every client (including the new one)
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        //find suitable team
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        //add a player
35        srv_con2player[con]=newplayerid;
36
37
38
39        //send new client its player, team and pad id
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        //send new player to all clients
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        //send all players to new client
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
80void 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        //remove player in clients
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        //destroy ent in clients
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
124bool NetGameODEPong::srv_msg_process(NetCon::pointer con, NetMsg::pointer msg) {
125        //THE decision
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                //ATTENTION: check carefully
140                case NetMsg::CmdEntUpdate:
141                        {
142                                msg->unpack_begin();
143                                uint16_t entid, classid;
144                                msg->unpack(entid);
145                                msg->unpack(classid);
146
147                                //does ent with entid exist?
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                                //does ent has the correct classid?
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                                //now check permission for entid
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                                        //TODO: security & sanity checks here
174                                        //postprocessing could take place here, too.
175                                        msg->unpack_finish();
176                                       
177                                        NetMsg::pointer forwardmsg=msg_ent_update_create(entid);
178                                        //send out msg to all other clients
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                //ATTENTION: check carefully
191                case NetMsg::CmdGameCustom:
192                        {
193                                LOGWARN("CmdGameCustom not yet used for client => server communication");
194                                return true;
195                                //wanna kick it?
196                                //return false;
197                        }
198                        break;
199        };
200
201        return true;
202};
203
204NetEnt::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
212void 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
267void 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
287void 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};
Note: See TracBrowser for help on using the browser.