1 #include "NetworkServer.hh" |
1 #include "NetworkServer.hh" |
2 #include "Protocol.hh" |
2 #include "Engine.hh" |
3 |
3 |
4 #include <iostream> |
4 #include <iostream> |
5 #include <cassert> |
5 #include <cassert> |
6 |
6 |
7 NetworkServer::NetworkServer (GameState &state, const std::string &listen_port) : |
7 NetworkServer::NetworkServer (GameState &state, const std::string &listen_port) : |
8 NetworkCore(state) { |
8 NetworkCore(state), pid_pool(0) { |
9 |
9 |
10 // connect slots |
10 // connect slots |
11 slots.connect(netsession.sig_computer_connected(), this, &NetworkServer::on_connect); |
11 slots.connect(netsession.sig_computer_connected(), this, &NetworkServer::on_connect); |
12 slots.connect(netsession.sig_computer_disconnected(), this, &NetworkServer::on_disconnect); |
12 slots.connect(netsession.sig_computer_disconnected(), this, &NetworkServer::on_disconnect); |
13 |
13 |
14 // and then we listen |
14 // and then we listen |
15 netsession.start_listen(listen_port); |
15 netsession.start_listen(listen_port); |
16 } |
16 } |
17 |
17 |
18 void NetworkServer::on_connect (CL_NetComputer &computer) { |
18 void NetworkServer::on_connect (CL_NetComputer &computer) { |
19 std::cout << "NetworkServer.on_connect: " << computer.get_address().get_address() << std::endl; |
19 // assign a pid |
|
20 uint16_t pid = ++pid_pool; |
|
21 |
|
22 // log |
|
23 std::cout << "[server.on_connect] INFO: " << computer.get_address().get_address() << " -> #" << pid << std::endl; |
|
24 |
|
25 // create the player object |
|
26 NetworkServerPlayer *player = new NetworkServerPlayer(*this, computer, pid); |
|
27 |
|
28 // map computer to it |
|
29 players[computer] = player; |
|
30 |
|
31 // add to GameState |
|
32 state.newRemotePlayer(player); |
20 } |
33 } |
21 |
34 |
22 void NetworkServer::on_disconnect (CL_NetComputer &computer) { |
35 void NetworkServer::on_disconnect (CL_NetComputer &computer) { |
23 std::cout << "NetworkServer.on_disconnect: " << computer.get_address().get_address() << std::endl; |
36 std::cout << "NetworkServer.on_disconnect: " << computer.get_address().get_address() << std::endl; |
|
37 |
|
38 // XXX: remove the player |
|
39 NetworkServerPlayer *player = players[computer]; |
|
40 |
|
41 // remove from players |
|
42 players.erase(computer); |
|
43 |
|
44 // remove from state |
|
45 state.removePlayer(player); |
|
46 |
|
47 // remove from game |
|
48 player->disconnected(); |
|
49 |
|
50 // delete |
|
51 delete player; |
24 } |
52 } |
25 |
53 |
26 NetworkServerClient::NetworkServerClient (NetworkServer &server) : server(server) { |
54 NetworkServerPlayer::NetworkServerPlayer (NetworkServer &server, CL_NetComputer &computer, uint16_t pid) : |
|
55 RemotePlayer(Coordinate(0, 0), true), server(server), computer(computer), netobj(&server.netobjs), pid(pid) { |
27 |
56 |
|
57 // messages |
|
58 slots.connect(netobj.sig_received_message(NETMSG_CLIENT_MOVE), this, &NetworkServerPlayer::on_move); |
|
59 |
|
60 // the initial NETMSG_PLAYER_HELLO |
|
61 CL_NetPacket hello_pkt; |
|
62 hello_pkt.output.write_uint32(position.x); |
|
63 hello_pkt.output.write_uint32(position.y); |
|
64 |
|
65 netobj.send(computer, NETMSG_SERVER_HELLO, hello_pkt, true); |
|
66 |
|
67 // send other player objects |
|
68 for (std::map<CL_NetComputer, NetworkServerPlayer*>::iterator it = server.players.begin(); it != server.players.end(); it++) { |
|
69 NetworkServerPlayer *player = it->second; |
|
70 CL_NetPacket player_pkt; |
|
71 |
|
72 // player is not in players list yet |
|
73 assert(player != this); |
|
74 |
|
75 player_pkt.output.write_uint32(player->position.x); |
|
76 player_pkt.output.write_uint32(player->position.y); |
|
77 |
|
78 player->netobj.send(computer, NETMSG_PLAYER_INFO, player_pkt, true); |
|
79 } |
|
80 |
|
81 |
|
82 // broadcast NETMSG_PLAYER_JOIN to all clients |
|
83 netobj.send(server.netsession.get_all(), NETMSG_PLAYER_JOIN, hello_pkt, true); |
28 } |
84 } |
29 |
85 |
|
86 void NetworkServerPlayer::disconnected (void) { |
|
87 CL_NetPacket pkt; |
|
88 |
|
89 netobj.send(server.netsession.get_all(), NETMSG_PLAYER_QUIT, pkt, true); |
|
90 } |
|
91 |
|
92 void NetworkServerPlayer::on_move (CL_NetComputer &from, CL_NetPacket &pkt) { |
|
93 // sanity-check |
|
94 if (!(from == computer)) |
|
95 return; |
|
96 |
|
97 // read packet |
|
98 uint32_t dx = pkt.input.read_uint32(); |
|
99 uint32_t dy = pkt.input.read_uint32(); |
|
100 |
|
101 // movement delta |
|
102 PositionDelta delta(dx, dy); |
|
103 |
|
104 // apply movement |
|
105 position += delta; |
|
106 |
|
107 // send position update |
|
108 send_position_update(); |
|
109 } |
|
110 |
|
111 void NetworkServerPlayer::send_position_update (void) { |
|
112 CL_NetPacket pkt; |
|
113 pkt.output.write_uint32(position.x); |
|
114 pkt.output.write_uint32(position.y); |
|
115 |
|
116 netobj.send(server.netsession.get_all(), NETMSG_PLAYER_POSITION, pkt, false); |
|
117 } |
|
118 |