terom@89: terom@89: #include "NetworkSession.hh" terom@89: #include "Engine.hh" terom@89: terom@89: #include terom@89: terom@89: NetworkSession::NetworkSession (uint64_t magic) : terom@89: magic(magic), tcp_srv(NULL), udp_srv(NULL), udp_client(NULL) { terom@89: terom@89: // nothing terom@89: } terom@89: terom@89: void NetworkSession::listen (const NetworkAddress &addr) { terom@89: assert(tcp_srv == NULL && udp_srv == NULL); terom@89: terom@89: // create TCP/UDP servers terom@89: tcp_srv = new NetworkTCPServer(addr); terom@89: udp_srv = new NetworkUDP(addr); terom@89: terom@89: // connect signals terom@89: slots.connect(tcp_srv->sig_client(), this, &NetworkSession::on_tcp_client); terom@89: slots.connect(udp_srv->sig_packet(), this, &NetworkSession::on_udp_packet); terom@89: } terom@89: terom@89: NetworkNode *NetworkSession::build_node (NetworkTCPTransport *tcp, NetworkUDP *udp, const NetworkAddress &addr, enum NetworkNodeType type) { terom@89: // XXX: unused terom@89: (void) type; terom@89: terom@89: // create node terom@89: return new NetworkNode(*this, tcp, udp, addr); terom@89: } terom@89: terom@89: NetworkNode* NetworkSession::connect (const NetworkAddress &addr) { terom@89: // XXX: only one connect terom@89: assert(!udp_client); terom@89: terom@89: // connect TCP terom@89: NetworkTCPClient *tcp_client = new NetworkTCPClient(addr); terom@89: terom@89: // create UDP socket on same address terom@89: udp_client = new NetworkUDP(tcp_client->getLocalAddress()); terom@89: terom@89: // build client terom@89: NetworkNode *client_node = build_node(tcp_client, udp_client, addr, NETWORK_NODE_CLIENT_SERVER); terom@89: terom@89: // add to nodes terom@89: nodes[addr] = client_node; terom@89: terom@89: // connect signals terom@89: slots.connect(udp_client->sig_packet(), this, &NetworkSession::on_udp_packet); terom@89: terom@89: // return the "server" node terom@89: return client_node; terom@89: } terom@89: terom@89: void NetworkSession::handle_disconnect (NetworkNode *node) { terom@89: // remove from nodes terom@89: nodes.erase(node->getRemoteAddress()); terom@89: } terom@89: terom@89: void NetworkSession::handle_message (NetworkPacket &pkt, NetworkNode *node) { terom@89: // read the channel id terom@89: NetworkChannelID channel_id = pkt.read_uint16(); terom@89: terom@89: // fire signal terom@89: _map_sig_chan_message[channel_id](pkt, node); terom@89: } terom@89: terom@89: void NetworkSession::on_tcp_client (NetworkTCPTransport *tcp_client) { terom@89: // get remote address manually, because NetworkTCPServer doesn't pass it in to us terom@89: NetworkAddress addr = tcp_client->getRemoteAddress(); terom@89: terom@89: // build client terom@89: NetworkNode *client_node = build_node(tcp_client, udp_srv, addr, NETWORK_NODE_SERVER_CLIENT); terom@89: terom@89: // add to nodes terom@89: nodes[addr] = client_node; terom@89: terom@89: // fire signals terom@89: _sig_node_connected(client_node); terom@89: } terom@89: terom@89: void NetworkSession::on_udp_packet (NetworkPacket &pkt, const NetworkAddress &addr) { terom@89: NetworkNode *node = nodes[addr]; terom@89: terom@89: // drop from unknown sources terom@89: if (!node) { terom@89: Engine::log(WARN, "net_session.on_udp_packet") << "dropping unsolicted UDP packet from " << addr; terom@89: return; terom@89: } terom@89: terom@89: // handle terom@89: handle_message(pkt, node); terom@89: } terom@89: terom@89: void NetworkSession::send_all (NetworkChannelID channel_id, const NetworkPacket &pkt, bool reliable) { terom@89: send_all_except(channel_id, pkt, NULL, reliable); terom@89: } terom@89: terom@89: void NetworkSession::send_all_except (NetworkChannelID channel_id, const NetworkPacket &pkt, const NetworkNode *node, bool reliable) { terom@89: for (std::map::iterator it = nodes.begin(); it != nodes.end(); it++) { terom@89: if (it->second == node) terom@89: continue; terom@89: terom@89: it->second->send(channel_id, pkt, reliable); terom@89: } terom@89: }