rendered paste body// ------------------------------------------------------------------------------
// ____ ___ ____ _____
// ___| _ \ / _ \/ ___|| ____|
// / _ \ |_) | | | \___ \| _|
// | __/ _ <| |_| |___) | |___
// \___|_| \_\\___/|____/|_____| 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; i<ClientList.size( ); i++ ) {
CWorldClient* thisclient = (CWorldClient*)ClientList[i];
if( !thisclient->inGame ) 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; i<ClientList.size( ); i++ ) {
CWorldClient* thisclient = (CWorldClient*)ClientList[i];
thisclient->rwmVC.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; i<ClientList.size( ); i++ ) {
CWorldClient* thisclient = (CWorldClient*)ClientList[i];
if( !thisclient->inGame ) continue;
for( unsigned j=i+1; j<ClientList.size( ); j++ ) {
CWorldClient* otherclient = (CWorldClient*)ClientList[j];
if( !otherclient->inGame ) 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; i<ClientList.size( ); i++ ) {
CWorldClient* thisclient = (CWorldClient*)ClientList[i];
if( !thisclient->inGame ) continue;
rwmMonsterList.acquireReadLock( );
for( unsigned j=0; j<MonsterList.size( ); j++ ) {
CMonster* thismonster = MonsterList[j];
if( thismonster->posMap != 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; i<ClientList.size( ); i++ ) {
CWorldClient* thisclient = (CWorldClient*)ClientList[i];
if( !thisclient->inGame ) continue;
rwmNPCList.acquireReadLock( );
for( unsigned j=0; j<NPCList.size( ); j++ ) {
CNPC* thisnpc = NPCList[j];
if( thisnpc->posMap != 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; i<ClientList.size( ); i++ ) {
CWorldClient* thisclient = (CWorldClient*)ClientList[i];
if( !thisclient->inGame ) continue;
rwmDropsList.acquireReadLock( );
for( unsigned j=0; j<DropsList.size( ); j++ ) {
CDrop* thisdrop = DropsList[j];
if( thisdrop->posMap != 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; i<ClientList.size( ); i++ ) {
CWorldClient* thisclient = (CWorldClient*)ClientList[i];
thisclient->rwmVC.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; i<ClientList.size( ); i++ ) {
CWorldClient* thisclient = (CWorldClient*)ClientList[i];
if( !thisclient->inGame ) 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 );
}