#ifndef TTCPSOCKET_H #define TTCPSOCKET_H #include #include #include #include #include #include #include #include #include EXTERN_OBJECT_NAME(TTcpSocket); extern TTcpSocket *tcp_socket_table[16]; struct at_ip4_opt { u8 ttl; u8 svctype; u8 df_flag; }; struct at_ip6_opt { u8 traffic_class; u32 flow_label; u8 hop_limit; }; struct at_ip_option { u32 type; union { struct at_ip6_opt ip6; struct at_ip4_opt ip4; } ip46; }; struct at_ip_addr { u32 type; union { u8 ip6[16]; u32 ip4; } ip46; }; struct send_buffs { short len; u8 *buff; }; extern void func_80019aa0(); extern void controller_stuff(); extern char func_801a5d1c(); extern void render_tick(); extern void func_803d96a4(); extern short tcp_abort(short nh); extern short tcp_bind(short nh, struct at_ip_addr *addr, u16 port); extern short tcp_connect(short nh, struct at_ip_addr *addr, u16 port, struct at_ip_option *option); extern short tcp_create(); extern short tcp_delete(short nh); extern short tcp_get_opt(short nh, short type, u32 *opt); extern short tcp_send(short nh, void (*notify)(short size, short sock_fd), char bufnum, struct send_buffs *sb); extern short tcp_stat(short nh, short *stat, short *backlog, u32 *sendwin, u32 *recvwin); extern short tcp_receive(short nh, void (*notify)(short size, short sock_fd), short len, u8 *buf); extern int get_link_status(); extern char *get_sock_status_name(short code); class TTcpSocket : public TSocket { private: PSOV3EncryptionTCP m_send_crypt; PSOV3EncryptionTCP m_recv_crypt; int m_is_encrypted; public: WEAK_FUNC TTcpSocket(TObject *parent = nullptr); virtual ~TTcpSocket() { close(); }; virtual void recv() { if (sock_fd() != -1) { packet_buffer().fill(0); set_buffer_cleared(true); (int)tcp_receive(sock_fd(), notify, packet_buffer().size(), packet_buffer().data()); } }; virtual int send(u8 *data, size_t size) { if (sock_fd() != -1) { if (!m_is_encrypted) { m_send_crypt.encrypt(data, size); } const s8 flags = sock_flags(); if (flags || !get_link_status()) { return -1; } else { if (int status = stat()) { log(get_sock_status_name(status)); set_flags(1); return 1; } else { if (send_window() <= size) { set_flags(1); return 1; } else { if (stat_val() < 0) { set_flags(1); return 1; } else { struct send_buffs sb; sb.buff = data; sb.len = size; set_unused(0); int ret = tcp_send(sock_fd(), nullptr, 1, &sb); if (ret >= 1 || ret < -1) { set_flags(1); log(get_sock_status_name(ret)); close(); return ret; } } } } } } else { return -1; } }; virtual short send(u8 *data) { if (sock_fd() != -1) { const s8 flags = sock_flags(); if (flags || !get_link_status()) { return -1; } else { if (short status = stat()) { log(get_sock_status_name(status)); set_flags(1); return 1; } else { if (stat_val() < 0) { set_flags(1); return 1; } else { s8 len = strlen(reinterpret_cast(data)); struct send_buffs sb; sb.buff = data; sb.len = len; if (send_window() <= len) { set_flags(1); return 1; } else { short ret = tcp_send(sock_fd(), nullptr, 1, &sb); if (ret) { close(); } return ret; } } } } } else { return -1; } }; virtual short open(); virtual short close(); short stat(); void some_stub(); int test_connection(); static void notify(short size, short sock_fd) { char tmp_str[64]; TTcpSocket *socket = tcp_socket_table[sock_fd]; if (socket != nullptr) { if (size > 0) { socket->set_buffer_cleared(false); socket->set_size(size); socket->set_buffer_offset(0); sprintf(tmp_str, "Rcv:%d byte", size); socket->log(tmp_str); if (socket->callback() != nullptr) { socket->callback()(socket); } } else { socket->set_flags(1); } } }; PRIVATE_MEMBER_ACCESSORS(PSOV3EncryptionTCP, send_crypt); PRIVATE_MEMBER_ACCESSORS(PSOV3EncryptionTCP, recv_crypt); PRIVATE_MEMBER_ACCESSORS(int, is_encrypted); }; #endif