📄 worldserver.cpp.svn-base
字号:
ADDBYTE ( pak, 0x00 );
cryptPacket( (char*)&pak, NULL );
send( csock, (char*)&pak, pak.Size, 0 );
}
if ( player->Fairy ){
GServer->FairyList.at(player->FairyListIndex)->assigned = false;
GServer->FairyList.at(player->FairyListIndex)->LastTime = clock();
GServer->FairyList.at(player->FairyListIndex)->ListIndex = 0;
GServer->FairyList.at(player->FairyListIndex)->WaitTime = GServer->Config.FairyWait * (rand()% GServer->GetFairyRange(1)+ GServer->GetFairyRange(0));
player->Fairy = false;
player->FairyListIndex = 0;
GServer->DoFairyStuff(player, 0);
// recalculate FairyMax
int oldFairyMax = GServer->Config.FairyMax;
GServer->Config.FairyMax = (int)ceil((float)GServer->ClientList.size() / 50.0); //(1 fairy more every 50 player)
if( oldFairyMax > GServer->Config.FairyMax ){
GServer->FairyList.erase( GServer->FairyList.begin() + GServer->FairyList.size() );
}
}
if(player->Party->party!=NULL)
{
CParty* party = player->Party->party;
BEGINPACKET( pak, 0x7d2 );
ADDWORD ( pak, 0xff00 );
ADDDWORD ( pak, player->CharInfo->charid );
bool pflag = false;
party->RemovePlayer( player );
if(party->Members.size()>1)
{
for(UINT i=0;i<party->Members.size();i++)
{
CPlayer* othermember = party->Members.at(i);
if(!pflag)
{
ADDDWORD( pak, othermember->CharInfo->charid );
if(player->Party->IsMaster)
othermember->Party->IsMaster = true;
pflag = true;
}
othermember->client->SendPacket( &pak );
}
}
else
{
for(UINT i=0;i<party->Members.size();i++)
{
CPlayer* othermember = party->Members.at(i);
BEGINPACKET( pak, 0x7d1 );
ADDBYTE ( pak, 0x05 );
ADDWORD ( pak, 0x0000 );
ADDWORD ( pak, 0x0000 );
othermember->client->SendPacket( &pak );
othermember->Party->party = NULL;
othermember->Party->IsMaster = true;
}
RemoveParty( party );
delete party;
party = NULL;
}
}
DB->QExecute("UPDATE accounts SET online=false where id=%u", player->Session->userid );
}
// Server is started, lets run our loop :D
void CWorldServer::ServerLoop( )
{
fd_set fds;
int activity;
maxfd = 0;
sockaddr_in ClientInfo;
SOCKET NewSocket;
timeval timeout;
maxfd = sock;
OnServerStep();
//LMA BEGIN
//MySQL Ping (every hour)
//20070623, 221000
UINT time_last_ping=clock();
UINT delay_ping=3600000;
//LMA END
do
{
//LMA BEGIN
//MySQL Ping
//20070623, 221000
UINT etime = (UINT)round((clock( ) - time_last_ping));
if(etime>=delay_ping)
{
time_last_ping=clock();
Ping();
}
//LMA END
timeout.tv_sec = 0;
timeout.tv_usec = 1000;
NewSocket = INVALID_SOCKET;
FD_ZERO( &fds );
pthread_mutex_lock( &PlayerMutex );
if(!Config.usethreads)
FillFDS( &fds );
FD_SET( sock, &fds );
activity = select( maxfd+1, &fds, NULL, NULL, &timeout );
if ( activity == 0 )
{
pthread_mutex_unlock( &PlayerMutex );
#ifdef _WIN32
Sleep(1);
#else
usleep(1);
#endif
continue;
}
if ( activity < 0 && errno != EINTR )
{
#ifdef _WIN32
Log( MSG_ERROR, "Select command failed. Error #%i", WSAGetLastError() );
#else
Log( MSG_ERROR, "Select command failed. Error #%i", errno );
#endif
isActive = false;
}
if ( FD_ISSET( sock, &fds ) && ConnectedClients < 1024 )
{
int clientinfolen = sizeof( sockaddr_in );
#ifdef _WIN32
NewSocket = accept( sock, (sockaddr*)&ClientInfo, (int*)&clientinfolen );
#else
NewSocket = accept( sock, (sockaddr*)&ClientInfo, (socklen_t*)&clientinfolen );
#endif
// TODO: check if server is full
if (NewSocket != INVALID_SOCKET)
AddUser( NewSocket, &ClientInfo );
else
{
#ifdef _WIN32
Log( MSG_ERROR, "Error accepting socket: %i", WSAGetLastError() );
#else
Log( MSG_ERROR, "Error accepting socket: %i", errno );
#endif
}
}
if(!Config.usethreads)
HandleClients( &fds );
pthread_mutex_unlock( &PlayerMutex );
#ifdef _WIN32
Sleep(1);
#else
usleep(1);
#endif
} while( isActive );
}
// Return a new clientsocket structure
CClientSocket* CWorldServer::CreateClientSocket( )
{
DB->QExecute( "UPDATE channels SET connected=%i where id=%i and type=2", ConnectedClients, Config.ServerID );
CClientSocket* client = new CClientSocket;
CPlayer* player = new CPlayer( client );
client->player = (void*) player;
return client;
}
// Deletes an old clientsocket structure
void CWorldServer::DeleteClientSocket( CClientSocket* thisclient )
{
DB->QExecute( "UPDATE channels SET connected=%i where id=%i and type=2", ConnectedClients, Config.ServerID );
if(thisclient->player!=NULL)
{
CPlayer* player = (CPlayer*) thisclient->player;
Log( MSG_INFO, "User disconnected (%s)", player->CharInfo->charname );
CMap* map = MapList.Index[player->Position->Map];
pthread_mutex_lock( &MapMutex );
map->RemovePlayer( player );
pthread_mutex_unlock( &MapMutex );
delete player;
player = NULL;
}
else
{
delete thisclient;
thisclient = NULL;
}
}
// This function is called just before the server starts
bool CWorldServer::OnServerReady( )
{
ServerOnline = true;
GServer = this;
clock_t timer = clock();
LastUpdateTime = clock();
ATTK_SPEED_MODIF = 120;
HIT_DELAY_MODIF = 0;
MOVE_SPEED_MODIF = 100000;
//Load our Server Info
LoadZoneData( );
LoadConsItem( );
LoadSellData( );
LoadProductItem( );
LoadPatItem( );
LoadNaturalItem( );
LoadJemItem( );
LoadEquip( );
LoadItemStats( );
LoadSkillData( );
LoadDropsData( );
LoadQuestData( );
LoadNPCData( );
LoadTeleGateData( );
LoadRespawnData( );
LoadMonsterSpawn( );
LoadNPCs( );
LoadMonsters( );
LoadUpgrade( );
CleanConnectedList( );
Log(MSG_INFO, "Database Loaded " );
pthread_create( &WorldThread[WORLD_THREAD], &at, WorldProcess, NULL);
pthread_create( &WorldThread[VISUALITY_THREAD], &at, VisibilityProcess, NULL);
pthread_create( &MapThread[0], &at, MapProcess, NULL);
Log( MSG_INFO, "Process Loaded. WorldDelay %i | MapDelay %i | VisualDelay %i",Config.WorldDelay,Config.MapDelay,Config.VisualDelay);
DB->QExecute( "DELETE FROM channels WHERE id=%u and type=%i", Config.ServerID, Config.ServerType );
if(!DB->QExecute("INSERT INTO channels (id,type,name,host,port,lanip,lansubmask,connected,maxconnections,owner) VALUES (%i,%i,'%s','%s',%u,'%s','%s',0,%i,%i)",
Config.ServerID, Config.ServerType, Config.ServerName, Config.WorldIP, Config.WorldPort, Config.LanIP, Config.LanSubnet, Config.MaxConnections, Config.ParentID))
{
Log(MSG_WARNING, "Error accessing to database, the other server will not connect to WorldServer" );
}
MYSQL_ROW row;
bool pflag = false;
//Get IP and Port from Charserver
MYSQL_RES *result = DB->QStore( "SELECT host,port,lanip FROM channels WHERE id=%u and type=1", Config.ParentID );
if(result==NULL) return false;
if (mysql_num_rows( result ) == 1)
{
row = mysql_fetch_row( result );
switch(Config.Connection)
{
case 0://wanip
Config.CharIP = row[0];
break;
case 1://lanip
Config.CharIP = row[2];
break;
default://localhost
Config.CharIP = "127.0.0.1";
break;
}
Config.CharPort = atoi(row[1]);
pflag = true;
}
DB->QFree( );
if(pflag)
{
Log( MSG_INFO, "Initialized Charserver connection" );
// Connect To LoginServer
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -