|
Fimbulwinter Project
Pre-Alpha
An Ragnarok Online Emulator
|
00001 /*==================================================================* 00002 * ___ _ _ _ _ _ * 00003 * / __(_)_ __ ___ | |__ _ _| |_ _(_)_ __ | |_ ___ _ __ * 00004 * / _\ | | '_ ` _ \| '_ \| | | | \ \ /\ / / | '_ \| __/ _ \ '__| * 00005 * / / | | | | | | | |_) | |_| | |\ V V /| | | | | || __/ | * 00006 * \/ |_|_| |_| |_|_.__/ \__,_|_| \_/\_/ |_|_| |_|\__\___|_| * 00007 * * 00008 * ------------------------------------------------------------------* 00009 * Emulator * 00010 * ------------------------------------------------------------------* 00011 * Licenced under GNU GPL v3 * 00012 * ----------------------------------------------------------------- * 00013 * Socket Macros * 00014 * ==================================================================*/ 00015 00016 #pragma once 00017 00018 #include <boost/bind.hpp> 00019 #include <boost/shared_ptr.hpp> 00020 #include <boost/enable_shared_from_this.hpp> 00021 #include <boost/asio.hpp> 00022 #include <boost/asio/ip/tcp.hpp> 00023 #include <malloc.h> 00024 #include <stdint.h> 00025 #include <map> 00026 00027 using namespace boost::asio::ip; 00028 00029 #define FIFOSIZE_SERVERLINK (256 * 1024) 00030 00031 /*==============================================================* 00032 * Function: Socket Manipulation Macros * 00033 * Author: GreenBox * 00034 * Date: 08/12/11 * 00035 * Description: Read "packet_guide.txt" in documentation * 00036 * for more information. * 00037 **==============================================================*/ 00038 00039 #define RFIFOHEAD(cl) 00040 #define WFIFOHEAD(cl, size) if(cl->wdata_size + (size) > cl->max_wdata) cl->realloc_writefifo(size); 00041 #define RFIFOP(cl,pos) (cl->rdata + cl->rdata_pos + (pos)) 00042 #define WFIFOP(cl,pos) (cl->wdata + cl->wdata_size + (pos)) 00043 00044 #define RFIFOB(cl,pos) (*(unsigned char*)RFIFOP(cl,pos)) 00045 #define WFIFOB(cl,pos) (*(unsigned char*)WFIFOP(cl,pos)) 00046 #define RFIFOW(cl,pos) (*(unsigned short*)RFIFOP(cl,pos)) 00047 #define WFIFOW(cl,pos) (*(unsigned short*)WFIFOP(cl,pos)) 00048 #define RFIFOL(cl,pos) (*(unsigned int*)RFIFOP(cl,pos)) 00049 #define WFIFOL(cl,pos) (*(unsigned int*)WFIFOP(cl,pos)) 00050 #define RFIFOQ(cl,pos) (*(unsigned long long*)RFIFOP(cl,pos)) 00051 #define WFIFOQ(cl,pos) (*(unsigned long long*)WFIFOP(cl,pos)) 00052 #define RFIFOSPACE(cl) (cl->max_rdata - cl->rdata_size) 00053 #define WFIFOSPACE(cl) (cl->max_wdata - cl->wdata_size) 00054 00055 #define RFIFOREST(cl) (cl->flags.eof ? 0 : cl->rdata_size - cl->rdata_pos) 00056 #define RFIFOFLUSH(cl) \ 00057 if(cl->rdata_size == cl->rdata_pos) { \ 00058 cl->rdata_size = cl->rdata_pos = 0; \ 00059 } else { \ 00060 cl->rdata_size -= cl->rdata_pos; \ 00061 memmove(cl->rdata, cl->rdata + cl->rdata_pos, cl->rdata_size); \ 00062 cl->rdata_pos = 0; \ 00063 } 00064 00065 #define RBUFP(p,pos) (((unsigned char*)(p)) + (pos)) 00066 #define RBUFB(p,pos) (*(unsigned char*)RBUFP((p),(pos))) 00067 #define RBUFW(p,pos) (*(unsigned short*)RBUFP((p),(pos))) 00068 #define RBUFL(p,pos) (*(unsigned int*)RBUFP((p),(pos))) 00069 #define RBUFQ(p,pos) (*(unsigned long long*)RBUFP((p),(pos))) 00070 00071 #define WBUFP(p,pos) (((unsigned char*)(p)) + (pos)) 00072 #define WBUFB(p,pos) (*(unsigned char*)WBUFP((p),(pos))) 00073 #define WBUFW(p,pos) (*(unsigned short*)WBUFP((p),(pos))) 00074 #define WBUFL(p,pos) (*(unsigned int*)WBUFP((p),(pos))) 00075 #define WBUFQ(p,pos) (*(unsigned long long*)WBUFP((p),(pos))) 00076 00077 #define TOB(n) ((unsigned char)((n)&UCHAR_MAX)) 00078 #define TOW(n) ((unsigned short)((n)&USHORT_MAX)) 00079 #define TOL(n) ((unsigned int)((n)&UINT_MAX)) 00080 #define TOQ(n) ((unsigned long long)((n)&ULLONG_MAX)) 00081 00082 #define RFIFO_SIZE (2 * 1024) 00083 #define WFIFO_SIZE (16 * 1024) 00084 #define WFIFO_MAX (1 * 1024 * 1024) 00085 00086 class tcp_connection 00087 : public boost::enable_shared_from_this<tcp_connection> 00088 { 00089 public: 00090 typedef boost::shared_ptr<tcp_connection> pointer; 00091 typedef boost::function<int (pointer)> parse; 00092 00093 static pointer create(boost::asio::io_service &io_service) 00094 { 00095 return pointer(new tcp_connection(io_service)); 00096 } 00097 00098 tcp::socket &socket() 00099 { 00100 return socket_; 00101 } 00102 00103 void do_close() 00104 { 00105 try 00106 { 00107 socket_.close(); 00108 00109 sessions_.erase(tag_); 00110 } 00111 catch (void *) 00112 { 00113 } 00114 } 00115 00116 bool is_eof() 00117 { 00118 return flags.eof == 1; 00119 } 00120 00121 void set_eof() 00122 { 00123 flags.eof = 1; 00124 00125 if (parse_) 00126 parse_((pointer)this->shared_from_this()); 00127 } 00128 00129 void *get_data() 00130 { 00131 return data_; 00132 } 00133 00134 void set_data(char *data) 00135 { 00136 data_ = data; 00137 } 00138 00139 void set_parser(parse p) 00140 { 00141 parse_ = p; 00142 } 00143 00144 void start(); 00145 void send_buffer(size_t len); 00146 int skip(size_t len); 00147 00148 int realloc_writefifo(size_t addition); 00149 int realloc_fifo(unsigned int rfifo_size, unsigned int wfifo_size); 00150 00151 unsigned char *rdata, *wdata; 00152 size_t max_rdata, max_wdata; 00153 size_t rdata_size, wdata_size; 00154 size_t rdata_pos; 00155 00156 struct 00157 { 00158 unsigned char eof : 1; 00159 unsigned char server : 1; 00160 } flags; 00161 00162 ~tcp_connection() 00163 { 00164 free(rdata); 00165 free(wdata); 00166 } 00167 00168 int tag() 00169 { 00170 return tag_; 00171 } 00172 00173 static pointer get_session_by_tag(int t) 00174 { 00175 return sessions_[t]; 00176 } 00177 00178 static bool session_exists(int t) 00179 { 00180 return sessions_.count(t) == 1; 00181 } 00182 00183 private: 00184 tcp_connection(boost::asio::io_service &io_service) 00185 : socket_(io_service) 00186 { 00187 flags.eof = 0; 00188 flags.server = 0; 00189 00190 data_ = NULL; 00191 parse_ = NULL; 00192 00193 max_rdata = RFIFO_SIZE; 00194 max_wdata = WFIFO_SIZE; 00195 00196 rdata = (unsigned char *)malloc(max_rdata); 00197 wdata = (unsigned char *)malloc(max_wdata); 00198 00199 rdata_size = rdata_pos = 0; 00200 wdata_size = 0; 00201 } 00202 00203 void start_read(); 00204 void handle_write(const boost::system::error_code& error); 00205 void handle_read(const boost::system::error_code &error, size_t bytes_transferred); 00206 00207 tcp::socket socket_; 00208 void *data_; 00209 parse parse_; 00210 int tag_; 00211 00212 static int tag_counter_; 00213 static std::map<int, pointer> sessions_; 00214 };
1.7.6.1