Jump to content


  • Posts

  • Joined

  • Last visited

Everything posted by phit666

  1. Primarily because of the select socket but to sort it out I changed mine to IOCP, its now running in multi threaded taking advantage of multi core processors.
  2. Base to sa latest revisions, nag add lang ako ng GUI interface sa windows and using IOCP socket na, compile it using visual studio 2019, select nyo lang Release GUI sa configuration. Sa security nag add ako ng dynamic encryption (disabled sya by default), pwede nyo enable (defines_pre.hpp under Custom) and it will help against proxy exploits or mga bots, kasama sa thirdparty folder yung client DLL (encDLL.dll) na magssend ng encrypted packet, hook nyo yung DLL using nemo. Sa gui mode, nilagay ko lahat ng reload options sa menu ng map server. https://github.com/phit666/rathena/tree/Levent
  3. This will allow the pointshop dealer to sell a bounded item and specific refine level, good for starter as it can't be exploited/spammed. The example below will sell an item with bound type 4 and refine level 10. prontera,155,166,4 pointshop Bounded Item Dealer 123,#votepoints:0:4,13103:600:10 pointshopext.diff
  4. The effective way is to have your own packet algo dynamic encryption, encryption should change every x counter, now when you made it create a heart beat packet that client will respond to when asked by server. See its not really easy so it cant be cheap^^
  5. I've added a GUI in windows, just so I can reload with a click
  6. https://github.com/phit666/rathena Added libevent library for socket, it will use IOCP as backend in windows, currently using SELECT, and EPOLL in linux.
  7. Ive added some missing stuffs for a friend, Im kind of in a hurry so I havnt really added docs and more cleaning/organizing is needed, I will tried to add more in my free time... https://github.com/phit666/roBrowser
  8. I will soon, Ive also set libevent to use IOCP as backend when compiling to windows, we knew how slow is select in windows so using the IOCP as backend will really add an edge for those windows users.
  9. So I've replaced the standard SELECT library with Libevent (libevent.org) library for obvious reasons below... 1. This will use EPOLL in linux which is a lot faster and efficient than SELECT mechanism, you will notice in socket.c, using SELECT mechanism the do_socket function is doing a lot of LOOOOOPS (sending/receiving/sending/parsing/sending to all active sockets) whenever SELECT is triggered, note how many "for(i = 1; i < fd_max; i++)" are there and being invoked whenever the server is receiving a few bytes. Using libevent mechanism, I only need to process one socket, only the socket where its receiving the data. 2. 1024 standard socket limit (FD_SETSIZE) of select in linux is enough for unpopulated server, but how about for those populated? EPOLL socket limit is way beyond 1024, its more than 100k sockets, it really depends on the kernel. Using select mechanism (note how many for loops are here) int do_sockets(int next) { fd_set rfd; struct timeval timeout; int ret,i; // PRESEND Timers are executed before do_sendrecv and can send packets and/or set sessions to eof. // Send remaining data and process client-side disconnects here. #ifdef SEND_SHORTLIST send_shortlist_do_sends(); #else for (i = 1; i < fd_max; i++) { if(!session[i]) continue; if(session[i]->wdata_size) session[i]->func_send(i); } #endif // can timeout until the next tick timeout.tv_sec = next/1000; timeout.tv_usec = next%1000*1000; memcpy(&rfd, &readfds, sizeof(rfd)); ret = sSelect(fd_max, &rfd, NULL, NULL, &timeout); if( ret == SOCKET_ERROR ) { if( sErrno != S_EINTR ) { ShowFatalError("do_sockets: select() failed, %s!\n", error_msg()); exit(EXIT_FAILURE); } return 0; // interrupted by a signal, just loop and try again } last_tick = time(NULL); #if defined(WIN32) // on windows, enumerating all members of the fd_set is way faster if we access the internals for( i = 0; i < (int)rfd.fd_count; ++i ) { int fd = sock2fd(rfd.fd_array[i]); if( session[fd] ) session[fd]->func_recv(fd); } #else // otherwise assume that the fd_set is a bit-array and enumerate it in a standard way for( i = 1; ret && i < fd_max; ++i ) { if(sFD_ISSET(i,&rfd) && session[i]) { session[i]->func_recv(i); --ret; } } #endif // POSTSEND Send remaining data and handle eof sessions. #ifdef SEND_SHORTLIST send_shortlist_do_sends(); #else for (i = 1; i < fd_max; i++) { if(!session[i]) continue; if(session[i]->wdata_size) session[i]->func_send(i); if(session[i]->flag.eof) //func_send can't free a session, this is safe. { //Finally, even if there is no data to parse, connections signalled eof should be closed, so we call parse_func [Skotlex] session[i]->func_parse(i); //This should close the session immediately. } } #endif // parse input data on each socket for(i = 1; i < fd_max; i++) { if(!session[i]) continue; if (session[i]->rdata_tick && DIFF_TICK(last_tick, session[i]->rdata_tick) > stall_time) { if( session[i]->flag.server ) {/* server is special */ if( session[i]->flag.ping != 2 )/* only update if necessary otherwise it'd resend the ping unnecessarily */ session[i]->flag.ping = 1; } else { ShowInfo("Session #%d timed out\n", i); set_eof(i); } } session[i]->func_parse(i); if(!session[i]) continue; // after parse, check client's RFIFO size to know if there is an invalid packet (too big and not parsed) if (session[i]->rdata_size == RFIFO_SIZE && session[i]->max_rdata == RFIFO_SIZE) { set_eof(i); continue; } RFIFOFLUSH(i); } #ifdef SHOW_SERVER_STATS if (last_tick != socket_data_last_tick) { char buf[1024]; sprintf(buf, "In: %.03f kB/s (%.03f kB/s, Q: %.03f kB) | Out: %.03f kB/s (%.03f kB/s, Q: %.03f kB) | RAM: %.03f MB", socket_data_i/1024., socket_data_ci/1024., socket_data_qi/1024., socket_data_o/1024., socket_data_co/1024., socket_data_qo/1024., malloc_usage()/1024.); #ifdef _WIN32 SetConsoleTitle(buf); #else ShowMessage("\033[s\033[1;1H\033[2K%s\033[u", buf); #endif socket_data_last_tick = last_tick; socket_data_i = socket_data_ci = 0; socket_data_o = socket_data_co = 0; } #endif return 0; } Now using libevent mechanism void conn_readcb(struct bufferevent *bev, void *ptr) { int len,i; int fd = ptr; if( !session_isValid(fd) ) { return; } len = bufferevent_read(bev,(char *)session[fd]->rdata + session[fd]->rdata_size,(int)RFIFOSPACE(fd)); if(len == 0) { set_eof(fd); } session[fd]->rdata_size += len; session[fd]->rdata_tick = last_tick; if(session[fd]->kill_tick > 0) return; session[fd]->func_parse(fd); session[fd]->func_send(fd); if(session[fd]->flag.eof) { session[fd]->func_parse(fd); } RFIFOFLUSH(fd); } Now for those owners who got a big number, preferrably more than 1024 players and using linux server, PM me if you would like to test my update.
  • Create New...

Important Information

By using this site, you agree to our Terms of Use and Privacy Policy.