src/proto2/NetworkServer.cc
branchno-netsession
changeset 36 785d220fc6b7
parent 35 e21cfda0edde
child 38 4189b8bf3a5b
equal deleted inserted replaced
35:e21cfda0edde 36:785d220fc6b7
     2 #include "Engine.hh"
     2 #include "Engine.hh"
     3 #include "Logger.hh"
     3 #include "Logger.hh"
     4 
     4 
     5 #include <cassert>
     5 #include <cassert>
     6 
     6 
     7 NetworkServer::NetworkServer (GameState &state, const std::string &listen_port) : 
     7 NetworkServer::NetworkServer (GameState &state, const NetworkAddress &listen_addr) : 
     8     NetworkCore(state), pid_pool(0) {
     8     NetworkCore(state), netsession(NETWORK_MAGIC_ID), netobjs(netsession, NETCHAN_CORE) {
     9     
     9     
    10     // connect slots
    10     // connect slots
    11     slots.connect(netsession.sig_computer_connected(), this, &NetworkServer::on_connect);
    11     slots.connect(netsession.sig_node_connected(), this, &NetworkServer::on_node_connected);
    12     slots.connect(netsession.sig_computer_disconnected(), this, &NetworkServer::on_disconnect);
       
    13     
    12     
    14     // and then we listen
    13     // and then we listen
    15     netsession.start_listen(listen_port);
    14     netsession.listen(listen_addr);
    16 
    15 
    17     Engine::log(INFO, "server") << "running, listen_port=" << listen_port;
    16     Engine::log(INFO, "server") << "running, listen_addr=" << listen_addr;
    18 }
    17 }
    19 
    18 
    20 void NetworkServer::on_connect (CL_NetComputer &computer) {
    19 void NetworkServer::on_node_connected (NetworkNode *node) {
    21     // assign a pid
    20     // create the player object (it logs it)
    22     uint16_t pid = ++pid_pool;
    21     NetworkServerPlayer *player = new NetworkServerPlayer(*this, node);
       
    22 
       
    23     // add to players
       
    24     players.push_back(player);
    23     
    25     
    24     // create the player object (it logs it)
       
    25     NetworkServerPlayer *player = new NetworkServerPlayer(*this, computer, pid);
       
    26     
       
    27     // map computer to it
       
    28     players[computer] = player;
       
    29 
       
    30     // add to GameState
    26     // add to GameState
    31     state.newRemotePlayer(player);
    27     state.newRemotePlayer(player);
    32 }
    28 }
    33 
    29         
    34 void NetworkServer::on_disconnect (CL_NetComputer &computer) {
    30 void NetworkServer::handle_disconnect (NetworkServerPlayer *player) {
    35     NetworkServerPlayer *player = players[computer];
       
    36     
       
    37     // remove from players
       
    38     players.erase(computer);
       
    39 
       
    40     // remove from state
    31     // remove from state
    41     state.removePlayer(player);
    32     state.removePlayer(player);
    42 
    33 
    43     // remove from game
    34     // remove from list
    44     player->disconnected();
    35     players.remove(player);
    45 
       
    46     // delete
       
    47     delete player;
       
    48 }
    36 }
    49         
    37         
    50 NetworkServerPlayer::NetworkServerPlayer (NetworkServer &server, CL_NetComputer &computer, uint16_t pid) : 
    38 NetworkServerPlayer::NetworkServerPlayer (NetworkServer &server, NetworkNode *node) : 
    51     RemotePlayer(server.state, Vector(PLAYER_INITIAL_X, PLAYER_INITIAL_Y), true), server(server), computer(computer), obj(&server.netobjs), pid(pid) {
    39     RemotePlayer(server.state, Vector(PLAYER_INITIAL_X, PLAYER_INITIAL_Y), true), server(server), obj(server.netobjs), node(node) {
    52     
    40     
    53     // log
    41     // log
    54     Engine::log(INFO, "server_player.connected") << "computer=" << computer << ", obj=" << obj;
    42     Engine::log(INFO, "server_player.connected") << "node=" << node << ", obj=" << obj;
    55 
    43 
    56     // messages
    44     // messages
    57     slots.connect(obj.sig_received_message(NETMSG_CLIENT_MOVE), this, &NetworkServerPlayer::on_move);   
    45     slots.connect(node->sig_disconnected(), this, &NetworkServerPlayer::on_disconnected);
       
    46     slots.connect(obj.sig_message(NETMSG_CLIENT_MOVE), this, &NetworkServerPlayer::on_move);
    58 
    47 
    59     // the initial NETMSG_PLAYER_HELLO
    48     // the initial NETMSG_PLAYER_HELLO
    60     CL_NetPacket hello_pkt;
    49     NetworkPacket hello_pkt;
    61     writeVector(hello_pkt, position);
    50     hello_pkt.write_vector(position);
    62 
    51 
    63     obj.send(computer, NETMSG_SERVER_HELLO, hello_pkt, true);
    52     obj.send_to(node, NETMSG_SERVER_HELLO, hello_pkt, true);
    64 
    53 
    65     // send other player objects
    54     // send other player objects
    66     for (std::map<CL_NetComputer, NetworkServerPlayer*>::iterator it = server.players.begin(); it != server.players.end(); it++) {
    55     for (std::list<NetworkServerPlayer*>::iterator it = server.players.begin(); it != server.players.end(); it++) {
    67         NetworkServerPlayer *player = it->second;
    56         NetworkServerPlayer *player = *it;
    68         CL_NetPacket player_pkt;
    57         NetworkPacket player_pkt;
    69         
    58         
    70         // player is not in players list yet
    59         // player is not in players list yet
    71         assert(player != this);
    60         assert(player != this);
       
    61         
       
    62         player_pkt.write_vector(player->position);
    72 
    63 
    73         writeVector(player_pkt, player->position);
    64         player->obj.send_to(node, NETMSG_PLAYER_INFO, player_pkt, true);
    74 
       
    75         player->obj.send(computer, NETMSG_PLAYER_INFO, player_pkt, true);
       
    76     }
    65     }
    77 
    66 
    78 
    67     // broadcast NETMSG_PLAYER_JOIN to all clients except current
    79     // broadcast NETMSG_PLAYER_JOIN to all clients
    68     obj.send_all_except(NETMSG_PLAYER_JOIN, hello_pkt, node, true);
    80     obj.send(server.netsession.get_all(), NETMSG_PLAYER_JOIN, hello_pkt, true);
       
    81 }
    69 }
    82 
    70 
    83 void NetworkServerPlayer::disconnected (void) {
    71 void NetworkServerPlayer::on_disconnected (void) {
    84     CL_NetPacket pkt;
    72     NetworkPacket pkt;
    85     
    73     
    86     Engine::log(INFO, "server_player.disconnected") << "computer=" << computer << ", obj=" << obj;
    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);
    87 
    81 
    88     obj.send(server.netsession.get_all(), NETMSG_PLAYER_QUIT, pkt, true);
    82     // free
       
    83     delete this;
    89 }
    84 }
    90 
    85 
    91 void NetworkServerPlayer::on_move (CL_NetComputer &from, CL_NetPacket &pkt) {
    86 void NetworkServerPlayer::on_move (NetworkNode *src, NetworkPacket &pkt) {
    92     // sanity-check
    87     // sanity-check
    93     if (!(from == computer))
    88     if (src != node)
    94         return;
    89         return;
    95     
    90     
    96     Vector impulse_force = readVector(pkt);    
    91     Vector impulse_force = pkt.read_vector();
    97     uint16_t impulse_ms = pkt.input.read_uint16();
    92     uint16_t impulse_ms = pkt.read_uint16();
    98 
    93 
    99     Engine::log(INFO, "server_player.on_move") << "obj=" << obj << ", old_pos=" << position << ", impulse=" << impulse_force << "@" << impulse_ms << "ms";
    94     Engine::log(INFO, "server_player.on_move") << "player=" << obj << ", old_pos=" << position << ", impulse=" << impulse_force << "@" << impulse_ms << "ms";
   100     
    95     
   101     // apply force
    96     // apply force
   102     applyForce(impulse_force, impulse_ms);
    97     applyForce(impulse_force, impulse_ms);
   103 
    98 
   104     // send position update
    99     // send position update
   105     send_position_update();
   100     send_position_update();
   106 }
   101 }
   107         
   102         
   108 void NetworkServerPlayer::send_position_update (void) {
   103 void NetworkServerPlayer::send_position_update (void) {
   109     CL_NetPacket pkt;
   104     NetworkPacket pkt;
   110     writeVector(pkt, position);
   105     pkt.write_vector(position);
   111     writeVector(pkt, velocity);
   106     pkt.write_vector(velocity);
   112 
   107 
   113     Engine::log(INFO, "server_player.send_position_update") << "obj=" << obj << " -> " << position << "+" << velocity;
   108     Engine::log(INFO, "server_player.send_position_update") << "obj=" << obj << " -> " << position << "+" << velocity;
   114 
   109 
   115     obj.send(server.netsession.get_all(), NETMSG_PLAYER_POSITION, pkt, false);
   110     obj.send_all(NETMSG_PLAYER_POSITION, pkt, false);
   116 }
   111 }
   117 
   112