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@431: node_map[remote_address] = client_node; terom@431: node_list.push_back(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@431: node_map.erase(node->getRemoteAddress()); terom@431: node_list.remove(node); 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@431: node_map[addr] = client_node; terom@431: node_list.push_back(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@431: NetworkNode *node = node_map[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@431: terom@431: void NetworkSession::write_packet_header (NetworkPacketOutput &pkt, NetworkChannelID channel_id) { terom@431: pkt.write_uint16(channel_id); terom@185: } terom@185: