Esempio n. 1
0
bool TCPConnection::SendData(bool &sent_something, char* errbuf) {
	if (errbuf)
		errbuf[0] = 0;
	/************ Get first send packet on queue and send it! ************/
	uchar* data = 0;
	int32 size = 0;
	int status = 0;
	if (ServerSendQueuePop(&data, &size)) {
#ifdef _WINDOWS
		status = send(connection_socket, (const char *) data, size, 0);
#else
		status = send(connection_socket, data, size, MSG_NOSIGNAL);
		if(errno==EPIPE) status = SOCKET_ERROR;
#endif
		if (status >= 1) {
#if TCPN_LOG_RAW_DATA_OUT >= 1
			struct in_addr	in;
			in.s_addr = GetrIP();
			CoutTimestamp(true);
			std::cout << ": Wrote " << status << " bytes to network. " << inet_ntoa(in) << ":" << GetrPort();
			std::cout << std::endl;
	#if TCPN_LOG_RAW_DATA_OUT == 2
			int32 tmp = status;
			if (tmp > 32)
				tmp = 32;
			DumpPacket(data, status);
	#elif TCPN_LOG_RAW_DATA_OUT >= 3
			DumpPacket(data, status);
	#endif
#endif
			sent_something = true;
			if (status < (signed)size) {
#if TCPN_LOG_RAW_DATA_OUT >= 1
				struct in_addr	in;
				in.s_addr = GetrIP();
				CoutTimestamp(true);
				std::cout << ": Pushed " << (size - status) << " bytes back onto the send queue. " << inet_ntoa(in) << ":" << GetrPort();
				std::cout << std::endl;
#endif
				// If there's network congestion, the number of bytes sent can be less than
				// what we tried to give it... Push the extra back on the queue for later
				ServerSendQueuePushFront(&data[status], size - status);
			}
			else if (status > (signed)size) {
				return false;
			}
			// else if (status == size) {}
		}
		else {
			ServerSendQueuePushFront(data, size);
		}

		safe_delete_array(data);
		if (status == SOCKET_ERROR) {
#ifdef _WINDOWS
			if (WSAGetLastError() != WSAEWOULDBLOCK)
#else
			if (errno != EWOULDBLOCK)
#endif
			{
				if (errbuf) {
#ifdef _WINDOWS
					snprintf(errbuf, TCPConnection_ErrorBufferSize, "TCPConnection::SendData(): send(): Errorcode: %i", WSAGetLastError());
#else
					snprintf(errbuf, TCPConnection_ErrorBufferSize, "TCPConnection::SendData(): send(): Errorcode: %s", strerror(errno));
#endif
				}

				//if we get an error while disconnecting, just jump to disconnected
				MState.lock();
				if(pState == TCPS_Disconnecting)
					pState = TCPS_Disconnected;
				MState.unlock();

				return false;
			}
		}
	}
	return true;
}
Esempio n. 2
0
		bool LoginServer::Process()
		{
#ifdef WIN32
			SOCKADDR_IN to;
#else
			struct sockaddr_in to;
#endif

			memset((char *) &to, 0, sizeof(to));
			to.sin_family = AF_INET;
			to.sin_port = port;
			to.sin_addr.s_addr = ip;

			if (statusupdate_timer->Check())
			{
				this->SendStatus();
			}

			if (staleauth_timer->Check())
			{
				staleauth_timer->Start();
				loginserver->CheckStale();
			}
		    
			/************ Get all packets from packet manager out queue and process them ************/
			ServerPacket *pack = 0;

			while(pack = ServerOutQueue.pop())
			{
				switch(pack->opcode) 
				{
					case 0:
					break;
					case ServerOP_KeepAlive: 
					{
						// ignore this -- froglok23 -- WHY?
					}
					break;
					case ServerOP_LSClientAuth:
					{
						this->ProcessServerOP_LSClientAuth(pack);
					}
					break;
				case ServerOP_LSFatalError: 
					{
						this->ProcessServerOP_LSFatalError(pack);          
					}
					break;
				case ServerOP_SystemwideMessage:
					{
						this->ProcessServerOP_SystemwideMessage(pack);
						break;
					}
				case ServerOP_UsertoWorldReq:
					{
						this->ProcessServerOP_UsertoWorldReq(pack);
						break;
					}
				case 0x0109:
				case 0x010a:
				case 0x0106:
				case 0x0107:
					{
						//Yeahlight: These opcodes occasionally appear with a packet size of 18 when a player attempts to enter a zone. Leave these packets unresolved is freezing the client
						this->ProcessServerOP_Unknown(pack);
						this->SendPacket(pack);
						break;
					}
				default:
					{
						this->ProcessServerOP_Unknown(pack);
						break;
					}
				}

				safe_delete(pack);//delete pack;
				//Yeahlight: Zone freeze debug
				if(ZONE_FREEZE_DEBUG && rand()%ZONE_FREEZE_DEBUG == 1)
					EQC_FREEZE_DEBUG(__LINE__, __FILE__);
			}

			/************ Get first send packet on queue and send it! ************/
			SPackSendQueue* p = 0;    
			int status = 0;
			while(p = ServerSendQueuePop())
			{

#ifdef WIN32
				status = send(send_socket, (const char *) p->buffer, p->size, 0);
#else
				status = send(send_socket, p->buffer, p->size, 0);
#endif
				safe_delete(p);//delete p;
				if (status == SOCKET_ERROR)
				{
					cout << "Loginserver send(): status=" << status  << ", Errorcode: " << EQC::Common::GetLastSocketError() << endl;	
					return false;
				}
				//Yeahlight: Zone freeze debug
				if(ZONE_FREEZE_DEBUG && rand()%ZONE_FREEZE_DEBUG == 1)
					EQC_FREEZE_DEBUG(__LINE__, __FILE__);
			}
			/************ Processing finished ************/
			if (timeout_timer->Check())
			{
				this->SendKeepAlive();
			}

			return true;
		}