PageRenderTime 106ms CodeModel.GetById 56ms app.highlight 46ms RepoModel.GetById 1ms app.codeStats 0ms

/ghost/bnlsclient.cpp

http://ghostcb.googlecode.com/
C++ | 199 lines | 149 code | 28 blank | 22 comment | 19 complexity | ece27487fa4eb726d27565f35b726f7f MD5 | raw file
  1/*
  2
  3   Copyright [2008] [Trevor Hogan]
  4
  5   Licensed under the Apache License, Version 2.0 (the "License");
  6   you may not use this file except in compliance with the License.
  7   You may obtain a copy of the License at
  8
  9       http://www.apache.org/licenses/LICENSE-2.0
 10
 11   Unless required by applicable law or agreed to in writing, software
 12   distributed under the License is distributed on an "AS IS" BASIS,
 13   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14   See the License for the specific language governing permissions and
 15   limitations under the License.
 16
 17   CODE PORTED FROM THE ORIGINAL GHOST PROJECT: http://ghost.pwner.org/
 18
 19*/
 20
 21#include "ghost.h"
 22#include "util.h"
 23#include "socket.h"
 24#include "commandpacket.h"
 25#include "bnlsprotocol.h"
 26#include "bnlsclient.h"
 27#include "ui/forward.h"
 28
 29//
 30// CBNLSClient
 31//
 32
 33CBNLSClient :: CBNLSClient( string nServer, uint16_t nPort, uint32_t nWardenCookie )
 34{
 35	m_Socket = new CTCPClient( );
 36	m_Protocol = new CBNLSProtocol( );
 37	m_WasConnected = false;
 38	m_Server = nServer;
 39	m_Port = nPort;
 40	m_LastNullTime = 0;
 41	m_WardenCookie = nWardenCookie;
 42	m_TotalWardenIn = 0;
 43	m_TotalWardenOut = 0;
 44}
 45
 46CBNLSClient :: ~CBNLSClient( )
 47{
 48	delete m_Socket;
 49	delete m_Protocol;
 50
 51	while( !m_Packets.empty( ) )
 52	{
 53		delete m_Packets.front( );
 54		m_Packets.pop( );
 55	}
 56}
 57
 58BYTEARRAY CBNLSClient :: GetWardenResponse( )
 59{
 60	BYTEARRAY WardenResponse;
 61
 62	if( !m_WardenResponses.empty( ) )
 63	{
 64		WardenResponse = m_WardenResponses.front( );
 65		m_WardenResponses.pop( );
 66		m_TotalWardenOut++;
 67	}
 68
 69	return WardenResponse;
 70}
 71
 72unsigned int CBNLSClient :: SetFD( void *fd, void *send_fd, int *nfds )
 73{
 74	if( !m_Socket->HasError( ) && m_Socket->GetConnected( ) )
 75	{
 76		m_Socket->SetFD( (fd_set *)fd, (fd_set *)send_fd, nfds );
 77		return 1;
 78	}
 79
 80	return 0;
 81}
 82
 83bool CBNLSClient :: Update( void *fd, void *send_fd )
 84{
 85	if( m_Socket->HasError( ) )
 86	{
 87		CONSOLE_Print( "[BNLSC: " + m_Server + ":" + UTIL_ToString( m_Port ) + ":C" + UTIL_ToString( m_WardenCookie ) + "] disconnected from BNLS server due to socket error" );
 88		forward(new CFwdData(FWD_GENERAL, "BNLSC: " + m_Server + ":" + UTIL_ToString( m_Port ) + ":C" + UTIL_ToString( m_WardenCookie ) + " - Disconnected from BNLS server due to socket error", 6, 0));
 89		return true;
 90	}
 91
 92	if( !m_Socket->GetConnecting( ) && !m_Socket->GetConnected( ) && m_WasConnected )
 93	{
 94		CONSOLE_Print( "[BNLSC: " + m_Server + ":" + UTIL_ToString( m_Port ) + ":C" + UTIL_ToString( m_WardenCookie ) + "] disconnected from BNLS server" );
 95		forward(new CFwdData(FWD_GENERAL, "BNLSC: " + m_Server + ":" + UTIL_ToString( m_Port ) + ":C" + UTIL_ToString( m_WardenCookie ) + " - Disconnected from BNLS server", 6, 0));
 96		return true;
 97	}
 98
 99	if( m_Socket->GetConnected( ) )
100	{
101		m_Socket->DoRecv( (fd_set *)fd );
102		ExtractPackets( );
103		ProcessPackets( );
104
105		if( GetTime( ) - m_LastNullTime >= 50 )
106		{
107			m_Socket->PutBytes( m_Protocol->SEND_BNLS_NULL( ) );
108			m_LastNullTime = GetTime( );
109		}
110
111		while( !m_OutPackets.empty( ) )
112		{
113			m_Socket->PutBytes( m_OutPackets.front( ) );
114			m_OutPackets.pop( );
115		}
116
117		m_Socket->DoSend( (fd_set *)send_fd );
118		return false;
119	}
120
121	if( m_Socket->GetConnecting( ) && m_Socket->CheckConnect( ) )
122	{
123		CONSOLE_Print( "[BNLSC: " + m_Server + ":" + UTIL_ToString( m_Port ) + ":C" + UTIL_ToString( m_WardenCookie ) + "] connected" );
124		forward(new CFwdData(FWD_GENERAL, "BNLSC: " + m_Server + ":" + UTIL_ToString( m_Port ) + ":C" + UTIL_ToString( m_WardenCookie ) + " - Connected", 0, 0));
125		m_WasConnected = true;
126		m_LastNullTime = GetTime( );
127		return false;
128	}
129
130	if( !m_Socket->GetConnecting( ) && !m_Socket->GetConnected( ) && !m_WasConnected )
131	{
132		CONSOLE_Print( "[BNLSC: " + m_Server + ":" + UTIL_ToString( m_Port ) + ":C" + UTIL_ToString( m_WardenCookie ) + "] connecting to server [" + m_Server + "] on port " + UTIL_ToString( m_Port ) );
133		forward(new CFwdData(FWD_GENERAL, "BNLSC: " + m_Server + ":" + UTIL_ToString( m_Port ) + ":C" + UTIL_ToString( m_WardenCookie ) + " - Connecting to server [" + m_Server + "] on port " + UTIL_ToString( m_Port ), 0, 0));
134		m_Socket->Connect( string( ), m_Server, m_Port );
135		return false;
136	}
137
138	return false;
139}
140
141void CBNLSClient :: ExtractPackets( )
142{
143	string *RecvBuffer = m_Socket->GetBytes( );
144	BYTEARRAY Bytes = UTIL_CreateByteArray( (unsigned char *)RecvBuffer->c_str( ), RecvBuffer->size( ) );
145
146	while( Bytes.size( ) >= 3 )
147	{
148		uint16_t Length = UTIL_ByteArrayToUInt16( Bytes, false );
149
150		if( Length >= 3 )
151		{
152			if( Bytes.size( ) >= Length )
153			{
154				m_Packets.push( new CCommandPacket( 0, Bytes[2], BYTEARRAY( Bytes.begin( ), Bytes.begin( ) + Length ) ) );
155				*RecvBuffer = RecvBuffer->substr( Length );
156				Bytes = BYTEARRAY( Bytes.begin( ) + Length, Bytes.end( ) );
157			}
158			else
159				return;
160		}
161		else
162		{
163			CONSOLE_Print( "[BNLSC: " + m_Server + ":" + UTIL_ToString( m_Port ) + ":C" + UTIL_ToString( m_WardenCookie ) + "] error - received invalid packet from BNLS server (bad length), disconnecting" );
164			forward(new CFwdData(FWD_GENERAL, "BNLSC: " + m_Server + ":" + UTIL_ToString( m_Port ) + ":C" + UTIL_ToString( m_WardenCookie ) + " - Error - received invalid packet from BNLS server (bad length), disconnecting", 0, 0));
165			m_Socket->Disconnect( );
166			return;
167		}
168	}
169}
170
171void CBNLSClient :: ProcessPackets( )
172{
173	while( !m_Packets.empty( ) )
174	{
175		CCommandPacket *Packet = m_Packets.front( );
176		m_Packets.pop( );
177
178		if( Packet->GetID( ) == CBNLSProtocol :: BNLS_WARDEN )
179		{
180			BYTEARRAY WardenResponse = m_Protocol->RECEIVE_BNLS_WARDEN( Packet->GetData( ) );
181
182			if( !WardenResponse.empty( ) )
183				m_WardenResponses.push( WardenResponse );
184		}
185
186		delete Packet;
187	}
188}
189
190void CBNLSClient :: QueueWardenSeed( uint32_t seed )
191{
192	m_OutPackets.push( m_Protocol->SEND_BNLS_WARDEN_SEED( m_WardenCookie, seed ) );
193}
194
195void CBNLSClient :: QueueWardenRaw( BYTEARRAY wardenRaw )
196{
197	m_OutPackets.push( m_Protocol->SEND_BNLS_WARDEN_RAW( m_WardenCookie, wardenRaw ) );
198	m_TotalWardenIn++;
199}