1 #include "NetworkServer.hh" |
|
2 #include "Engine.hh" |
|
3 #include "Logger.hh" |
|
4 |
|
5 #include <cassert> |
|
6 |
|
7 NetworkServer::NetworkServer (GameState &state, const NetworkAddress &listen_addr) : |
|
8 NetworkCore(state), netsession(NETWORK_MAGIC_ID), netobjs(netsession, NETCHAN_CORE) { |
|
9 |
|
10 // connect slots |
|
11 slots.connect(netsession.sig_node_connected(), this, &NetworkServer::on_node_connected); |
|
12 |
|
13 // and then we listen |
|
14 netsession.listen(listen_addr); |
|
15 |
|
16 Engine::log(INFO, "server") << "running, listen_addr=" << listen_addr; |
|
17 } |
|
18 |
|
19 void NetworkServer::on_node_connected (NetworkNode *node) { |
|
20 // create the player object (it logs it) |
|
21 NetworkServerPlayer *player = new NetworkServerPlayer(*this, node); |
|
22 |
|
23 // add to players |
|
24 players.push_back(player); |
|
25 |
|
26 // add to GameState |
|
27 state.newRemotePlayer(player); |
|
28 } |
|
29 |
|
30 void NetworkServer::handle_disconnect (NetworkServerPlayer *player) { |
|
31 // remove from state |
|
32 state.removePlayer(player); |
|
33 |
|
34 // remove from list |
|
35 players.remove(player); |
|
36 } |
|
37 |
|
38 NetworkServerPlayer::NetworkServerPlayer (NetworkServer &server, NetworkNode *node) : |
|
39 RemotePlayer(server.state, Vector(PLAYER_INITIAL_X, PLAYER_INITIAL_Y), true), server(server), obj(server.netobjs), node(node) { |
|
40 |
|
41 // log |
|
42 Engine::log(INFO, "server_player.connected") << "node=" << node << ", obj=" << obj; |
|
43 |
|
44 // messages |
|
45 slots.connect(node->sig_disconnected(), this, &NetworkServerPlayer::on_disconnected); |
|
46 slots.connect(obj.sig_message(NETMSG_CLIENT_MOVE), this, &NetworkServerPlayer::on_move); |
|
47 |
|
48 // the initial NETMSG_PLAYER_HELLO |
|
49 NetworkPacket hello_pkt; |
|
50 hello_pkt.write_vector(position); |
|
51 |
|
52 obj.send_to(node, NETMSG_SERVER_HELLO, hello_pkt, true); |
|
53 |
|
54 // send other player objects |
|
55 for (std::list<NetworkServerPlayer*>::iterator it = server.players.begin(); it != server.players.end(); it++) { |
|
56 NetworkServerPlayer *player = *it; |
|
57 NetworkPacket player_pkt; |
|
58 |
|
59 // player is not in players list yet |
|
60 assert(player != this); |
|
61 |
|
62 player_pkt.write_vector(player->position); |
|
63 |
|
64 player->obj.send_to(node, NETMSG_PLAYER_INFO, player_pkt, true); |
|
65 } |
|
66 |
|
67 // broadcast NETMSG_PLAYER_JOIN to all clients except current |
|
68 obj.send_all_except(NETMSG_PLAYER_JOIN, hello_pkt, node, true); |
|
69 } |
|
70 |
|
71 void NetworkServerPlayer::on_disconnected (void) { |
|
72 NetworkPacket pkt; |
|
73 |
|
74 Engine::log(INFO, "server_player.disconnected") << "node=" << node << ", obj=" << obj; |
|
75 |
|
76 // remove from server |
|
77 server.handle_disconnect(this); |
|
78 |
|
79 // tell other clients |
|
80 obj.send_all(NETMSG_PLAYER_QUIT, pkt, true); |
|
81 |
|
82 // free |
|
83 // delete this; |
|
84 } |
|
85 |
|
86 void NetworkServerPlayer::on_move (NetworkNode *src, NetworkPacket &pkt) { |
|
87 // sanity-check, other players shouldn't move |
|
88 if (src != node) { |
|
89 Engine::log(WARN, "server_player.on_move") << "packet from wrong src=" << src << ", node=" << node; |
|
90 return; |
|
91 } |
|
92 |
|
93 PlayerInput_Move input = pkt.read_uint16(); |
|
94 |
|
95 Engine::log(INFO, "server_player.on_move") << "player=" << obj << ", old_pos=" << position << ", input=" << input; |
|
96 |
|
97 // apply input |
|
98 handleMove(input); |
|
99 |
|
100 // send position update |
|
101 send_position_update(); |
|
102 } |
|
103 |
|
104 void NetworkServerPlayer::send_position_update (void) { |
|
105 NetworkPacket pkt; |
|
106 pkt.write_vector(position); |
|
107 pkt.write_vector(velocity); |
|
108 pkt.write_uint8(inAir & NETWORK_PHYSICS_INAIR); |
|
109 |
|
110 Engine::log(INFO, "server_player.send_position_update") << "obj=" << obj << " -> " << position << "+" << velocity; |
|
111 |
|
112 obj.send_all(NETMSG_PLAYER_POSITION, pkt, false); |
|
113 } |
|
114 |
|