// ------------------------------------------------------------------------------ // ____ ___ ____ _____ // ___| _ \ / _ \/ ___|| ____| // / _ \ |_) | | | \___ \| _| // | __/ _ <| |_| |___) | |___ // \___|_| \_\\___/|____/|_____| PRIVATE SERVER // // Written by Brett19 // Special thanks to Genesis, Donan, PelleNoob // ------------------------------------------------------------------------------ #include "world_sockets.h" void CWorldServer::ProcessingThread( ) { fPoint delta; unsigned mspeed; clock_t tm; CPacket pakout; clock_t laststatusupdate = clock( ); unsigned ticks = 0; do { Sleep( 1 ); // ------------------------------ CALCULATE PLAYER MOVEMENT ------------------------------ rwmClientList.acquireReadLock( ); for( unsigned i=0; iinGame ) continue; thisclient->rwmPos.acquireReadLock( ); if( thisclient->newPos.x == thisclient->pos.x && thisclient->newPos.y == thisclient->pos.y ) { thisclient->rwmPos.releaseReadLock( ); continue; } delta.x = thisclient->newPos.x - thisclient->pos.x; delta.y = thisclient->newPos.y - thisclient->pos.y; mspeed = thisclient->GetMSpeed( ); tm = thisclient->lastMoveTime; thisclient->rwmPos.releaseReadLock( ); float dist = sqrt( ( delta.x * delta.x ) + ( delta.y * delta.y ) ); clock_t etime = clock( ) - tm; // ELAPSED TIME float ntime=dist / mspeed * 100000; // TIME TO FINISH MOVE thisclient->rwmPos.acquireWriteLock( ); thisclient->lastMoveTime=clock( ); if ( ntime <= etime || dist == 0 ) { thisclient->pos = thisclient->newPos; } else { thisclient->pos.x = delta.x * ( etime / ntime ) + thisclient->pos.x; thisclient->pos.y = delta.y * ( etime / ntime ) + thisclient->pos.y; } thisclient->rwmPos.releaseWriteLock( ); } rwmClientList.releaseReadLock( ); // ------------------------------ CLEAR VISIBILITY LISTS ------------------------------ rwmClientList.acquireReadLock( ); for( unsigned i=0; irwmVC.acquireReadLock( ); thisclient->InactiveVC->clear( ); thisclient->rwmVC.releaseReadLock( ); thisclient->rwmVM.acquireReadLock( ); thisclient->InactiveVM->clear( ); thisclient->rwmVM.releaseReadLock( ); thisclient->rwmVN.acquireReadLock( ); thisclient->InactiveVN->clear( ); thisclient->rwmVN.releaseReadLock( ); thisclient->rwmVD.acquireReadLock( ); thisclient->InactiveVD->clear( ); thisclient->rwmVD.releaseReadLock( ); } rwmClientList.releaseReadLock( ); // ------------------------------ UPDATE PLAYER VISIBLITY LIST ------------------------------ rwmClientList.acquireReadLock( ); for( unsigned i=0; iinGame ) continue; for( unsigned j=i+1; jinGame ) continue; if( otherclient->posMap != thisclient->posMap ) continue; float dx = ( thisclient->pos.x - otherclient->pos.x ); float dy = ( thisclient->pos.y - otherclient->pos.y ); if( ObjectIsVisible( thisclient, otherclient ) ) { if ( abs( dx * dx + dy * dy ) < MAXVISUALRANGE*MAXVISUALRANGE ){ thisclient->rwmVC.acquireReadLock( ); thisclient->InactiveVC->push_back( otherclient ); thisclient->rwmVC.releaseReadLock( ); otherclient->rwmVC.acquireReadLock( ); otherclient->InactiveVC->push_back( thisclient ); otherclient->rwmVC.releaseReadLock( ); }else{ pakClearObject( thisclient, otherclient->clientid ); pakClearObject( otherclient, thisclient->clientid ); } }else{ if ( abs( dx * dx + dy * dy ) < MINVISUALRANGE*MAXVISUALRANGE ){ thisclient->rwmVC.acquireReadLock( ); thisclient->InactiveVC->push_back( otherclient ); thisclient->rwmVC.releaseReadLock( ); otherclient->rwmVC.acquireReadLock( ); otherclient->InactiveVC->push_back( thisclient ); otherclient->rwmVC.releaseReadLock( ); pakSpawnChar( thisclient, otherclient ); pakSpawnChar( otherclient, thisclient ); } } } } rwmClientList.releaseReadLock( ); // ------------------------------ UPDATE MONSTER VISIBLITY LIST ------------------------------ rwmClientList.acquireReadLock( ); for( unsigned i=0; iinGame ) continue; rwmMonsterList.acquireReadLock( ); for( unsigned j=0; jposMap != thisclient->posMap ) continue; float dx = ( thisclient->pos.x - thismonster->pos.x ); float dy = ( thisclient->pos.y - thismonster->pos.y ); if( ObjectIsVisible( thisclient, thismonster ) ) { if ( abs( dx * dx + dy * dy ) < MAXVISUALRANGE*MAXVISUALRANGE ){ thisclient->InactiveVM->push_back( thismonster ); }else{ pakClearObject( thisclient, thismonster->clientid ); } }else{ if ( abs( dx * dx + dy * dy ) < MINVISUALRANGE*MAXVISUALRANGE ){ thisclient->InactiveVM->push_back( thismonster ); pakSpawnMonster( thisclient, thismonster ); } } } rwmMonsterList.releaseReadLock( ); } rwmClientList.releaseReadLock( ); // ------------------------------ UPDATE NPC VISIBLITY LIST ------------------------------ rwmClientList.acquireReadLock( ); for( unsigned i=0; iinGame ) continue; rwmNPCList.acquireReadLock( ); for( unsigned j=0; jposMap != thisclient->posMap ) continue; float dx = ( thisclient->pos.x - thisnpc->pos.x ); float dy = ( thisclient->pos.y - thisnpc->pos.y ); if( ObjectIsVisible( thisclient, thisnpc ) ) { if ( abs( dx * dx + dy * dy ) < MAXVISUALRANGE*MAXVISUALRANGE ){ thisclient->InactiveVN->push_back( thisnpc ); }else{ pakClearObject( thisclient, thisnpc->clientid ); } }else{ if ( abs( dx * dx + dy * dy ) < MINVISUALRANGE*MAXVISUALRANGE ){ thisclient->InactiveVN->push_back( thisnpc ); pakSpawnNPC( thisclient, thisnpc ); } } } rwmNPCList.releaseReadLock( ); } rwmClientList.releaseReadLock( ); // ------------------------------ UPDATE DROP VISIBLITY LIST ------------------------------ rwmClientList.acquireReadLock( ); for( unsigned i=0; iinGame ) continue; rwmDropsList.acquireReadLock( ); for( unsigned j=0; jposMap != thisclient->posMap ) continue; float dx = ( thisclient->pos.x - thisdrop->pos.x ); float dy = ( thisclient->pos.y - thisdrop->pos.y ); if( ObjectIsVisible( thisclient, thisdrop ) ) { if ( abs( dx * dx + dy * dy ) < MAXVISUALRANGE*MAXVISUALRANGE ){ thisclient->InactiveVD->push_back( thisdrop ); }else{ pakClearObject( thisclient, thisdrop->clientid ); } }else{ if ( abs( dx * dx + dy * dy ) < MINVISUALRANGE*MAXVISUALRANGE ){ thisclient->InactiveVD->push_back( thisdrop ); pakSpawnDrop( thisclient, thisdrop ); } } } rwmDropsList.releaseReadLock( ); } rwmClientList.releaseReadLock( ); // ------------------------------ SWITCH VISIBLITY LISTS ------------------------------ rwmClientList.acquireReadLock( ); for( unsigned i=0; irwmVC.acquireWriteLock( ); std::vector< CWorldClient* >* tmpc = thisclient->ActiveVC; thisclient->ActiveVC = thisclient->InactiveVC; thisclient->InactiveVC = tmpc; thisclient->rwmVC.releaseWriteLock( ); thisclient->rwmVM.acquireWriteLock( ); std::vector< CMonster* >* tmpm = thisclient->ActiveVM; thisclient->ActiveVM = thisclient->InactiveVM; thisclient->InactiveVM = tmpm; thisclient->rwmVM.releaseWriteLock( ); thisclient->rwmVN.acquireWriteLock( ); std::vector< CNPC* >* tmpn = thisclient->ActiveVN; thisclient->ActiveVN = thisclient->InactiveVN; thisclient->InactiveVN = tmpn; thisclient->rwmVN.releaseWriteLock( ); thisclient->rwmVD.acquireWriteLock( ); std::vector< CDrop* >* tmpd = thisclient->ActiveVD; thisclient->ActiveVD = thisclient->InactiveVD; thisclient->InactiveVD = tmpd; thisclient->rwmVD.releaseWriteLock( ); } rwmClientList.releaseReadLock( ); // ------------------------------ CHECK FOR LEVELERS! ------------------------------ rwmClientList.acquireReadLock( ); for( unsigned i=0; iinGame ) continue; if( thisclient->exp > thisclient->GetLevelExp( ) ) pakLevelUp( thisclient ); } rwmClientList.releaseReadLock( ); // ------------------------------ PRINT SERVER DATA ------------------------------ ticks++; if( clock( ) - laststatusupdate > 10000 ) { rwmClientList.acquireReadLock( ); Log( MSG_INFO, "FPS:%f, USER-COUNT:%u, MOB-COUNT:%u", (float)( ticks / 10 ), ClientList.size( ), MonsterList.size( ) ); rwmClientList.releaseReadLock( ); ticks = 0; laststatusupdate = clock( ); } } while( 1 ); }