25 #include "../../bscript/berror.h" 26 #include "../../bscript/bstruct.h" 27 #include "../../clib/clib.h" 28 #include "../../clib/logfacility.h" 29 #include "../../clib/strutil.h" 30 #include "../../clib/wallclock.h" 31 #include "../accounts/account.h" 32 #include "../crypt/cryptbase.h" 33 #include "../crypt/cryptengine.h" 34 #include "../globals/network.h" 35 #include "../globals/state.h" 36 #include "../mobile/charactr.h" 37 #include "../pktdef.h" 39 #include "../polsig.h" 40 #include "../realms/WorldChangeReasons.h" 42 #include "../unicode.h" 43 #include "../uoclient.h" 44 #include "../uoscrobj.h" 45 #include "../uworld.h" 46 #include "../xbuffer.h" 59 disable : 4351 ) // new behavior: elements of array '...' will be default initialized 78 Interface( aInterface ),
83 recv_state( RECV_STATE_CRYPTSEED_WAIT ),
90 encrypt_server_stream( 0 ),
95 first_xmit_buffer( nullptr ),
96 last_xmit_buffer( nullptr ),
98 queued_bytes_counter( 0 ),
100 instance_( ++instance_counter_ ),
104 UOExpansionFlag( 0 ),
105 UOExpansionFlagClient( 0 ),
108 movementsequence( 0 ),
109 last_activity_at( 0 ),
157 shutdown(
csocket, SHUT_RDWR );
185 ERROR_PRINT <<
"Uhh... active character not logged in!??\n";
203 if ( !
fpLog.empty() )
205 time_t now = time(
nullptr );
207 FLEXLOG(
fpLog ) <<
"Log closed at " << asctime( &time ) <<
"\n";
232 using namespace Bscript;
233 std::unique_ptr<BStruct> ret(
new BStruct );
240 ret->addMember(
"cpu_manufacturer",
244 ret->addMember(
"cpu_clockspeed",
257 unsigned wlen_vd = 0;
261 ret->addMember(
"video_description",
265 ret->addMember(
"video_description", arr_vd );
270 ret->addMember(
"video_memory",
274 ret->addMember(
"clients_installed",
276 ret->addMember(
"partial_installed",
281 unsigned wlen_lc = 0;
285 ret->addMember(
"langcode",
new Bscript::BError(
"Invalid Unicode speech received." ) );
288 ret->addMember(
"langcode", arr_lc );
291 std::unique_ptr<ObjArray> arr_u2(
new ObjArray );
294 ret->addMember(
"unknown2", arr_u2.release() );
296 return ret.release();
303 size_t dot1 = ver.find_first_of(
'.', 0 );
304 size_t dot2 = ver.find_first_of(
'.', dot1 + 1 );
305 size_t dot3 = ver.find_first_of(
'.', dot2 + 1 );
306 if ( dot3 == std::string::npos )
309 while ( ( dot3 < ver.length() ) && ( isdigit( ver[dot3] ) ) )
315 detail.
major = atoi( ver.substr( 0, dot1 ).c_str() );
316 detail.
minor = atoi( ver.substr( dot1 + 1, dot2 - dot1 - 1 ).c_str() );
317 detail.
rev = atoi( ver.substr( dot2 + 1, dot3 - dot2 - 1 ).c_str() );
319 if ( dot3 < ver.length() )
321 if ( ( detail.
major <= 5 ) && ( detail.
minor <= 0 ) && ( detail.
rev <= 6 ) )
323 if ( ver[dot3] !=
' ' )
324 detail.
patch = ( ver[dot3] -
'a' ) + 1;
327 detail.
patch = atoi( ver.substr( dot3 + 1, ver.length() - dot3 - 1 ).c_str() );
336 POLLOG.Format(
"Malformed clientversion string: {}\n" ) << ver;
359 else if ( ver1.
rev > ver2.
rev )
361 else if ( ver1.
rev < ver2.
rev )
429 if (
acct !=
nullptr )
430 st +=
"AC:" + std::string(
acct->
name() ) +
" ";
431 if (
chr !=
nullptr )
432 st +=
"CH:" +
chr->
name() +
" ";
456 xbuffer->
next =
nullptr;
459 memcpy( xbuffer->
data, data, datalen );
479 POLLOG.Format(
"Client#{}: Unable to allocate {} bytes for queued data. Disconnecting.\n" )
507 const unsigned char* cdata = (
const unsigned char*)data;
510 if ( -1 == ( nsent = send(
csocket, (
const char*)cdata, datalen, 0 ) ) )
518 POLLOG_ERROR.Format(
"Client#{}: Switching to queued data mode (1, {} bytes)\n" )
529 POLLOG_ERROR.Format(
"Client#{}: Disconnecting client due to send() error (1): {}\n" )
539 datalen -=
static_cast<unsigned short>( nsent );
540 counters.bytes_transmitted += nsent;
567 int sckerr = WSAGetLastError();
579 POLLOG.Format(
"Client#{}: Disconnecting client due to send() error (2): {}\n" )
587 xbuffer->
nsent +=
static_cast<unsigned short>( nsent );
588 xbuffer->
lenleft -=
static_cast<unsigned short>( nsent );
589 counters.bytes_transmitted += nsent;
597 POLLOG.Format(
"Client#{}: Leaving queued mode ({} bytes xmitted)\n" )
599 queued_bytes_counter = 0;
623 xmit( pause_pre_encrypted,
sizeof pause_pre_encrypted );
648 xmit( restart_pre_encrypted,
sizeof restart_pre_encrypted );
668 POLLOG_ERROR.Format(
"Client#{}: More then 100 Movepackets in queue. Disconnecting.\n" )
694 POLLOG_ERROR.Format(
"Client#{}: More then 100 Movepackets in queue. Disconnecting.\n" )
723 while ( buffer_size !=
nullptr )
725 size +=
sizeof( buffer_size ) + buffer_size->
lenleft;
726 buffer_size = buffer_size->
next;
#define PKTIN_02_ASYNCHRONOUS
VersionDetailStruct getversiondetail() const
bool have_queued_data() const
std::atomic< u64 > bytes_sent
void send_remove_character_to_nearby(const Character *chr)
void set_opponent(Character *opponent, bool inform_old_opponent=true)
enum Pol::Network::Client::e_recv_states recv_state
std::atomic< int > pause_count
bool SpeedHackPrevention(bool add=true)
std::tm localtime(const std::time_t &t)
threadsafe version of localtime
std::string decint(unsigned short v)
Client(ClientInterface &aInterface, Crypt::TCryptInfo &encryption)
static const unsigned char restart_pre_encrypted[2]
#define MSGOPT_33_FLOW_PAUSE
#define THREAD_CHECKPOINT(thread, check)
static void Delete(Client *client)
void transmit(const void *data, int len, bool needslock=false)
void xmit(const void *data, unsigned short datalen)
Clib::wallclock_t next_movement
std::string hexint(unsigned short v)
Core::PKTIN_D9 clientinfo_
void checkpoint(const char *msg, unsigned short minlvl)
size_t estimatedSize() const
unsigned char pktbuffer[PKTIN_02_SIZE]
CCryptBase * create_crypt_engine(TCryptInfo &infoCrypt)
NetworkManager networkManager
std::queue< PacketThrottler > movementqueue
const char * name() const
ClientInterface & Interface
unsigned char buffer[MAXBUFFER]
weak_ptr< Client > getWeakPtr() const
static const unsigned char pause_pre_encrypted[2]
static unsigned int instance_counter_
Core::XmitBuffer * first_xmit_buffer
bool encrypt_server_stream
bool convertUCtoArray(const u16 *in_wtext, Bscript::ObjArray *&out_text, size_t textlen, bool ConvFromBE)
VersionDetailStruct versiondetail_
void ClrCharacterWorldPosition(Mobile::Character *chr, Realms::WorldChangeReason reason)
static std::mutex _SocketMutex
bool compareVersion(const std::string &ver)
std::unordered_map< u64, ScriptDiffData > data
weak_ptr_owner< Client > weakptr
SettingsManager settingsManager
Crypt::CCryptBase * cryptengine
Character * get_opponent() const
wallclock_diff_t wallclock_diff_ms(wallclock_t start, wallclock_t finish)
u16 video_description[64]
Bscript::BStruct * getclientinfo() const
bool can_speedhack() const
void setClientType(ClientTypeFlag type)
unsigned char last_msgtype
std::string status() const
std::string ipaddrAsString() const
struct Pol::Network::Client::@12 counters
void queue_data(const void *data, unsigned short datalen)
virtual void Encrypt(void *pvIn, void *pvOut, int len)
unsigned int wallclock_diff_t
Bscript::BObjectImp * make_ref()
size_t estimatedSize() const
virtual std::string name() const
std::lock_guard< SpinLock > SpinLockGuard
Clib::SpinLock _fpLog_lock
void cancel_trade(Mobile::Character *chr1)
Core::XmitBuffer * last_xmit_buffer
#define MSGOPT_33_FLOW_RESTART
void deregister_client(Client *client)
void register_client(Client *client)
#define CLOSE_FLEXLOG(id)
static void itemizeclientversion(const std::string &ver, VersionDetailStruct &detail)