diff options
-rw-r--r-- | context.h | 190 | ||||
-rw-r--r-- | include/pso/TTcpSocket.h | 41 | ||||
-rw-r--r-- | include/pso/forward.h | 2 | ||||
-rw-r--r-- | obj_files.mk | 1 | ||||
-rw-r--r-- | src/pso/TTcpSocket.cpp | 181 |
5 files changed, 341 insertions, 74 deletions
@@ -88,6 +88,7 @@ typedef long ptrdiff_t; #define FOREACH_NODE_NODECL_MULTI_ITER(type, first, varname, ...) for (varname = (type *)(first); varname != NULL; varname = (type *)(varname->next()), __VA_ARGS__) #define __packed__ +#define WEAK_FUNC __declspec(weak) #define PRIVATE_MEMBER_GETTER(type, name) \ type name() { \ @@ -118,6 +119,14 @@ typedef long ptrdiff_t; PRIVATE_MEMBER_GETTER(type, name); \ PRIVATE_MEMBER_SETTER(type, name) +#define PRIVATE_MEMBER_ACCESSORS(type, name) \ + PRIVATE_MEMBER_GETTER(type &, name); \ + PRIVATE_MEMBER_SETTER(type, name) + +#define PRIVATE_MEMBER_ACCESSORS_NON_REF(type, name) \ + PRIVATE_MEMBER_GETTER(type, name); \ + PRIVATE_MEMBER_SETTER(type, name) + #define PRIVATE_MEMBER_ACCESSORS_ARRAY(type, name, size) \ PRIVATE_MEMBER_GETTER_ARRAY(type, name, size) @@ -148,6 +157,9 @@ typedef long ptrdiff_t; // pso/forward.h // Class forward. +class TTcpSocket; +class PSOV3EncryptionTCP; +class TSocket; class THeap; class TObject; class TMainTask; @@ -434,8 +446,12 @@ TMenuListEntry<T> &TMenuListEntry<T>::operator=(const TMenuListEntry<T> &src) { // Const defs. static const int tl_object_count = 20; -// TObject.cpp +// TTcpSocket.cpp // Extern defs. +EXTERN_OBJECT_NAME(TTcpSocket); +extern TTcpSocket *tcp_socket_table[16]; + +// TObject.cpp #define o(name) extern const char *name##_name; OBJECT_NAMES #undef o @@ -568,77 +584,6 @@ private: u32 m_seed; }; -// pso/TSocket.h -class TSocket : public TObject { -private: - void set_flags(u8 flags) { - m_sock_flags |= flags; - }; - - void clear_flags(u8 flags) { - m_sock_flags &= ~flags; - }; - - void toggle_flags(u8 flags) { - m_sock_flags ^= flags; - }; - - u8 get_flags(u8 flags) { - return m_sock_flags & flags; - }; - - ipv4_addr m_dst_addr; - u16 m_dst_port; - u16 m_src_port; - ipv4_addr m_src_addr; - s16 m_sock_fd; - u8 m_sock_flags; - bool m_buffer_cleared; - s16 m_size; - s16 m_buffer_offset; - u32 m_unused; - TArray<u8, 64> m_unused2; - TArray<u8, 2048> m_packet_buffer; - s16 m_stat; - u16 m_unused3; - u32 m_send_window; - u32 m_recv_window; - void (*m_callback)(TSocket *socket); -public: - TSocket(TObject *parent); - virtual ~TSocket(); - - virtual int open() = 0; - virtual int close() = 0; - virtual void recv() = 0; - virtual int send(u8 *data) = 0; - virtual int send(u8 *data, size_t size) = 0; - - int resolve_domain(char *domain); - void set_ip_address(u32 addr); - void set_port(u32 port); - const u8 next(); - int is_empty(); - - PRIVATE_MEMBER_ACCESSORS(ipv4_addr, dst_addr); - PRIVATE_MEMBER_ACCESSORS(u16, dst_port); - PRIVATE_MEMBER_ACCESSORS(u16, src_port); - PRIVATE_MEMBER_ACCESSORS(ipv4_addr, src_addr); - PRIVATE_MEMBER_ACCESSORS(s16, sock_fd); - PRIVATE_MEMBER_ACCESSORS(u8, sock_flags); - PRIVATE_MEMBER_ACCESSORS(bool, buffer_cleared); - PRIVATE_MEMBER_ACCESSORS(s16, size); - PRIVATE_MEMBER_ACCESSORS(s16, buffer_offset); - PRIVATE_MEMBER_ACCESSORS(u32, unused); - PRIVATE_MEMBER_ACCESSORS_ARRAY(u8, unused2, 64); - PRIVATE_MEMBER_ACCESSORS_ARRAY(u8, packet_buffer, 2048); - PRIVATE_MEMBER_ACCESSORS(s16, stat); - PRIVATE_MEMBER_ACCESSORS(u16, unused3); - PRIVATE_MEMBER_ACCESSORS(u32, send_window); - PRIVATE_MEMBER_ACCESSORS(u32, recv_window); - PRIVATE_MEMBER_ACCESSORS_FUNC(void, callback, TSocket *socket); -}; - // pso/THeap.h class THeap { public: @@ -798,6 +743,103 @@ public: bool toggle_flag_9_if_flag_10_is_clear(); }; +// pso/TSocket.h +class TSocket : public TObject { +private: + ipv4_addr m_dst_addr; + u16 m_dst_port; + u16 m_src_port; + ipv4_addr m_src_addr; + s16 m_sock_fd; + u8 m_sock_flags; + bool m_buffer_cleared; + s16 m_size; + s16 m_buffer_offset; + u32 m_unused; + TArray<u8, 64> m_unused2; + TArray<u8, 2048> m_packet_buffer; + s16 m_stat_val; + u16 m_unused3; + u32 m_send_window; + u32 m_recv_window; + void (*m_callback)(TSocket *socket); +public: + TSocket(TObject *parent); + virtual ~TSocket(); + + virtual short open() = 0; + virtual short close() = 0; + virtual void recv() = 0; + virtual short send(u8 *data) = 0; + virtual int send(u8 *data, size_t size) = 0; + + int resolve_domain(char *domain); + void set_ip_address(u32 addr); + void set_port(u32 port); + const u8 next(); + int is_empty(); + + void set_flags(u8 flags) { + m_sock_flags |= flags; + }; + + void clear_flags(u8 flags) { + m_sock_flags &= ~flags; + }; + + void toggle_flags(u8 flags) { + m_sock_flags ^= flags; + }; + + u8 get_flags(u8 flags) { + return m_sock_flags & flags; + }; + + PRIVATE_MEMBER_ACCESSORS(ipv4_addr, dst_addr); + PRIVATE_MEMBER_ACCESSORS(u16, dst_port); + PRIVATE_MEMBER_ACCESSORS(u16, src_port); + PRIVATE_MEMBER_ACCESSORS(ipv4_addr, src_addr); + PRIVATE_MEMBER_ACCESSORS(s16, sock_fd); + PRIVATE_MEMBER_ACCESSORS(u8, sock_flags); + PRIVATE_MEMBER_ACCESSORS(bool, buffer_cleared); + PRIVATE_MEMBER_ACCESSORS(s16, size); + PRIVATE_MEMBER_ACCESSORS(s16, buffer_offset); + PRIVATE_MEMBER_ACCESSORS(u32, unused); + PRIVATE_MEMBER_ACCESSORS_ARRAY(u8, unused2, 64); + PRIVATE_MEMBER_ACCESSORS_ARRAY(u8, packet_buffer, 2048); + PRIVATE_MEMBER_ACCESSORS(s16, stat_val); + PRIVATE_MEMBER_ACCESSORS(u16, unused3); + PRIVATE_MEMBER_ACCESSORS(u32, send_window); + PRIVATE_MEMBER_ACCESSORS(u32, recv_window); + PRIVATE_MEMBER_ACCESSORS_FUNC(void, callback, TSocket *socket); +}; + +// pso/TTcpSocket.h +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(); + + virtual short open() override; + virtual short close() override; + virtual void recv() override; + virtual short send(u8 *data) override; + virtual int send(u8 *data, size_t size) override; + + int stat(); + int test_connection(); + + static void notify(short size, short sock_fd); + + PRIVATE_MEMBER_ACCESSORS(PSOV3EncryptionTCP, send_crypt); + PRIVATE_MEMBER_ACCESSORS(PSOV3EncryptionTCP, recv_crypt); + PRIVATE_MEMBER_ACCESSORS(int, is_encrypted); +}; + // pso/TMainTask.h class TMainTask : public TObject { public: @@ -864,8 +906,8 @@ public: virtual u32 next() override; PRIVATE_MEMBER_ACCESSORS_ARRAY(u32, buffer, 522); - PRIVATE_MEMBER_ACCESSORS(u32 *, buffer_start); - PRIVATE_MEMBER_ACCESSORS(u32 *, buffer_end); + PRIVATE_MEMBER_ACCESSORS_NON_REF(u32 *, buffer_start); + PRIVATE_MEMBER_ACCESSORS_NON_REF(u32 *, buffer_end); private: TArray<u32, 522> m_buffer; diff --git a/include/pso/TTcpSocket.h b/include/pso/TTcpSocket.h new file mode 100644 index 0000000..9740a3a --- /dev/null +++ b/include/pso/TTcpSocket.h @@ -0,0 +1,41 @@ +#ifndef TTCPSOCKET_H +#define TTCPSOCKET_H + +#include <global_types.h> +#include <string.h> +#include <pso/macros.h> +#include <pso/forward.h> +#include <pso/PSOV3EncryptionTCP.h> +#include <pso/TArray.h> +#include <pso/TSocket.h> +#include <pso/TObject.h> + +EXTERN_OBJECT_NAME(TTcpSocket); +extern TTcpSocket *tcp_socket_table[16]; + +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(); + + virtual short open() override; + virtual short close() override; + virtual void recv() override; + virtual short send(u8 *data) override; + virtual int send(u8 *data, size_t size) override; + + int stat(); + int test_connection(); + + static void notify(short size, short sock_fd); + + PRIVATE_MEMBER_ACCESSORS(PSOV3EncryptionTCP, send_crypt); + PRIVATE_MEMBER_ACCESSORS(PSOV3EncryptionTCP, recv_crypt); + PRIVATE_MEMBER_ACCESSORS(int, is_encrypted); +}; + +#endif diff --git a/include/pso/forward.h b/include/pso/forward.h index 165b9ad..1bc71cf 100644 --- a/include/pso/forward.h +++ b/include/pso/forward.h @@ -1,6 +1,8 @@ #ifndef FORWARD_H #define FORWARD_H +class TTcpSocket; +class PSOV3EncryptionTCP; class TSocket; class THeap; class TObject; diff --git a/obj_files.mk b/obj_files.mk index 1f9de57..48bd54d 100644 --- a/obj_files.mk +++ b/obj_files.mk @@ -1,5 +1,6 @@ O_FILES := $(BUILD_DIR)/src/main.o \ $(BUILD_DIR)/src/pso/TPlyGuildCardTag.o \ + $(BUILD_DIR)/src/pso/TTcpSocket.o \ $(BUILD_DIR)/src/pso/TSocket.o \ $(BUILD_DIR)/src/pso/PSOV3EncryptionTCP.o \ $(BUILD_DIR)/src/pso/THeap.o \ diff --git a/src/pso/TTcpSocket.cpp b/src/pso/TTcpSocket.cpp new file mode 100644 index 0000000..71bdd99 --- /dev/null +++ b/src/pso/TTcpSocket.cpp @@ -0,0 +1,181 @@ +#include <global_types.h> +#include <stdio.h> +#include <string.h> +#include "pso/macros.h" +#include "pso/TArray.h" +#include "pso/TObject.h" +#include "pso/TSocket.h" +#include "pso/TTcpSocket.h" + +OBJECT_NAME(TTcpSocket); +TTcpSocket *tcp_socket_table[16] = {nullptr}; + +struct send_buffs { + short len; + u8 *buff; +}; + +short tcp_abort(short nh); +short tcp_delete(short nh); +short tcp_send(short nh, void (*notify)(short size, short sock_fd), char bufnum, struct send_buffs *sb); +short tcp_stat(short nh, short *stat, short *backlog, u32 *sendwin, u32 *recvwin); +short tcp_receive(short nh, void (*notify)(short size, short sock_fd), short len, u8 *buf); +int get_link_status(); +char *get_sock_status_name(short code); + + +WEAK_FUNC TTcpSocket::TTcpSocket(TObject *parent) : TSocket(parent) { + set_name(TTcpSocket_name); +} + +TTcpSocket::~TTcpSocket() { + close(); +} + +void TTcpSocket::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()); + } +} + +void TTcpSocket::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); + } + } +} + +int TTcpSocket::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; + } +} + +short TTcpSocket::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<const char *>(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; + } +} + +int TTcpSocket::test_connection() { + +} + +void some_stub() {} + +int TTcpSocket::stat() { + if (sock_fd() != -1) { + return tcp_stat(sock_fd(), &stat_val(), nullptr, &send_window(), &recv_window()); + } else { + return 0; + } +} + +short TTcpSocket::close() { + if (sock_fd() != -1) { + (short)tcp_abort(sock_fd()); + (short)tcp_delete(sock_fd()); + tcp_socket_table[sock_fd()] = nullptr; + set_sock_fd(-1); + m_is_encrypted = 0; + set_size(0); + set_buffer_offset(0); + set_buffer_cleared(true); + } + return sock_fd(); +} + +short TTcpSocket::open() { + +} + +short tcp_abort(short nh) {} +short tcp_delete(short nh) {} +short tcp_send(short nh, void (*notify)(short size, short sock_fd), char bufnum, struct send_buffs *sb) {} +short tcp_stat(short nh, short *stat, short *backlog, u32 *sendwin, u32 *recvwin) {} +short tcp_receive(short nh, void (*notify)(short size, short sock_fd), short len, u8 *buf) {} +int get_link_status() {} +char *get_sock_status_name(short code) {} |