8 #include "../../bscript/bobject.h" 9 #include "../../clib/esignal.h" 10 #include "../../clib/fdump.h" 11 #include "../../clib/logfacility.h" 12 #include "../../clib/passert.h" 13 #include "../../clib/spinlock.h" 14 #include "../../clib/stlutil.h" 15 #include "../../plib/systemstate.h" 16 #include "../accounts/account.h" 18 #include "../crypt/cryptbase.h" 19 #include "../mobile/charactr.h" 20 #include "../pktboth.h" 21 #include "../pktbothid.h" 22 #include "../pktdef.h" 23 #include "../pktinid.h" 24 #include "../polcfg.h" 25 #include "../polclock.h" 26 #include "../polsem.h" 27 #include "../schedule.h" 28 #include "../scrdef.h" 29 #include "../scrsched.h" 30 #include "../sockets.h" 31 #include "../uoscrobj.h" 32 #include "../uworld.h" 39 #include <format/format.h> 41 #define CLIENT_CHECKPOINT( x ) client->checkpoint = x 44 #pragma warning( disable : 4127 ) // conditional expression is constant, because of FD_SET 52 void call_chr_scripts( Mobile::Character* chr,
const std::string& root_script_ecl,
53 const std::string& pkg_script_ecl,
bool offline =
false );
63 struct timeval c_select_timeout = {0, 0};
71 POLLOG.Format(
"Network::Client#{} i/o thread starting\n" ) << client->
instance_;
84 POLLOG.Format(
"Client#{} i/o thread past initial lock\n" ) << client->
instance_;
94 FD_ZERO( &c_recv_fd );
96 FD_ZERO( &c_send_fd );
106 clientSocket < FD_SETSIZE,
107 "Select() implementation in Linux cant handle this many sockets at the same time." )
108 nfds = clientSocket + 1;
111 FD_SET( clientSocket, &c_recv_fd );
112 FD_SET( clientSocket, &c_err_fd );
114 FD_SET( clientSocket, &c_send_fd );
122 c_select_timeout.tv_sec = 0;
127 c_select_timeout.tv_sec = 2;
128 c_select_timeout.tv_usec = 0;
131 res = select( nfds, &c_recv_fd, &c_send_fd, &c_err_fd, &c_select_timeout );
139 POLLOG.Format(
"Client#{}: select res={}, sckerr={}\n" )
145 if ( ( !client->
chr ||
174 if ( FD_ISSET( clientSocket, &c_err_fd ) )
189 unsigned char msgtype = pkt.
pktbuffer[0];
195 << fmt::hexu( msgtype ) <<
"\n";
201 catch ( std::exception& ex )
203 POLLOG_ERROR.Format(
"Client#{}: Exception in message handler 0x{:X}: {}\n" )
204 << client->
instance_ << (int)msgtype << ex.what();
207 POLLOG << tmp.str() <<
"\n";
218 if ( FD_ISSET( clientSocket, &c_recv_fd ) )
263 catch ( std::string& str )
265 POLLOG_ERROR.Format(
"Client#{}: Exception in i/o thread: {}! (checkpoint={})\n" )
268 catch (
const char* msg )
270 POLLOG_ERROR.Format(
"Client#{}: Exception in i/o thread: {}! (checkpoint={})\n" )
273 catch ( std::exception& ex )
275 POLLOG_ERROR.Format(
"Client#{}: Exception in i/o thread: {}! (checkpoint={})\n" )
282 POLLOG.Format(
"Client#{} ({}): disconnected (account {})\n" )
284 << ( ( client->
acct != nullptr ) ? client->
acct->
name() :
"unknown" );
306 int seconds_wait = 0;
326 seconds_wait = blong->
value();
365 catch ( std::exception& ex )
367 POLLOG.Format(
"Client#{}: Exception in i/o thread: {}! (checkpoint={}, what={})\n" )
368 << client->
instance_ << checkpoint << ex.what();
378 if ( length >
sizeof client->
buffer )
412 unsigned char msgtype = client->
buffer[0];
415 INFO_PRINT.Format(
"Incoming msg type: 0x{:X}\n" ) << (int)msgtype;
467 unsigned char msgtype = client->
buffer[0];
472 if ( !client->
fpLog.empty() )
475 tmp <<
"Client -> Server: 0x" << fmt::hexu( msgtype ) <<
", " << client->
message_length 483 INFO_PRINT.Format(
"Message Received: Type 0x{:X}, Length {} bytes\n" )
513 <<
"Client#" << client->
instance_ <<
": message 0x" << fmt::hexu( msgtype ) <<
"\n";
519 catch ( std::exception& ex )
521 POLLOG_ERROR.Format(
"Client#{}: Exception in message handler 0x{:X}: {}\n" )
522 << client->
instance_ << (int)msgtype << ex.what();
525 POLLOG << tmp.str() <<
"\n";
532 POLLOG_ERROR.Format(
"Client#{} ({}, Acct {}) sent non-allowed message type 0x{:X}.\n" )
534 << ( client->
acct ? client->
acct->
name() :
"unknown" ) << (
int)msgtype;
552 unsigned char cstype = client->
buffer[0];
554 if ( ( client->
buffer[0] == 0xff ) && ( client->
buffer[1] == 0xff ) &&
555 ( client->
buffer[2] == 0xff ) && ( client->
buffer[3] == 0xff ) )
559 INFO_PRINT.Format(
"UOKR Seed Message Received: Type 0x{:X}\n" ) << (int)cstype;
562 msg->WriteFlipped<
u16>( 77u );
563 msg->WriteFlipped<
u32>( 0x03u );
564 msg->Write<
u8>( 0x02u );
565 msg->Write<
u8>( 0x01u );
566 msg->Write<
u8>( 0x03u );
567 msg->WriteFlipped<
u32>( 0x13u );
568 msg->Write<
u8>( 0x02u );
569 msg->Write<
u8>( 0x11u );
570 msg->Write<
u8>( 0x00u );
571 msg->Write<
u8>( 0xfcu );
572 msg->Write<
u8>( 0x2fu );
573 msg->Write<
u8>( 0xe3u );
574 msg->Write<
u8>( 0x81u );
575 msg->Write<
u8>( 0x93u );
576 msg->Write<
u8>( 0xcbu );
577 msg->Write<
u8>( 0xafu );
578 msg->Write<
u8>( 0x98u );
579 msg->Write<
u8>( 0xddu );
580 msg->Write<
u8>( 0x83u );
581 msg->Write<
u8>( 0x13u );
582 msg->Write<
u8>( 0xd2u );
583 msg->Write<
u8>( 0x9eu );
584 msg->Write<
u8>( 0xeau );
585 msg->Write<
u8>( 0xe4u );
586 msg->Write<
u8>( 0x13u );
587 msg->WriteFlipped<
u32>( 0x10u );
588 msg->Write<
u8>( 0x78u );
589 msg->Write<
u8>( 0x13u );
590 msg->Write<
u8>( 0xb7u );
591 msg->Write<
u8>( 0x7bu );
592 msg->Write<
u8>( 0xceu );
593 msg->Write<
u8>( 0xa8u );
594 msg->Write<
u8>( 0xd7u );
595 msg->Write<
u8>( 0xbcu );
596 msg->Write<
u8>( 0x52u );
597 msg->Write<
u8>( 0xdeu );
598 msg->Write<
u8>( 0x38u );
599 msg->Write<
u8>( 0x30u );
600 msg->Write<
u8>( 0xeau );
601 msg->Write<
u8>( 0xe9u );
602 msg->Write<
u8>( 0x1eu );
603 msg->Write<
u8>( 0xa3u );
604 msg->WriteFlipped<
u32>( 0x20u );
605 msg->WriteFlipped<
u32>( 0x10u );
606 msg->Write<
u8>( 0x5au );
607 msg->Write<
u8>( 0xceu );
608 msg->Write<
u8>( 0x3eu );
609 msg->Write<
u8>( 0xe3u );
610 msg->Write<
u8>( 0x97u );
611 msg->Write<
u8>( 0x92u );
612 msg->Write<
u8>( 0xe4u );
613 msg->Write<
u8>( 0x8au );
614 msg->Write<
u8>( 0xf1u );
615 msg->Write<
u8>( 0x9au );
616 msg->Write<
u8>( 0xd3u );
617 msg->Write<
u8>( 0x04u );
618 msg->Write<
u8>( 0x41u );
619 msg->Write<
u8>( 0x03u );
620 msg->Write<
u8>( 0xcbu );
621 msg->Write<
u8>( 0x53u );
626 else if ( client->
buffer[0] ==
631 INFO_PRINT.Format(
"6.0.5.0+ Crypt Seed Message Received: Type 0x{:X}\n" ) << (int)cstype;
650 unsigned char tempseed[4];
651 tempseed[0] = client->
buffer[1];
652 tempseed[1] = client->
buffer[2];
653 tempseed[2] = client->
buffer[3];
654 tempseed[3] = client->
buffer[4];
665 switch ( client->
buffer[0] )
687 tmp.Format(
"Client#{}: {} type 0x{:X}, {} bytes (IP: {}, Account: {})\n" )
690 << ( ( client->
acct != nullptr ) ? client->
acct->
name() :
"None" );
701 POLLOG << tmp.str() <<
"\n";
717 int msgtype = (int)client->
buffer[0];
718 INFO_PRINT.Format(
"Undefined message type 0x{:X}\n" ) << msgtype;
738 tmp.Format(
"Humongous packet (length {})", reported_size );
void pol_sleep_ms(unsigned int millis)
#define CLIENT_CHECKPOINT(x)
bool have_queued_data() const
#define MSGLEN_2BYTELEN_DATA
void quickconfig(const Plib::Package *pkg, const std::string &name_ecl)
enum Pol::Network::Client::e_recv_states recv_state
void recv_remaining_nocrypt(int total_expected)
Core::polclock_t last_packet_at
bool client_io_thread(Network::Client *client, bool login)
std::atomic< int > pause_count
bool SpeedHackPrevention(bool add=true)
void handle_unknown_packet(Client *client)
static MSG_HANDLER find_handler(unsigned char msgid, const Client *client)
unsigned char cmdlevel() const
bool isa(BObjectImp::BObjectType type) const
void fdump(fmt::Writer &writer, const void *data, int len)
unsigned int bytes_received
void CoreSetSysTrayToolTip(const std::string &text, Priority priority)
static bool is_defined(unsigned char msgid)
void recv_remaining(int total_expected)
unsigned char bufcheck2_55
bool process_data(Network::Client *client)
static void handle_msg(unsigned char msgid, Client *client, void *data)
#define passert_r(exp, reason)
#define PKTOUT_53_WARN_CHARACTER_IDLE
bool check_inactivity(Network::Client *client)
std::unique_ptr< Network::ClientTransmit > clientTransmit
unsigned int message_length
void checkpoint(const char *msg, unsigned short minlvl)
unsigned char pktbuffer[PKTIN_02_SIZE]
bool speedhack_prevention
unsigned char msgtype_allowed[256]
NetworkManager networkManager
std::queue< PacketThrottler > movementqueue
void Send(Client *client, int len=-1) const
unsigned short select_timeout_usecs
const char * name() const
std::string tostring(const Bscript::BTokenType &v)
unsigned char bufcheck1_AA
unsigned char buffer[MAXBUFFER]
void handle_undefined_packet(Network::Client *client)
virtual void Init(void *pvSeed, int type=typeAuto)=0
void notify_left(Mobile::Character &wholeft)
const char * AddressToString(struct sockaddr *addr)
void handle_humongous_packet(Network::Client *client, unsigned int reported_size)
SettingsManager settingsManager
Crypt::CCryptBase * cryptengine
void report_weird_packet(Network::Client *client, const std::string &why)
const Core::MessageTypeFilter * msgtype_filter
void setClientType(ClientTypeFlag type)
unsigned char last_msgtype
#define INFO_PRINT_TRACE(n)
bool isReallyConnected() const
std::string ipaddrAsString() const
bool valid_message_length(Network::Client *client, unsigned int length)
std::atomic< unsigned int > count
std::atomic< unsigned int > bytes
unsigned short inactivity_disconnect_timeout
bool run_script_to_completion(const char *filename, Bscript::BObjectImp *parameter)
Core::polclock_t last_activity_at
void restart_all_clients()
std::lock_guard< SpinLock > SpinLockGuard
Clib::SpinLock _fpLog_lock
void call_chr_scripts(Mobile::Character *chr, const std::string &root_script_ecl, const std::string &pkg_script_ecl, bool offline=false)
const polclock_t POLCLOCKS_PER_SEC
void disconnect_cleanup()
std::atomic< bool > exit_signalled
unsigned short min_cmdlvl_ignore_inactivity