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