📄 socketclient.cpp.svn-base
字号:
/*
Rose Online Server Emulator
Copyright (C) 2006,2007 OSRose Team http://osroseon.to.md
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
depeloped with Main erose/hrose source server + some change from the original eich source
*/
#include "sockets.h"
// Constructor
CClientSocket::CClientSocket( )
{
PacketSize = 6; // Starting size
PacketOffset = 0; // No bytes read, yet.
}
// Destructor
CClientSocket::~CClientSocket( )
{
}
// Receive this client's socket
bool CClientSocket::ReceiveData( )
{
int ReceivedBytes;
short BytesToRead;
// Calculate bytes to read to get the full packet
BytesToRead = PacketSize - PacketOffset;
// This should never happen, but it is integrated:
if ( BytesToRead > 0x600 - PacketOffset ) return false;
if ( BytesToRead == 0 ) return false;
// Receive data from client
ReceivedBytes = recv( sock, (char*)&Buffer[ PacketOffset ], BytesToRead, 0 );
if ( ReceivedBytes <= 0 ) return false;
// Update pointer
PacketOffset += ReceivedBytes;
// If the packet is not complete, leave the function
if ( ReceivedBytes != BytesToRead ) return true;
if ( PacketSize == 6 )
{
// We received the headerblock
PacketSize = *((unsigned short*)&Buffer[0]);
// Did we receive an incorrect buffer?
if ( PacketSize < 6 )
{
Log( MSG_WARNING, "(SID:%i) Client sent incorrect blockheader.", sock );
return false;
}
// Is the packet larger than just the header, then continue receiving
if ( PacketSize > 6 ) return true;
}
cryptPacket( (char*)Buffer, this->CryptTable );
CPacket* pak = (CPacket*)Buffer;
FILE *fh = NULL;
switch(LOG_THISSERVER)
{
case LOG_LOGIN_SERVER:
fh = fopen( LOG_DIRECTORY LOG_LOGINPACKETS, "a+" );
break;
case LOG_CHARACTER_SERVER:
fh = fopen( LOG_DIRECTORY LOG_CHARPACKETS, "a+" );
break;
case LOG_WORLD_SERVER:
if( pak->Command==0x7ec || pak->Command==0x808 )
break;
fh = fopen( LOG_DIRECTORY LOG_WORLDPACKETS, "a+" );
break;
case LOG_SAME_FILE:
if( pak->Command==0x7ec || pak->Command== 0x808 )
break;
fh = fopen( LOG_DIRECTORY LOG_DEFAULTPACKETS, "a+" );
break;
}
if ( fh != NULL )
{
fprintf( fh, "(SID:%08u) IN %04x: ", sock, pak->Command );
for ( int i=0; i<pak->Size-6; ++i )
fprintf( fh, "%02x ", (unsigned char)pak->Buffer[i] );
fprintf( fh, "\n" );
fclose( fh );
}
// Handle actions for this packet
if ( !GS->OnReceivePacket( this, pak ) )
return false;
// Reset values for the next packet
PacketSize = 6;
PacketOffset = 0;
return true;
}
// Send a packet to this client
void CClientSocket::SendPacket( CPacket *P )
{
// :WARNING: IF WE ADD A CRYPT FUNCTION HERE WE MUST COPY THE
// PACKET AND NOT USE THE ORIGINAL, IT WILL FUCK UP
// THE SENDTOALL FUNCTIONS
if (!this->isActive) return;
FILE *fh = NULL;
switch(LOG_THISSERVER)
{
case LOG_LOGIN_SERVER:
fh = fopen( LOG_DIRECTORY LOG_LOGINPACKETS, "a+" );
break;
case LOG_CHARACTER_SERVER:
fh = fopen( LOG_DIRECTORY LOG_CHARPACKETS, "a+" );
break;
case LOG_WORLD_SERVER:
if( P->Command==0x7ec || P->Command==0x808)
break;
fh = fopen( LOG_DIRECTORY LOG_WORLDPACKETS, "a+" );
break;
case LOG_SAME_FILE:
if( P->Command==0x7ec || P->Command==0x808 )
break;
fh = fopen( LOG_DIRECTORY LOG_DEFAULTPACKETS, "a+" );
break;
}
if ( fh != NULL )
{
fprintf( fh, "(SID:%08u) OUT %04x: ", sock, P->Command );
for ( int i=0; i<P->Size-6; ++i )
fprintf( fh, "%02x ", (unsigned char)P->Buffer[i] );
fprintf( fh, "\n" );
fclose( fh );
}
u_long iMode = 1;
#ifdef WIN32
if (ioctlsocket(sock, FIONBIO, &iMode))
{
Log( MSG_WARNING, "ioctlsocket unblock: %i", errno);
}
#else
if(ioctl(sock, F_SETFL, O_NONBLOCK)!=0)
{
Log( MSG_WARNING, "ioctlsocket unblock: %i", errno);
}
#endif
int retval = send( sock, (char*)P, P->Size, 0 );
iMode=0;
#ifdef WIN32
if(ioctlsocket(sock, FIONBIO, &iMode)==SOCKET_ERROR)
{
Log( MSG_WARNING, "ioctlsocket block: %i", errno);
}
#else
if(ioctl(sock, F_SETFL, 0))!=0)
{
Log( MSG_WARNING, "ioctlsocket block: %i", errno);
}
#endif
}
// Handle client socket (threads)
PVOID ClientMainThread( PVOID ClientSocket )
{
CClientSocket* thisplayer = (CClientSocket*) ClientSocket;
fd_set fds;
while(thisplayer->isActive)
{
FD_ZERO(&fds);
FD_SET (thisplayer->sock, &fds);
int Select = select( thisplayer->sock+1, &fds, NULL, NULL, NULL );
if(Select == SOCKET_ERROR)
{
Log( MSG_ERROR,NULL,"Error in Select");
thisplayer->isActive = false;
}
else
{
if(FD_ISSET( thisplayer->sock, &fds ))
{
if(!thisplayer->ReceiveData( ))
thisplayer->isActive = false;
}
}
}
thisplayer->GS->DisconnectClient( thisplayer );
pthread_exit(NULL);
}
// -----------------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -